diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-06-19 15:20:38 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-06-19 15:20:38 +0000 |
commit | 7810af0a43fc6b46eaed5c5c366adc0d3dda98c5 (patch) | |
tree | cecb37431c2a64630c88bcda6b514966a28be80e /clang/lib/AST/MicrosoftMangle.cpp | |
parent | 3793d5ed30613b97bf7735c21d84d440cbb00133 (diff) | |
download | bcm5719-llvm-7810af0a43fc6b46eaed5c5c366adc0d3dda98c5.tar.gz bcm5719-llvm-7810af0a43fc6b46eaed5c5c366adc0d3dda98c5.zip |
[ms-cxxabi] Emit and install appropriately mangled vbtables
In Itanium, dynamic classes have one vtable with several different
address points for dynamic base classes that can't share vtables.
In the MS C++ ABI, each vbtable that can't be shared gets its own
symbol, similar to how ctor vtables work in Itanium. However, instead
of mangling the subobject offset into the symbol, the unique portions of
the inheritance path are mangled into the symbol to make it unique.
This patch implements the MSVC 2012 scheme for forming unique vbtable
symbol names. MSVC 2010 use the same mangling with a different subset
of the path. Implementing that mangling and possibly others is TODO.
Each vbtable is an array of i32 offsets from the vbptr that points to it
to another virtual base subobject. The first entry of a vbtable always
points to the base of the current subobject, implying that it is the
same no matter which parent class contains it.
Reviewers: rjmccall
Differential Revision: http://llvm-reviews.chandlerc.com/D636
llvm-svn: 184309
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 976fcf8ad69..5e488e042e7 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -155,6 +155,9 @@ public: raw_ostream &); virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &); + virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, + ArrayRef<const CXXRecordDecl *> BasePath, + raw_ostream &Out); virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, const CXXRecordDecl *Type, raw_ostream &); @@ -1757,24 +1760,41 @@ void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, "cannot mangle thunk for this destructor yet"); getDiags().Report(DD->getLocation(), DiagID); } + void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &Out) { - // <mangled-name> ::= ? <operator-name> <class-name> <storage-class> - // <cvr-qualifiers> [<name>] @ - // <operator-name> ::= _7 # vftable - // ::= _8 # vbtable + // <mangled-name> ::= ?_7 <class-name> <storage-class> + // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> - // is always '6' for vftables and '7' for vbtables. (The difference is - // beyond me.) - // TODO: vbtables. + // is always '6' for vftables. MicrosoftCXXNameMangler Mangler(*this, Out); Mangler.getStream() << "\01??_7"; Mangler.mangleName(RD); - Mangler.getStream() << "6B"; + Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const. // TODO: If the class has more than one vtable, mangle in the class it came // from. Mangler.getStream() << '@'; } + +void MicrosoftMangleContext::mangleCXXVBTable( + const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath, + raw_ostream &Out) { + // <mangled-name> ::= ?_8 <class-name> <storage-class> + // <cvr-qualifiers> [<name>] @ + // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> + // is always '7' for vbtables. + MicrosoftCXXNameMangler Mangler(*this, Out); + Mangler.getStream() << "\01??_8"; + Mangler.mangleName(Derived); + Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const. + for (ArrayRef<const CXXRecordDecl *>::iterator I = BasePath.begin(), + E = BasePath.end(); + I != E; ++I) { + Mangler.mangleName(*I); + } + Mangler.getStream() << '@'; +} + void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) { llvm_unreachable("The MS C++ ABI does not have virtual table tables!"); |