This is an archive of the discontinued LLVM Phabricator instance.

typeinfo: provide a partial implementation for Win32
ClosedPublic

Authored by compnerd on Jan 1 2017, 2:53 PM.

Details

Summary

The RTTI structure is different on Windows when building under MS ABI.
Update the definition to reflect this. The structure itself contains an
area for caching the undecorated name (which is 0-initialized). The
decorated name has a bitfield followed by the linkage name. When
std::type_info::name is invoked for the first time, the runtime should
undecorate the name, cache it, and return the undecorated name. This
requires access to an implementation of __unDName. For now, return
the raw name.

This uses the fnv-1a hash to hash the name of the RTTI. We could use an alternate hash (murmur? city?), but, this was the quickest to throw together.

Diff Detail

Event Timeline

compnerd updated this revision to Diff 82790.Jan 1 2017, 2:53 PM
compnerd retitled this revision from to typeinfo: provide a partial implementation for Win32.
compnerd updated this object.
compnerd added reviewers: EricWF, mclow.lists, majnemer, rnk.
compnerd set the repository for this revision to rL LLVM.
compnerd added subscribers: smeenai, kastiglione, cfe-commits.
majnemer added inline comments.Jan 1 2017, 4:49 PM
src/typeinfo.cpp
28–29

These literals are ill-formed, I think you need a ULL suffix here.

28–32

Why make these static? Seems strange to use that storage duration.

compnerd marked an inline comment as done.Jan 2 2017, 1:27 PM
compnerd added inline comments.
src/typeinfo.cpp
28–32

Oh, just to ensure that they are handled as literal constants. I can drop the static if you like, since the compiler should do the right thing anyways.

compnerd updated this revision to Diff 82815.Jan 2 2017, 1:28 PM

Add suffixes

EricWF edited edge metadata.Jan 2 2017, 4:43 PM

I would really rather see a single definition of the typeinfo class between all platforms, but I see how that could get messy. How about instead of declaring a new one we use the existing class definition, but move all of the method definitions out-of-line and then define them in their own #ifdef blocks?

EricWF commandeered this revision.Jan 2 2017, 5:31 PM
EricWF edited reviewers, added: compnerd; removed: EricWF.

Stealing this revision to update with the requested style changes: @compnerd please steal this back.

EricWF updated this revision to Diff 82825.Jan 2 2017, 5:33 PM
EricWF removed rL LLVM as the repository for this revision.

Update with the prefered style changes. @compnerd please still this revision back when ready.

compnerd commandeered this revision.Jan 3 2017, 11:55 AM
compnerd edited reviewers, added: EricWF; removed: compnerd.

Ill use this version for the commit, but Id like to get an okay on it before I do that :-).

rnk added inline comments.Jan 4 2017, 9:57 AM
include/typeinfo
75

Is _WIN32 the right condition? It seems like this is intended to match the MS ABI RTTI structure, not the Itanium one. _MSC_VER maybe?

src/typeinfo.cpp
28–32

Isn't constexpr const redundant?

compnerd added inline comments.Jan 4 2017, 10:14 AM
include/typeinfo
75

Yeah, this is meant to match the MS ABI RTTI. Yeah, _MSC_VER seems more appropriate than _WIN32.

src/typeinfo.cpp
28–32

Yeah, intentional. I should be using _LIBCPP_CONSTEXPR just incase the compiler doesn't support constexpr.

EricWF added inline comments.Jan 4 2017, 10:07 PM
include/typeinfo
75

I agree. Please make this change before committing.

193

This constructor is almost certainly not correct. @compnerd do you know what constructor call clang-cl generates to construct type_info?

src/typeinfo.cpp
28–32

All supported compiler provide constexpr when building the dylib, so you can assume we have it.

I have no strong objection to the redundancy, but I'm not opposed to removing either const or constexpr.

compnerd updated this revision to Diff 83326.Jan 5 2017, 4:45 PM
compnerd set the repository for this revision to rL LLVM.
EricWF edited edge metadata.Jan 6 2017, 12:22 PM

This isn't applying against master. Could you rebase?

include/typeinfo
109

Don't we need a constructor here?

Nevermind. Missed the dependency. Would you be willing to kill that dependency for now and we can fix it once we get Clang support?

compnerd updated this revision to Diff 83489.Jan 6 2017, 7:13 PM
compnerd edited edge metadata.

Rebase for r291329.

compnerd added inline comments.Jan 7 2017, 1:43 PM
include/typeinfo
109

No, we do not need a constructor since the emitted object is already a well formed object instance.

smeenai commandeered this revision.Sep 12 2017, 7:55 PM
smeenai added a reviewer: compnerd.
smeenai added a reviewer: bcraig.

Rebased and tested on Windows again.

I'd like to see this patch get through to reduce the dependencies on the vcruntime headers, since those end up pulling in lots of cruft and can cause some nasty conflicts. (Similarly, I'll be trying to remove dependencies on Windows.h, which is an evil, evil header.)

There's a behavior difference between this implementation and vcruntime's, since this one doesn't demangle the type name. Idk how much that difference matters in practice though, and I think it's fine to address in a follow-up.

What else needs to be addressed before this is good to go?

include/typeinfo
109

I believe @EricWF was referring to the internal constructors that take a const char *. Do we need one of those for the Microsoft typeinfo?

compnerd edited edge metadata.Sep 12 2017, 8:57 PM

I'm happy to pick this up again. LMK what needs to be addressed. AFAIK, no constructors will be invoked as the class is just a wrapper over static data so we don't need the constructors. I would rather do the undecorating stuff in a follow-up.

@compnerd, @EricWF and I discussed this a bit on IRC yesterday.

My motivation here is that I'm using libc++ with other headers that clash badly with the vcruntime headers, which prevents me from using libc++'s _LIBCPP_ABI_MICROSOFT support. Reducing libc++'s dependencies on the vcruntime headers enables me to at least use parts of the Microsoft ABI support.

At the same time, @EricWF pointed out that most people will expect libc++ to play nicely with the vcruntime headers. In particular, vcruntime_new.h ends up getting pulled in from all sorts of places, which is why libc++ defers to that header instead of trying to provide its own new/delete declarations for _LIBCPP_ABI_MICROSOFT.

One option would be an alternate ABI configuration, which is basically "Microsoft ABI support without reliance on and interoperability with vcruntime headers". Another possibility would be for the libc++ headers to provide vcruntime-compatible declarations for _LIBCPP_ABI_MICROSOFT, which would allow us to remain compatible with the vcruntime headers without depending on them. I find the second option to be cleaner conceptually and would prefer it.

In this particular case, however, I don't believe those concerns apply. vcruntime_typeinfo.h is only pulled in from MSVC's typeinfo header, so it's not going to get pulled in unless explicitly requested, and therefore there are no interoperability concerns. Additionally, the type_info structure here is completely compatible with the one from the vcruntime headers, since they both model the Microsoft ABI typeinfo structure. The only behavior difference is that vcruntime's implementation will demangle the type name, whereas this one won't, but we can address that in a follow-up. In other words, I believe this change can go in independent of whatever decision we reach for vcruntime interoperability in the general case.

EricWF requested changes to this revision.Sep 14 2017, 2:21 PM
  • List Item

@compnerd, @EricWF and I discussed this a bit on IRC yesterday.

In this particular case, however, I don't believe those concerns apply. vcruntime_typeinfo.h is only pulled in from MSVC's typeinfo header, so it's not going to get pulled in unless explicitly requested, and therefore there are no interoperability concerns. Additionally, the type_info structure here is completely compatible with the one from the vcruntime headers, since they both model the Microsoft ABI typeinfo structure. The only behavior difference is that vcruntime's implementation will demangle the type name, whereas this one won't, but we can address that in a follow-up. In other words, I believe this change can go in independent of whatever decision we reach for vcruntime interoperability in the general case.

I'm convinced. Kill away.

This patch LGTM other than the mentioned nits.

include/typeinfo
95

Perhaps the struct should have a different name than the instance of it.

100

These should probably have _LIBCPP_FUNC_VIS visibility declarations attached to them.

101

Is there a reason why __name and __hash need wrappers? Can't we just provide out-of-line definitions for name() and hash_code() directly?

200

Comment on #endif please.

This revision now requires changes to proceed.Sep 14 2017, 2:21 PM
EricWF accepted this revision.Sep 14 2017, 2:23 PM

Woops. didn't mean to reject.

This revision is now accepted and ready to land.Sep 14 2017, 2:23 PM
compnerd commandeered this revision.Sep 14 2017, 5:27 PM
compnerd edited reviewers, added: smeenai; removed: compnerd.
compnerd added inline comments.
include/typeinfo
100

Wont bother due to out-of-line definition

101

I don't remember why ... we can address that when we hit it. Going to out-of-line them.

109

No, no such constructor is needed with MS ABI AFAIK. Construction of the type does not invoke a constructor and libc++ does not create instances of this.

200

Sure!

src/typeinfo.cpp
28–32

Removed static and const.

compnerd updated this revision to Diff 115326.Sep 14 2017, 5:31 PM
smeenai added inline comments.Sep 14 2017, 8:33 PM
include/typeinfo
100

Drop the struct; it causes compilation errors.

This needs to be marked const.

src/typeinfo.cpp
15

Drop the struct and add the const.

21

You need a const here.

36

The -> should be .

compnerd marked 4 inline comments as done.Sep 14 2017, 8:39 PM

Also added _NOEXCEPT to __compare.

compnerd closed this revision.Sep 14 2017, 11:03 PM

SVN r313344