diff options
-rw-r--r-- | include/clang/AST/Mangle.h | 6 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 5 | ||||
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.cpp | 10 | ||||
-rw-r--r-- | test/CodeGen/tbaa-ms-abi.cpp | 22 |
5 files changed, 45 insertions, 7 deletions
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index e875c31fc0..4df2955aec 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -148,6 +148,12 @@ public: virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &) = 0; + /// Generates a unique string for an externally visible type for use with TBAA + /// or type uniquing. + /// TODO: Extend this to internal types by generating names that are unique + /// across translation units so it can be used with LTO. + virtual void mangleTypeName(QualType T, raw_ostream &) = 0; + /// @} }; diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index e94b4cf907..0621d7b1ad 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -144,6 +144,7 @@ public: raw_ostream &); void mangleCXXRTTI(QualType T, raw_ostream &); void mangleCXXRTTIName(QualType T, raw_ostream &); + void mangleTypeName(QualType T, raw_ostream &); void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, raw_ostream &); void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, @@ -3784,6 +3785,10 @@ void ItaniumMangleContextImpl::mangleCXXRTTIName(QualType Ty, Mangler.mangleType(Ty); } +void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) { + mangleCXXRTTIName(Ty, Out); +} + ItaniumMangleContext * ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) { return new ItaniumMangleContextImpl(Context, Diags); diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index ff1b0158c5..ed7168e3eb 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -197,6 +197,7 @@ public: raw_ostream &Out); virtual void mangleCXXRTTI(QualType T, raw_ostream &); virtual void mangleCXXRTTIName(QualType T, raw_ostream &); + virtual void mangleTypeName(QualType T, raw_ostream &); virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, raw_ostream &); virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, @@ -2019,6 +2020,14 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, raw_ostream &) { << T.getBaseTypeIdentifier(); } +void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) { + // This is just a made up unique string for the purposes of tbaa. undname + // does *not* know how to demangle it. + MicrosoftCXXNameMangler Mangler(*this, Out); + Mangler.getStream() << '?'; + Mangler.mangleType(T, SourceRange()); +} + void MicrosoftMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, raw_ostream &Out) { diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index 11e376ff40..699cc2eabe 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -152,11 +152,9 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible()) return MetadataCache[Ty] = getChar(); - // TODO: This is using the RTTI name. Is there a better way to get - // a unique string for a type? SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); - MContext.mangleCXXRTTIName(QualType(ETy, 0), Out); + MContext.mangleTypeName(QualType(ETy, 0), Out); Out.flush(); return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar()); } @@ -268,13 +266,11 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth())); } - // TODO: This is using the RTTI name. Is there a better way to get - // a unique string for a type? SmallString<256> OutName; if (Features.CPlusPlus) { - // Don't use mangleCXXRTTIName for C code. + // Don't use the mangler for C code. llvm::raw_svector_ostream Out(OutName); - MContext.mangleCXXRTTIName(QualType(Ty, 0), Out); + MContext.mangleTypeName(QualType(Ty, 0), Out); Out.flush(); } else { OutName = RD->getName(); diff --git a/test/CodeGen/tbaa-ms-abi.cpp b/test/CodeGen/tbaa-ms-abi.cpp new file mode 100644 index 0000000000..67390b1a8a --- /dev/null +++ b/test/CodeGen/tbaa-ms-abi.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -cxx-abi microsoft -triple i686-pc-win32 -disable-llvm-optzns -emit-llvm -o - -O1 %s | FileCheck %s +// +// Test that TBAA works in the Microsoft C++ ABI. We used to error out while +// attempting to mangle RTTI. + +struct StructA { + int a; +}; + +struct StructB : virtual StructA { + StructB(); +}; + +StructB::StructB() { + a = 42; +// CHECK: store i32 42, i32* {{.*}}, !tbaa [[TAG_A_i32:!.*]] +} + +// CHECK: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata +// CHECK: [[TYPE_INT:!.*]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]], i64 0} +// CHECK: [[TAG_A_i32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 0} +// CHECK: [[TYPE_A]] = metadata !{metadata !"?AUStructA@@", metadata [[TYPE_INT]], i64 0} |