[cfe-commits] r105931 - in /cfe/trunk: lib/CodeGen/MicrosoftCXXABI.cpp test/CodeGenCXX/mangle-ms.cpp

Charles Davis cdavis at mines.edu
Sun Jun 13 22:29:01 PDT 2010


Author: cdavis
Date: Mon Jun 14 00:29:01 2010
New Revision: 105931

URL: http://llvm.org/viewvc/llvm-project?rev=105931&view=rev
Log:
Microsoft C++ Mangler:
- Mangle qualifiers.
- Start mangling variables' types into the name. A variable declared with a
  builtin type should now mangle properly.

Modified:
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms.cpp

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=105931&r1=105930&r2=105931&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Mon Jun 14 00:29:01 2010
@@ -45,6 +45,7 @@
 
   void mangle(const NamedDecl *D, llvm::StringRef Prefix = "?");
   void mangleName(const NamedDecl *ND);
+  void mangleVariableEncoding(const VarDecl *VD);
   void mangleType(QualType T);
 
 private:
@@ -54,6 +55,7 @@
   void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
   void mangleSourceName(const IdentifierInfo *II);
   void manglePostfix(const DeclContext *DC, bool NoFunction=false);
+  void mangleQualifiers(Qualifiers Quals, bool IsMember);
 
   void mangleObjCMethodName(const ObjCMethodDecl *MD);
 
@@ -175,7 +177,38 @@
   // <mangled-name> ::= ? <name> <type>
   Out << Prefix;
   mangleName(D);
-  // TODO: Mangle type.
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+    mangleVariableEncoding(VD);
+  // TODO: Function types.
+}
+
+void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
+  // <encoding> ::= <variable name> <storage-class> <variable-type>
+  // <storage-class> ::= 0  # private static member
+  //                 ::= 1  # protected static member
+  //                 ::= 2  # public static member
+  //                 ::= 3  # global
+  //                 ::= 4  # static local
+  
+  // The first character in the encoding (after the name) is the storage class.
+  if (VD->isStaticDataMember()) {
+    // If it's a static member, it also encodes the access level.
+    switch (VD->getAccess()) {
+      default:
+      case AS_private: Out << '0'; break;
+      case AS_protected: Out << '1'; break;
+      case AS_public: Out << '2'; break;
+    }
+  }
+  else if (!VD->isStaticLocal())
+    Out << '3';
+  else
+    Out << '4';
+  // Now mangle the type.
+  // <variable-type> ::= <type> <cvr-qualifiers>
+  QualType Ty = VD->getType();
+  mangleType(Ty.getLocalUnqualifiedType());
+  mangleQualifiers(Ty.getLocalQualifiers(), false);
 }
 
 void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
@@ -313,6 +346,88 @@
   Out << Buffer;
 }
 
+void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
+                                               bool IsMember) {
+  // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
+  // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);
+  // 'I' means __restrict (32/64-bit).
+  // Note that the MSVC __restrict keyword isn't the same as the C99 restrict
+  // keyword!
+  // <base-cvr-qualifiers> ::= A  # near
+  //                       ::= B  # near const
+  //                       ::= C  # near volatile
+  //                       ::= D  # near const volatile
+  //                       ::= E  # far (16-bit)
+  //                       ::= F  # far const (16-bit)
+  //                       ::= G  # far volatile (16-bit)
+  //                       ::= H  # far const volatile (16-bit)
+  //                       ::= I  # huge (16-bit)
+  //                       ::= J  # huge const (16-bit)
+  //                       ::= K  # huge volatile (16-bit)
+  //                       ::= L  # huge const volatile (16-bit)
+  //                       ::= M <basis> # based
+  //                       ::= N <basis> # based const
+  //                       ::= O <basis> # based volatile
+  //                       ::= P <basis> # based const volatile
+  //                       ::= Q  # near member
+  //                       ::= R  # near const member
+  //                       ::= S  # near volatile member
+  //                       ::= T  # near const volatile member
+  //                       ::= U  # far member (16-bit)
+  //                       ::= V  # far const member (16-bit)
+  //                       ::= W  # far volatile member (16-bit)
+  //                       ::= X  # far const volatile member (16-bit)
+  //                       ::= Y  # huge member (16-bit)
+  //                       ::= Z  # huge const member (16-bit)
+  //                       ::= 0  # huge volatile member (16-bit)
+  //                       ::= 1  # huge const volatile member (16-bit)
+  //                       ::= 2 <basis> # based member
+  //                       ::= 3 <basis> # based const member
+  //                       ::= 4 <basis> # based volatile member
+  //                       ::= 5 <basis> # based const volatile member
+  //                       ::= 6  # near function (pointers only)
+  //                       ::= 7  # far function (pointers only)
+  //                       ::= 8  # near method (pointers only)
+  //                       ::= 9  # far method (pointers only)
+  //                       ::= _A <basis> # based function (pointers only)
+  //                       ::= _B <basis> # based function (far?) (pointers only)
+  //                       ::= _C <basis> # based method (pointers only)
+  //                       ::= _D <basis> # based method (far?) (pointers only)
+  // <basis> ::= 0 # __based(void)
+  //         ::= 1 # __based(segment)?
+  //         ::= 2 <name> # __based(name)
+  //         ::= 3 # ?
+  //         ::= 4 # ?
+  //         ::= 5 # not really based
+  if (!IsMember) {
+    if (!Quals.hasVolatile()) {
+      if (!Quals.hasConst())
+        Out << 'A';
+      else
+        Out << 'B';
+    } else {
+      if (!Quals.hasConst())
+        Out << 'C';
+      else
+        Out << 'D';
+    }
+  } else {
+    if (!Quals.hasVolatile()) {
+      if (!Quals.hasConst())
+        Out << 'Q';
+      else
+        Out << 'R';
+    } else {
+      if (!Quals.hasConst())
+        Out << 'S';
+      else
+        Out << 'T';
+    }
+  }
+
+  // FIXME: For now, just drop all extension qualifiers on the floor.
+}
+
 void MicrosoftCXXNameMangler::mangleType(QualType T) {
   // Only operate on the canonical type!
   T = getASTContext().getCanonicalType(T);

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=105931&r1=105930&r2=105931&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Mon Jun 14 00:29:01 2010
@@ -1,8 +1,11 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
 
-// CHECK: @"\01?a@@"
-// CHECK: @"\01?b at N@@"
+// CHECK: @"\01?a@@3HA"
+// CHECK: @"\01?b at N@@3HA"
 // CHECK: @c
+// CHECK: @"\01?d at foo@@0FB"
+// CHECK: @"\01?e at foo@@1JC"
+// CHECK: @"\01?f at foo@@2DD"
 
 int a;
 
@@ -11,3 +14,15 @@
 static int c;
 int _c(void) {return c;}
 
+class foo {
+  static const short d;
+protected:
+  static volatile long e;
+public:
+  static const volatile char f;
+};
+
+const short foo::d = 0;
+volatile long foo::e;
+const volatile char foo::f = 'C';
+





More information about the cfe-commits mailing list