r196752 - [-cxx-abi microsoft] Properly mangle enums

David Majnemer david.majnemer at gmail.com
Sun Dec 8 20:28:34 PST 2013


Author: majnemer
Date: Sun Dec  8 22:28:34 2013
New Revision: 196752

URL: http://llvm.org/viewvc/llvm-project?rev=196752&view=rev
Log:
[-cxx-abi microsoft] Properly mangle enums

While testing our ability to mangle large constants (PR18175), I
incidentally discovered that we did not properly mangle enums correctly.

Previously, we would append the width of the enum in bytes after the
type-tag differentiator.

This would mean "enum : short" would be mangled as 'W2' while "enum :
char" would be mangled as 'W1'.  Upon testing this with several versions
of MSVC, I found that this did not match their behavior: they always use
'W4'.

N.B.  Quick testing uncovered that undname allows different numbers to
follow the 'W' in the following way:

'W0' -> "enum char"
'W1' -> "enum unsigned char"
'W2' -> "enum short"
'W3' -> "enum unsigned short"
'W4' -> "enum"
'W5' -> "enum unsigned int"
'W6' -> "enum long"
'W7' -> "enum unsigned long"

However this scheme appears abandoned, I cannot get MSVC to trigger it.
Furthermore, it's incomplete: it doesn't handle "bool" or "long long".

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

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=196752&r1=196751&r2=196752&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Sun Dec  8 22:28:34 2013
@@ -1472,7 +1472,7 @@ void MicrosoftCXXNameMangler::mangleType
 // <union-type>  ::= T <name>
 // <struct-type> ::= U <name>
 // <class-type>  ::= V <name>
-// <enum-type>   ::= W <size> <name>
+// <enum-type>   ::= W4 <name>
 void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) {
   mangleType(cast<TagType>(T)->getDecl());
 }
@@ -1492,9 +1492,7 @@ void MicrosoftCXXNameMangler::mangleType
       Out << 'V';
       break;
     case TTK_Enum:
-      Out << 'W';
-      Out << getASTContext().getTypeSizeInChars(
-                cast<EnumDecl>(TD)->getIntegerType()).getQuantity();
+      Out << "W4";
       break;
   }
   mangleName(TD);

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=196752&r1=196751&r2=196752&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Sun Dec  8 22:28:34 2013
@@ -246,6 +246,87 @@ namespace PR13182 {
   }
 }
 
+namespace EnumMangling {
+  extern enum Enum01 { } Enum;
+  extern enum Enum02 : bool { } BoolEnum;
+  extern enum Enum03 : char { } CharEnum;
+  extern enum Enum04 : signed char { } SCharEnum;
+  extern enum Enum05 : unsigned char { } UCharEnum;
+  extern enum Enum06 : short { } SShortEnum;
+  extern enum Enum07 : unsigned short { } UShortEnum;
+  extern enum Enum08 : int { } SIntEnum;
+  extern enum Enum09 : unsigned int { } UIntEnum;
+  extern enum Enum10 : long { } SLongEnum;
+  extern enum Enum11 : unsigned long { } ULongEnum;
+  extern enum Enum12 : long long { } SLongLongEnum;
+  extern enum Enum13 : unsigned long long { } ULongLongEnum;
+// CHECK-DAG: @"\01?Enum at EnumMangling@@3W4Enum01 at 1@A"
+// CHECK-DAG: @"\01?BoolEnum at EnumMangling@@3W4Enum02 at 1@A
+// CHECK-DAG: @"\01?CharEnum at EnumMangling@@3W4Enum03 at 1@A
+// CHECK-DAG: @"\01?SCharEnum at EnumMangling@@3W4Enum04 at 1@A
+// CHECK-DAG: @"\01?UCharEnum at EnumMangling@@3W4Enum05 at 1@A
+// CHECK-DAG: @"\01?SShortEnum at EnumMangling@@3W4Enum06 at 1@A"
+// CHECK-DAG: @"\01?UShortEnum at EnumMangling@@3W4Enum07 at 1@A"
+// CHECK-DAG: @"\01?SIntEnum at EnumMangling@@3W4Enum08 at 1@A"
+// CHECK-DAG: @"\01?UIntEnum at EnumMangling@@3W4Enum09 at 1@A"
+// CHECK-DAG: @"\01?SLongEnum at EnumMangling@@3W4Enum10 at 1@A"
+// CHECK-DAG: @"\01?ULongEnum at EnumMangling@@3W4Enum11 at 1@A"
+// CHECK-DAG: @"\01?SLongLongEnum at EnumMangling@@3W4Enum12 at 1@A"
+// CHECK-DAG: @"\01?ULongLongEnum at EnumMangling@@3W4Enum13 at 1@A"
+  decltype(Enum) *UseEnum() { return &Enum; }
+  decltype(BoolEnum) *UseBoolEnum() { return &BoolEnum; }
+  decltype(CharEnum) *UseCharEnum() { return &CharEnum; }
+  decltype(SCharEnum) *UseSCharEnum() { return &SCharEnum; }
+  decltype(UCharEnum) *UseUCharEnum() { return &UCharEnum; }
+  decltype(SShortEnum) *UseSShortEnum() { return &SShortEnum; }
+  decltype(UShortEnum) *UseUShortEnum() { return &UShortEnum; }
+  decltype(SIntEnum) *UseSIntEnum() { return &SIntEnum; }
+  decltype(UIntEnum) *UseUIntEnum() { return &UIntEnum; }
+  decltype(SLongEnum) *UseSLongEnum() { return &SLongEnum; }
+  decltype(ULongEnum) *UseULongEnum() { return &ULongEnum; }
+  decltype(SLongLongEnum) *UseSLongLongEnum() { return &SLongLongEnum; }
+  decltype(ULongLongEnum) *UseULongLongEnum() { return &ULongLongEnum; }
+  extern enum class EnumClass01 { } EnumClass;
+  extern enum class EnumClass02 : bool { } BoolEnumClass;
+  extern enum class EnumClass03 : char { } CharEnumClass;
+  extern enum class EnumClass04 : signed char { } SCharEnumClass;
+  extern enum class EnumClass05 : unsigned char { } UCharEnumClass;
+  extern enum class EnumClass06 : short { } SShortEnumClass;
+  extern enum class EnumClass07 : unsigned short { } UShortEnumClass;
+  extern enum class EnumClass08 : int { } SIntEnumClass;
+  extern enum class EnumClass09 : unsigned int { } UIntEnumClass;
+  extern enum class EnumClass10 : long { } SLongEnumClass;
+  extern enum class EnumClass11 : unsigned long { } ULongEnumClass;
+  extern enum class EnumClass12 : long long { } SLongLongEnumClass;
+  extern enum class EnumClass13 : unsigned long long { } ULongLongEnumClass;
+// CHECK-DAG: @"\01?EnumClass at EnumMangling@@3W4EnumClass01 at 1@A"
+// CHECK-DAG: @"\01?BoolEnumClass at EnumMangling@@3W4EnumClass02 at 1@A
+// CHECK-DAG: @"\01?CharEnumClass at EnumMangling@@3W4EnumClass03 at 1@A
+// CHECK-DAG: @"\01?SCharEnumClass at EnumMangling@@3W4EnumClass04 at 1@A
+// CHECK-DAG: @"\01?UCharEnumClass at EnumMangling@@3W4EnumClass05 at 1@A
+// CHECK-DAG: @"\01?SShortEnumClass at EnumMangling@@3W4EnumClass06 at 1@A"
+// CHECK-DAG: @"\01?UShortEnumClass at EnumMangling@@3W4EnumClass07 at 1@A"
+// CHECK-DAG: @"\01?SIntEnumClass at EnumMangling@@3W4EnumClass08 at 1@A"
+// CHECK-DAG: @"\01?UIntEnumClass at EnumMangling@@3W4EnumClass09 at 1@A"
+// CHECK-DAG: @"\01?SLongEnumClass at EnumMangling@@3W4EnumClass10 at 1@A"
+// CHECK-DAG: @"\01?ULongEnumClass at EnumMangling@@3W4EnumClass11 at 1@A"
+// CHECK-DAG: @"\01?SLongLongEnumClass at EnumMangling@@3W4EnumClass12 at 1@A"
+// CHECK-DAG: @"\01?ULongLongEnumClass at EnumMangling@@3W4EnumClass13 at 1@A"
+  decltype(EnumClass) *UseEnumClass() { return &EnumClass; }
+  decltype(BoolEnumClass) *UseBoolEnumClass() { return &BoolEnumClass; }
+  decltype(CharEnumClass) *UseCharEnumClass() { return &CharEnumClass; }
+  decltype(SCharEnumClass) *UseSCharEnumClass() { return &SCharEnumClass; }
+  decltype(UCharEnumClass) *UseUCharEnumClass() { return &UCharEnumClass; }
+  decltype(SShortEnumClass) *UseSShortEnumClass() { return &SShortEnumClass; }
+  decltype(UShortEnumClass) *UseUShortEnumClass() { return &UShortEnumClass; }
+  decltype(SIntEnumClass) *UseSIntEnumClass() { return &SIntEnumClass; }
+  decltype(UIntEnumClass) *UseUIntEnumClass() { return &UIntEnumClass; }
+  decltype(SLongEnumClass) *UseSLongEnumClass() { return &SLongEnumClass; }
+  decltype(ULongEnumClass) *UseULongEnumClass() { return &ULongEnumClass; }
+  decltype(SLongLongEnumClass) *UseSLongLongEnumClass() { return &SLongLongEnumClass; }
+  decltype(ULongLongEnumClass) *UseULongLongEnumClass() { return &ULongLongEnumClass; }
+}
+
 extern "C" inline void extern_c_func() {
   static int local;
 // CHECK-DAG: @"\01?local@?1??extern_c_func@@9 at 4HA"





More information about the cfe-commits mailing list