]> granicus.if.org Git - clang/commitdiff
[-cxx-abi microsoft] Properly mangle enums
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 9 Dec 2013 04:28:34 +0000 (04:28 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 9 Dec 2013 04:28:34 +0000 (04:28 +0000)
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".

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196752 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms.cpp

index ae4fbf7f0480ec8b08380f6f5d07357fa2b55160..0599d8af81320183324d6af87b5d76606418a627 100644 (file)
@@ -1472,7 +1472,7 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
 // <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(const TagDecl *TD) {
       Out << 'V';
       break;
     case TTK_Enum:
-      Out << 'W';
-      Out << getASTContext().getTypeSizeInChars(
-                cast<EnumDecl>(TD)->getIntegerType()).getQuantity();
+      Out << "W4";
       break;
   }
   mangleName(TD);
index 68ec2b3baf68b3c8d79e65847733a062c11a6459..62f98317504f895c9678d0b12a36344033bcad8f 100644 (file)
@@ -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@EnumMangling@@3W4Enum01@1@A"
+// CHECK-DAG: @"\01?BoolEnum@EnumMangling@@3W4Enum02@1@A
+// CHECK-DAG: @"\01?CharEnum@EnumMangling@@3W4Enum03@1@A
+// CHECK-DAG: @"\01?SCharEnum@EnumMangling@@3W4Enum04@1@A
+// CHECK-DAG: @"\01?UCharEnum@EnumMangling@@3W4Enum05@1@A
+// CHECK-DAG: @"\01?SShortEnum@EnumMangling@@3W4Enum06@1@A"
+// CHECK-DAG: @"\01?UShortEnum@EnumMangling@@3W4Enum07@1@A"
+// CHECK-DAG: @"\01?SIntEnum@EnumMangling@@3W4Enum08@1@A"
+// CHECK-DAG: @"\01?UIntEnum@EnumMangling@@3W4Enum09@1@A"
+// CHECK-DAG: @"\01?SLongEnum@EnumMangling@@3W4Enum10@1@A"
+// CHECK-DAG: @"\01?ULongEnum@EnumMangling@@3W4Enum11@1@A"
+// CHECK-DAG: @"\01?SLongLongEnum@EnumMangling@@3W4Enum12@1@A"
+// CHECK-DAG: @"\01?ULongLongEnum@EnumMangling@@3W4Enum13@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@EnumMangling@@3W4EnumClass01@1@A"
+// CHECK-DAG: @"\01?BoolEnumClass@EnumMangling@@3W4EnumClass02@1@A
+// CHECK-DAG: @"\01?CharEnumClass@EnumMangling@@3W4EnumClass03@1@A
+// CHECK-DAG: @"\01?SCharEnumClass@EnumMangling@@3W4EnumClass04@1@A
+// CHECK-DAG: @"\01?UCharEnumClass@EnumMangling@@3W4EnumClass05@1@A
+// CHECK-DAG: @"\01?SShortEnumClass@EnumMangling@@3W4EnumClass06@1@A"
+// CHECK-DAG: @"\01?UShortEnumClass@EnumMangling@@3W4EnumClass07@1@A"
+// CHECK-DAG: @"\01?SIntEnumClass@EnumMangling@@3W4EnumClass08@1@A"
+// CHECK-DAG: @"\01?UIntEnumClass@EnumMangling@@3W4EnumClass09@1@A"
+// CHECK-DAG: @"\01?SLongEnumClass@EnumMangling@@3W4EnumClass10@1@A"
+// CHECK-DAG: @"\01?ULongEnumClass@EnumMangling@@3W4EnumClass11@1@A"
+// CHECK-DAG: @"\01?SLongLongEnumClass@EnumMangling@@3W4EnumClass12@1@A"
+// CHECK-DAG: @"\01?ULongLongEnumClass@EnumMangling@@3W4EnumClass13@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@4HA"