Index: include/clang/AST/PrettyPrinter.h =================================================================== --- include/clang/AST/PrettyPrinter.h +++ include/clang/AST/PrettyPrinter.h @@ -52,7 +52,7 @@ Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false), - FullyQualifiedName(false) { } + FullyQualifiedName(false), ABICompatibleFormatting(false) { } /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -225,6 +225,13 @@ /// When true, print the fully qualified name of function declarations. /// This is the opposite of SuppressScope and thus overrules it. bool FullyQualifiedName : 1; + + /// Use formatting compatible with ABI specification. It is necessary for + /// saving entities into debug tables which have to be compatible with + /// the representation, described in ABI specification. In particular, this forces + /// templates parametrized with enums to be represented as "T<(Enum)0>" instead of + /// "T" and template specializations to be written in canonical form. + bool ABICompatibleFormatting : 1; }; } // end namespace clang Index: lib/AST/TemplateBase.cpp =================================================================== --- lib/AST/TemplateBase.cpp +++ lib/AST/TemplateBase.cpp @@ -56,14 +56,22 @@ const llvm::APSInt &Val = TemplArg.getAsIntegral(); if (const EnumType *ET = T->getAs()) { - for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) { - // In Sema::CheckTemplateArugment, enum template arguments value are - // extended to the size of the integer underlying the enum type. This - // may create a size difference between the enum value and template - // argument value, requiring isSameValue here instead of operator==. - if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { - ECD->printQualifiedName(Out, Policy); - return; + if (Policy.ABICompatibleFormatting) { + Out << "("; + ET->getDecl()->getNameForDiagnostic(Out, Policy, true); + Out << ")"; + Out << Val; + return; + } else { + for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) { + // In Sema::CheckTemplateArugment, enum template arguments value are + // extended to the size of the integer underlying the enum type. This + // may create a size difference between the enum value and template + // argument value, requiring isSameValue here instead of operator==. + if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { + ECD->printQualifiedName(Out, Policy); + return; + } } } } Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -1060,7 +1060,9 @@ if (ClassTemplateSpecializationDecl *Spec = dyn_cast(D)) { ArrayRef Args; - if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { + if (TypeSourceInfo *TAW = !Policy.ABICompatibleFormatting + ? Spec->getTypeAsWritten() + : nullptr) { const TemplateSpecializationType *TST = cast(TAW->getType()); Args = TST->template_arguments(); Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -234,6 +234,7 @@ if (CGM.getCodeGenOpts().EmitCodeView) PP.MSVCFormatting = true; + PP.ABICompatibleFormatting = true; return PP; }