diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index e875c31fc002..4df2955aecc2 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/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/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index e94b4cf90732..0621d7b1ad86 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/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/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index ff1b0158c5d0..ed7168e3eb04 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/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/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 11e376ff4034..699cc2eabe18 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/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/clang/test/CodeGen/tbaa-ms-abi.cpp b/clang/test/CodeGen/tbaa-ms-abi.cpp new file mode 100644 index 000000000000..67390b1a8a54 --- /dev/null +++ b/clang/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}