[cfe-commits] r159059 - in /cfe/trunk: lib/AST/MicrosoftMangle.cpp test/CodeGenCXX/mangle-ms-back-references.cpp

Timur Iskhodzhanov timurrrr at google.com
Fri Jun 22 17:54:17 PDT 2012


Author: timurrrr
Date: Fri Jun 22 19:54:17 2012
New Revision: 159059

URL: http://llvm.org/viewvc/llvm-project?rev=159059&view=rev
Log:
[Windows] Fix mangling of repeated types in the presence of bool and function pointers PR13176,PR13177

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-back-references.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=159059&r1=159058&r2=159059&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Jun 22 19:54:17 2012
@@ -31,8 +31,8 @@
   MangleContext &Context;
   raw_ostream &Out;
 
-  typedef llvm::DenseMap<const IdentifierInfo*, unsigned> BackRefMap;
-  BackRefMap BackReferences;
+  typedef llvm::DenseMap<void*, unsigned> BackRefMap;
+  BackRefMap NameBackReferences, TypeBackReferences;
 
   ASTContext &getASTContext() const { return Context.getASTContext(); }
 
@@ -66,6 +66,8 @@
   void mangleObjCMethodName(const ObjCMethodDecl *MD);
   void mangleLocalName(const FunctionDecl *FD);
 
+  void mangleTypeRepeated(QualType T, SourceRange Range);
+
   // Declare manglers for every type class.
 #define ABSTRACT_TYPE(CLASS, PARENT)
 #define NON_CANONICAL_TYPE(CLASS, PARENT)
@@ -644,12 +646,12 @@
 
 void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
   // <source name> ::= <identifier> @
-  BackRefMap::iterator Found = BackReferences.find(II);
-  if (Found == BackReferences.end()) {
+  BackRefMap::iterator Found = NameBackReferences.find((void*)II);
+  if (Found == NameBackReferences.end()) {
     Out << II->getName() << '@';
-    if (BackReferences.size() < 10) {
-      size_t Size = BackReferences.size();
-      BackReferences[II] = Size;
+    if (NameBackReferences.size() < 10) {
+      size_t Size = NameBackReferences.size();
+      NameBackReferences[(void*)II] = Size;
     }
   } else {
     Out << Found->second;
@@ -852,6 +854,28 @@
   // FIXME: For now, just drop all extension qualifiers on the floor.
 }
 
+void MicrosoftCXXNameMangler::mangleTypeRepeated(QualType T, SourceRange Range) {
+  void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();
+  BackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
+
+  if (Found == TypeBackReferences.end()) {
+    size_t OutSizeBefore = Out.GetNumBytesInBuffer();
+
+    mangleType(T,Range);
+
+    // See if it's worth creating a back reference.
+    // Only types longer than 1 character are considered
+    // and only 10 back references slots are available:
+    bool LongerThanOneChar = (Out.GetNumBytesInBuffer() - OutSizeBefore > 1);
+    if (LongerThanOneChar && TypeBackReferences.size() < 10) {
+      size_t Size = TypeBackReferences.size();
+      TypeBackReferences[TypePtr] = Size;
+    }
+  } else {
+    Out << Found->second;
+  }
+}
+
 void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range) {
   // Only operate on the canonical type!
   T = getASTContext().getCanonicalType(T);
@@ -1026,8 +1050,6 @@
   if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
     Out << 'X';
   } else {
-    typedef llvm::DenseMap<void*, unsigned> BackRef;
-    BackRef BackReferences;
     if (D) {
       // If we got a decl, use the type-as-written to make sure arrays
       // get mangled right.  Note that we can't rely on the TSI
@@ -1036,24 +1058,14 @@
              ParmEnd = D->param_end(); Parm != ParmEnd; ++Parm) {
         TypeSourceInfo *TSI = (*Parm)->getTypeSourceInfo();
         QualType Type = TSI ? TSI->getType() : (*Parm)->getType();
-        CanQualType Canonical = getASTContext().getCanonicalType(Type);
-        void *TypePtr = Canonical.getAsOpaquePtr();
-        BackRef::iterator Found = BackReferences.find(TypePtr);
-        if (Found == BackReferences.end()) {
-          mangleType(Type, (*Parm)->getSourceRange());
-          if (BackReferences.size() < 10 && (Canonical->getTypeClass() != Type::Builtin)) {
-            size_t Size = BackReferences.size();
-            BackReferences[TypePtr] = Size;
-          }
-        } else {
-          Out << Found->second;
-        }
+        mangleTypeRepeated(Type, (*Parm)->getSourceRange());
       }
     } else {
+      // Happens for function pointer type arguments for example.
       for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
            ArgEnd = Proto->arg_type_end();
            Arg != ArgEnd; ++Arg)
-        mangleType(*Arg, SourceRange());
+        mangleTypeRepeated(*Arg, SourceRange());
     }
     // <builtin-type>      ::= Z  # ellipsis
     if (Proto->isVariadic())

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-back-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-back-references.cpp?rev=159059&r1=159058&r2=159059&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-back-references.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-back-references.cpp Fri Jun 22 19:54:17 2012
@@ -12,17 +12,35 @@
 const char *f4(const char* a, const char* b) {}
 // CHECK: "\01?f4@@YAPBDPBD0 at Z"
 
+void f5(char const* a, unsigned int b, char c, void const* d, char const* e, unsigned int f) {}
+// CHECK: "\01?f5@@YAXPBDIDPBX0I at Z"
+
+void f6(bool a, bool b) {}
+// CHECK: "\01?f6@@YAX_N0 at Z"
+
+void f7(int a, int* b, int c, int* d, bool e, bool f, bool* g) {}
+// CHECK: "\01?f7@@YAXHPAHH0_N1PA_N at Z"
+
 // FIXME: tests for more than 10 types?
 
-struct S {};
+struct S {
+  void mbb(bool a, bool b) {}
+};
 
-void g4(const char* a, struct S* b, const char *c, struct S* d) {}
-// CHECK: "\01?g4@@YAXPBDPAUS@@01 at Z"
+void g1(struct S a) {}
+// CHECK: "\01?g1@@YAXUS@@@Z"
 
-typedef void (*VoidFunc)();
+void g2(struct S a, struct S b) {}
+// CHECK: "\01?g2@@YAXUS@@0 at Z"
+
+void g3(struct S a, struct S b, struct S* c, struct S* d) {}
+// CHECK: "\01?g3@@YAXUS@@0PAU1 at 1@Z"
 
-void foo_ptr(const char* a, const char* b, VoidFunc c, VoidFunc d) {}
-// CHECK: @"\01?foo_ptr@@YAXPBD0P6AXXZ1 at Z"
+void g4(const char* a, struct S* b, const char* c, struct S* d) {
+// CHECK: "\01?g4@@YAXPBDPAUS@@01 at Z"
+  b->mbb(false, false);
+// CHECK: "\01?mbb at S@@QAEX_N0 at Z"
+}
 
 // Make sure that different aliases of built-in types end up mangled as the
 // built-ins.
@@ -30,3 +48,16 @@
 typedef unsigned int size_t;
 void *h(size_t a, uintptr_t b) {}
 // CHECK: "\01?h@@YAPAXII at Z"
+
+// Function pointers might be mangled in a complex way.
+typedef void (*VoidFunc)();
+typedef int* (*PInt3Func)(int* a, int* b);
+
+void h1(const char* a, const char* b, VoidFunc c, VoidFunc d) {}
+// CHECK: "\01?h1@@YAXPBD0P6AXXZ1 at Z"
+
+void h2(void (*f_ptr)(void *), void *arg) {}
+// CHECK: "\01?h2@@YAXP6AXPAX at Z0@Z"
+
+PInt3Func h3(PInt3Func x, PInt3Func y, int* z) { return 0; }
+// CHECK: "\01?h3@@YAP6APAHPAH0 at ZP6APAH00@Z10 at Z"





More information about the cfe-commits mailing list