Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6187,7 +6187,7 @@ StringRef lookupStr(const IdentifierInfo *ID); }; -/// TypeString encodings for union fields must be order. +/// TypeString encodings for enum & union fields must be order. /// FieldEncoding is a helper for this ordering process. class FieldEncoding { bool HasName; @@ -6457,12 +6457,12 @@ // We collect all encoded fields and order as necessary. bool IsRecursive = false; - SmallVector FE; const RecordDecl *RD = RT->getDecl()->getDefinition(); if (RD && !RD->field_empty()) { // An incomplete TypeString stub is placed in the cache for this RecordType // so that recursive calls to this RecordType will use it whilst building a // complete TypeString for this RecordType. + SmallVector FE; std::string StubEnc(Enc.substr(Start).str()); StubEnc += '}'; // StubEnc now holds a valid incomplete TypeString. TSC.addIncomplete(ID, std::move(StubEnc)); @@ -6475,15 +6475,14 @@ // See FieldEncoding::operator< for sort algorithm. if (RT->isUnionType()) std::sort(FE.begin(), FE.end()); - } - - // We can now complete the TypeString. - if (unsigned E = FE.size()) + // We can now complete the TypeString. + unsigned E = FE.size(); for (unsigned I = 0; I != E; ++I) { if (I) Enc += ','; Enc += FE[I].str(); } + } Enc += '}'; TSC.addIfComplete(ID, Enc.substr(Start), IsRecursive); return true; @@ -6505,18 +6504,26 @@ if (ID) Enc += ID->getName(); Enc += "){"; + + // We collect all encoded enumerations and order them alphanumerically. if (const EnumDecl *ED = ET->getDecl()->getDefinition()) { - auto I = ED->enumerator_begin(); - auto E = ED->enumerator_end(); - while (I != E) { - Enc += "m("; - Enc += I->getName(); - Enc += "){"; - I->getInitVal().toString(Enc); - Enc += '}'; - ++I; - if (I != E) + SmallVector FE; + for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E; + ++I) { + SmallStringEnc EnumEnc; + EnumEnc += "m("; + EnumEnc += I->getName(); + EnumEnc += "){"; + I->getInitVal().toString(EnumEnc); + EnumEnc += '}'; + FE.push_back(FieldEncoding(!I->getName().empty(), EnumEnc)); + } + std::sort(FE.begin(), FE.end()); + unsigned E = FE.size(); + for (unsigned I = 0; I != E; ++I) { + if (I) Enc += ','; + Enc += FE[I].str(); } } Enc += '}'; Index: test/CodeGen/xcore-stringtype.c =================================================================== --- test/CodeGen/xcore-stringtype.c +++ test/CodeGen/xcore-stringtype.c @@ -163,7 +163,7 @@ // test EnumType // CHECK: !33 = metadata !{i32* @EnumAnon, metadata !"e(){m(EA){3}}"} // CHECK: !34 = metadata !{i32 (i32)* @enumType, metadata -// CHECK: !"f{si}(e(E){m(A){0},m(B){1},m(C){5},m(D){6}})"} -enum E {A, B, C=5, D}; +// CHECK: !"f{si}(e(E){m(A){7},m(B){6},m(C){5},m(D){0}})"} +enum E {D, C=5, B, A}; enum {EA=3} EnumAnon = EA; int enumType(enum E e) {return EnumAnon;}