]> granicus.if.org Git - clang/commitdiff
Merging r195168:
authorBill Wendling <isanbard@gmail.com>
Wed, 20 Nov 2013 06:46:42 +0000 (06:46 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 20 Nov 2013 06:46:42 +0000 (06:46 +0000)
------------------------------------------------------------------------
r195168 | rnk | 2013-11-19 15:23:00 -0800 (Tue, 19 Nov 2013) | 17 lines

Add a mangler entry point for TBAA rather than using RTTI directly

Summary:
RTTI is not yet implemented for the Microsoft C++ ABI and isn't expected
soon.  We could easily add the mangling, but the error is what prevents
us from silently miscompiling code that expects RTTI.

Instead, add a new mangleTypeName entry point that simply forwards to
mangleName or mangleType to produce a string that isn't part of the ABI.
Itanium can continue to use RTTI names to avoid unecessary test
breakage.

This also seems like the right design.  The fact that TBAA names happen
to be RTTI names is now an implementation detail of the mangler, rather
than part of TBAA.

Differential Revision: http://llvm-reviews.chandlerc.com/D2153
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@195227 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Mangle.h
lib/AST/ItaniumMangle.cpp
lib/AST/MicrosoftMangle.cpp
lib/CodeGen/CodeGenTBAA.cpp
test/CodeGen/tbaa-ms-abi.cpp [new file with mode: 0644]

index e875c31fc002f9692f2d73560b6a16c3d617dcf9..4df2955aecc2ca90832a7224d9be48bbd6f5dfbf 100644 (file)
@@ -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;
+
   /// @}
 };
 
index e94b4cf90732b37f8f50b3543f744bfa50e1b3a9..0621d7b1ad868bdaad433a1b3ae09eb09e0cde09 100644 (file)
@@ -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);
index ff1b0158c5d06a64747b92661d68de5975c835b4..ed7168e3eb049eb6857bf399240a98b05251637d 100644 (file)
@@ -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) {
index 11e376ff4034cd1781d3d9417a8fc4300526e358..699cc2eabe184c12e5f13cb1cde76b6ffc5a2d8f 100644 (file)
@@ -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 (file)
index 0000000..67390b1
--- /dev/null
@@ -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}