[cfe-commits] r82102 - in /cfe/trunk: lib/CodeGen/Mangle.cpp test/CodeGenCXX/function-template-specialization.cpp test/CodeGenCXX/mangle-extreme.cpp test/CodeGenCXX/mangle-subst.cpp

Anders Carlsson andersca at mac.com
Wed Sep 16 17:43:46 PDT 2009


Author: andersca
Date: Wed Sep 16 19:43:46 2009
New Revision: 82102

URL: http://llvm.org/viewvc/llvm-project?rev=82102&view=rev
Log:
Add basic substitution to the C++ mangler. It currently only looks at types.

Added:
    cfe/trunk/test/CodeGenCXX/mangle-extreme.cpp
    cfe/trunk/test/CodeGenCXX/mangle-subst.cpp
Modified:
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/test/CodeGenCXX/function-template-specialization.cpp

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=82102&r1=82101&r2=82102&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Sep 16 19:43:46 2009
@@ -35,6 +35,8 @@
     unsigned StructorType;
     CXXCtorType CtorType;
 
+    llvm::DenseMap<uintptr_t, unsigned> Substitutions;
+    
   public:
     CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
       : Context(C), Out(os), Structor(0), StructorType(0) { }
@@ -53,6 +55,9 @@
     void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type);
 
   private:
+    bool mangleSubstitution(QualType T);
+    void addSubstitution(QualType T);
+    
     bool mangleFunctionDecl(const FunctionDecl *FD);
 
     void mangleFunctionEncoding(const FunctionDecl *FD);
@@ -521,20 +526,33 @@
   // Only operate on the canonical type!
   T = Context.getCanonicalType(T);
 
-  //  <type> ::= <CV-qualifiers> <type>
-  mangleCVQualifiers(T.getCVRQualifiers());
+  bool IsSubstitutable = !isa<BuiltinType>(T);
+  if (IsSubstitutable && mangleSubstitution(T))
+    return;
+
+  if (unsigned CVRQualifiers = T.getCVRQualifiers()) {
+    //  <type> ::= <CV-qualifiers> <type>
+    mangleCVQualifiers(CVRQualifiers);
 
-  switch (T->getTypeClass()) {
+    mangleType(T.getUnqualifiedType());
+  } else {
+    switch (T->getTypeClass()) {
 #define ABSTRACT_TYPE(CLASS, PARENT)
 #define NON_CANONICAL_TYPE(CLASS, PARENT) \
-  case Type::CLASS: \
-    llvm::llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
-    return;
+    case Type::CLASS: \
+      llvm::llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
+      return;
 #define TYPE(CLASS, PARENT) \
-  case Type::CLASS: \
-    return mangleType(static_cast<CLASS##Type*>(T.getTypePtr()));
+    case Type::CLASS: \
+      mangleType(static_cast<CLASS##Type*>(T.getTypePtr())); \
+      break;
 #include "clang/AST/TypeNodes.def"
+    }
   }
+
+  // Add the substitution.
+  if (IsSubstitutable)
+    addSubstitution(T);
 }
 
 void CXXNameMangler::mangleType(const BuiltinType *T) {
@@ -868,6 +886,52 @@
   }
 }
 
+// <substitution> ::= S <seq-id> _
+//                ::= S_
+bool CXXNameMangler::mangleSubstitution(QualType T) {
+  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+
+  llvm::DenseMap<uintptr_t, unsigned>::iterator I = 
+    Substitutions.find(TypePtr);
+  if (I == Substitutions.end())
+    return false;
+  
+  unsigned SeqID = I->second;
+  if (SeqID == 0)
+    Out << "S_";
+  else {
+    SeqID--;
+    
+    // <seq-id> is encoded in base-36, using digits and upper case letters.
+    char Buffer[10];
+    char *BufferPtr = Buffer + 9;
+    
+    *BufferPtr = 0;
+    if (SeqID == 0) *--BufferPtr = '0';
+    
+    while (SeqID) {
+      assert(BufferPtr > Buffer && "Buffer overflow!");
+      
+      unsigned char c = static_cast<unsigned char>(SeqID) % 36;
+      
+      *--BufferPtr =  (c < 10 ? '0' + c : 'A' + c - 10);
+      SeqID /= 36;
+    }
+    
+    Out << 'S' << BufferPtr << '_';
+  }
+  
+  return true;
+}
+
+void CXXNameMangler::addSubstitution(QualType T) {
+  uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+  unsigned SeqID = Substitutions.size();
+  
+  assert(!Substitutions.count(TypePtr) && "Substitution already exists!");
+  Substitutions[TypePtr] = SeqID;  
+}
+
 namespace clang {
   /// \brief Mangles the name of the declaration D and emits that name to the
   /// given output stream.

Modified: cfe/trunk/test/CodeGenCXX/function-template-specialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/function-template-specialization.cpp?rev=82102&r1=82101&r2=82102&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/function-template-specialization.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/function-template-specialization.cpp Wed Sep 16 19:43:46 2009
@@ -9,10 +9,10 @@
 
 void test(int *iptr, float *fptr, int diff) {
   // FIXME: should be "_Z4nextIiiEPT_S1_RKT0_"
-  // RUN: grep "_Z4nextIiiEPiPiRKi" %t &&
+  // RUN: grep "_Z4nextIiiEPiS_RKi" %t &&
   iptr = next(iptr, diff);
   // FIXME: should be "_Z4nextIfiEPT_S1_RKT0_"
-  // RUN: grep "_Z4nextIfiEPfPfRKi" %t &&
+  // RUN: grep "_Z4nextIfiEPfS_RKi" %t &&
   fptr = next(fptr, diff);
 }
 
@@ -22,6 +22,6 @@
 void test2(int *iptr, double *dptr, int diff) {
   iptr = next(iptr, diff);
   // FIXME: should be "_Z4nextIdiEPT_S1_RKT0_"
-  // RUN: grep "_Z4nextIdiEPdPdRKi" %t
+  // RUN: grep "_Z4nextIdiEPdS_RKi" %t
   dptr = next(dptr, diff);
 }

Added: cfe/trunk/test/CodeGenCXX/mangle-extreme.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-extreme.cpp?rev=82102&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-extreme.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-extreme.cpp Wed Sep 16 19:43:46 2009
@@ -0,0 +1,49 @@
+// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin10 && 
+
+struct X { };
+
+// RUN: grep "define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_(" %t &&
+void f(X****************************************,
+       X****************************************,
+       X***************************************,
+       X**************************************,
+       X*************************************,
+       X************************************,
+       X***********************************,
+       X**********************************,
+       X*********************************,
+       X********************************,
+       X*******************************,
+       X******************************,
+       X*****************************,
+       X****************************,
+       X***************************,
+       X**************************,
+       X*************************,
+       X************************,
+       X***********************,
+       X**********************,
+       X*********************,
+       X********************,
+       X*******************,
+       X******************,
+       X*****************,
+       X****************,
+       X***************,
+       X**************,
+       X*************,
+       X************,
+       X***********,
+       X**********,
+       X*********,
+       X********,
+       X*******,
+       X******,
+       X*****,
+       X****,
+       X***,
+       X**,
+       X*,
+       X) { }
+       
+// RUN: true

Added: cfe/trunk/test/CodeGenCXX/mangle-subst.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-subst.cpp?rev=82102&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-subst.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-subst.cpp Wed Sep 16 19:43:46 2009
@@ -0,0 +1,20 @@
+// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 && 
+
+struct X {};
+
+// RUN: grep "define void @_Z1f1XS_" %t | count 1 &&
+void f(X, X) { }
+
+// RUN: grep "define void @_Z1fR1XS0_" %t | count 1 &&
+void f(X&, X&) { }
+
+// RUN: grep "define void @_Z1fRK1XS1_" %t | count 1 &&
+void f(const X&, const X&) { }
+
+typedef void T();
+struct S {};
+
+// RUN: grep "define void @_Z1fPFvvEM1SFvvE" %t | count 1 &&
+void f(T*, T (S::*)) {}
+
+// RUN: true





More information about the cfe-commits mailing list