r190488 - [-cxx-abi microsoft] Canonicalize array parameters better

David Majnemer david.majnemer at gmail.com
Tue Sep 10 21:44:30 PDT 2013


Author: majnemer
Date: Tue Sep 10 23:44:30 2013
New Revision: 190488

URL: http://llvm.org/viewvc/llvm-project?rev=190488&view=rev
Log:
[-cxx-abi microsoft] Canonicalize array parameters better

Summary:
More accurately characterize the nature of array parameters. Doing this
removes false back-reference opportunities.  Remove some hacks now that
we characterize these better.

Reviewers: rnk, timurrrr, whunt, cdavis5x

CC: cfe-commits

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

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=190488&r1=190487&r2=190488&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue Sep 10 23:44:30 2013
@@ -125,7 +125,7 @@ private:
 #undef TYPE
   
   void mangleType(const TagDecl *TD);
-  void mangleDecayedArrayType(const ArrayType *T, bool IsGlobal);
+  void mangleDecayedArrayType(const ArrayType *T);
   void mangleArrayType(const ArrayType *T);
   void mangleFunctionClass(const FunctionDecl *FD);
   void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false);
@@ -337,7 +337,7 @@ void MicrosoftCXXNameMangler::mangleVari
       mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
   } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
     // Global arrays are funny, too.
-    mangleDecayedArrayType(AT, true);
+    mangleDecayedArrayType(AT);
     if (AT->getElementType()->isArrayType())
       Out << 'A';
     else
@@ -1057,25 +1057,30 @@ void MicrosoftCXXNameMangler::mangleArgu
                                                  SourceRange Range) {
   // MSVC will backreference two canonically equivalent types that have slightly
   // different manglings when mangled alone.
-  void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();
+
+  // Decayed types do not match up with non-decayed versions of the same type.
+  //
+  // e.g.
+  // void (*x)(void) will not form a backreference with void x(void)
+  void *TypePtr;
+  if (const DecayedType *DT = T->getAs<DecayedType>()) {
+    TypePtr = DT->getOriginalType().getCanonicalType().getAsOpaquePtr();
+    // If the original parameter was textually written as an array,
+    // instead treat the decayed parameter like it's const.
+    //
+    // e.g.
+    // int [] -> int * const
+    if (DT->getOriginalType()->isArrayType())
+      T = T.withConst();
+  } else
+    TypePtr = T.getCanonicalType().getAsOpaquePtr();
+
   ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
 
   if (Found == TypeBackReferences.end()) {
     size_t OutSizeBefore = Out.GetNumBytesInBuffer();
 
-    if (const DecayedType *DT = T->getAs<DecayedType>()) {
-      QualType OT = DT->getOriginalType();
-      if (const ArrayType *AT = getASTContext().getAsArrayType(OT)) {
-        mangleDecayedArrayType(AT, false);
-      } else if (const FunctionType *FT = OT->getAs<FunctionType>()) {
-        Out << "P6";
-        mangleFunctionType(FT, 0, false, false);
-      } else {
-        llvm_unreachable("unexpected decayed type");
-      }
-    } else {
-      mangleType(T, Range, QMM_Drop);
-    }
+    mangleType(T, Range, QMM_Drop);
 
     // See if it's worth creating a back reference.
     // Only types longer than 1 character are considered
@@ -1467,22 +1472,13 @@ void MicrosoftCXXNameMangler::mangleType
 // <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
 //                  [Y <dimension-count> <dimension>+]
 //                  <element-type> # as global, E is never required
-//              ::= Q E? <cvr-qualifiers> [Y <dimension-count> <dimension>+]
-//                  <element-type> # as param, E is required for 64-bit
 // It's supposed to be the other way around, but for some strange reason, it
 // isn't. Today this behavior is retained for the sole purpose of backwards
 // compatibility.
-void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T,
-                                                     bool IsGlobal) {
+void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
   // This isn't a recursive mangling, so now we have to do it all in this
   // one call.
-  if (IsGlobal) {
-    manglePointerQualifiers(T->getElementType().getQualifiers());
-  } else {
-    Out << 'Q';
-    if (PointersAre64Bit)
-      Out << 'E';
-  }
+  manglePointerQualifiers(T->getElementType().getQualifiers());
   mangleType(T->getElementType(), SourceRange());
 }
 void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp?rev=190488&r1=190487&r2=190488&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp Tue Sep 10 23:44:30 2013
@@ -204,3 +204,37 @@ void mangle_fwd(char * x) {}
 void mangle_no_fwd(char * x) {}
 // CHECK: "\01?mangle_no_fwd@@YAXPAD at Z"
 // X64:   "\01?mangle_no_fwd@@YAXPEAD at Z"
+
+// The first argument gets mangled as-if it were written "int *const"
+// The second arg should not form a backref because it isn't qualified
+void mangle_no_backref0(int[], int *) {}
+// CHECK: "\01?mangle_no_backref0@@YAXQAHPAH at Z"
+// X64:   "\01?mangle_no_backref0@@YAXQEAHPEAH at Z"
+
+void mangle_no_backref1(int[], int *const) {}
+// CHECK: "\01?mangle_no_backref1@@YAXQAHQAH at Z"
+// X64:   "\01?mangle_no_backref1@@YAXQEAHQEAH at Z"
+
+typedef void fun_type(void);
+typedef void (*ptr_to_fun_type)(void);
+
+// Pointer to function types don't backref with function types
+void mangle_no_backref2(fun_type, ptr_to_fun_type) {}
+// CHECK: "\01?mangle_no_backref2@@YAXP6AXXZP6AXXZ at Z"
+// X64:   "\01?mangle_no_backref2@@YAXP6AXXZP6AXXZ at Z"
+
+void mangle_yes_backref0(int[], int []) {}
+// CHECK: "\01?mangle_yes_backref0@@YAXQAH0 at Z"
+// X64:   "\01?mangle_yes_backref0@@YAXQEAH0 at Z"
+
+void mangle_yes_backref1(int *const, int *const) {}
+// CHECK: "\01?mangle_yes_backref1@@YAXQAH0 at Z"
+// X64:   "\01?mangle_yes_backref1@@YAXQEAH0 at Z"
+
+void mangle_yes_backref2(fun_type *const[], ptr_to_fun_type const[]) {}
+// CHECK: "\01?mangle_yes_backref2@@YAXQBQ6AXXZ0 at Z"
+// X64:   "\01?mangle_yes_backref2@@YAXQEBQ6AXXZ0 at Z"
+
+void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {}
+// CHECK: "\01?mangle_yes_backref3@@YAXQAP6AXXZ0 at Z"
+// X64:   "\01?mangle_yes_backref3@@YAXQEAP6AXXZ0 at Z"





More information about the cfe-commits mailing list