Index: clang/lib/AST/MicrosoftMangle.cpp =================================================================== --- clang/lib/AST/MicrosoftMangle.cpp +++ clang/lib/AST/MicrosoftMangle.cpp @@ -378,8 +378,10 @@ void mangleFunctionClass(const FunctionDecl *FD); void mangleCallingConvention(CallingConv CC); void mangleCallingConvention(const FunctionType *T); - void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean); - void mangleExpression(const Expr *E); + void mangleIntegerLiteral(const llvm::APSInt &Number, + const NonTypeTemplateParmDecl *PD = nullptr, + QualType *TemplateArgType = nullptr); + void mangleExpression(const Expr *E, const NonTypeTemplateParmDecl *PD); void mangleThrowSpecification(const FunctionProtoType *T); void mangleTemplateArgs(const TemplateDecl *TD, @@ -1357,24 +1359,32 @@ mangleUnqualifiedName(TD); } -void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value, - bool IsBoolean) { - // ::= $0 - Out << "$0"; - // Make sure booleans are encoded as 0/1. - if (IsBoolean && Value.getBoolValue()) - mangleNumber(1); - else if (Value.isSigned()) +void MicrosoftCXXNameMangler::mangleIntegerLiteral( + const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD, + QualType *TemplateArgType) { + // ::= $ [] 0 + Out << "$"; + + // mangle argument type if parmeter is auto + if (PD && PD->getType()->getTypeClass() == Type::Auto && TemplateArgType) { + mangleType(*TemplateArgType, SourceRange(), QMM_Drop); + } + + Out << "0"; + + if (Value.isSigned()) mangleNumber(Value.getSExtValue()); else mangleNumber(Value.getZExtValue()); } -void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { +void MicrosoftCXXNameMangler::mangleExpression( + const Expr *E, const NonTypeTemplateParmDecl *PD) { // See if this is a constant expression. llvm::APSInt Value; if (E->isIntegerConstantExpr(Value, Context.getASTContext())) { - mangleIntegerLiteral(Value, E->getType()->isBooleanType()); + QualType T = E->getType(); + mangleIntegerLiteral(Value, PD, &T); return; } @@ -1448,10 +1458,12 @@ } break; } - case TemplateArgument::Integral: + case TemplateArgument::Integral: { + QualType T = TA.getIntegralType(); mangleIntegerLiteral(TA.getAsIntegral(), - TA.getIntegralType()->isBooleanType()); + cast(Parm), &T); break; + } case TemplateArgument::NullPtr: { QualType T = TA.getNullPtrType(); if (const MemberPointerType *MPT = T->getAs()) { @@ -1473,16 +1485,18 @@ // However, we are free to use 0 *if* we would use multiple fields for // non-nullptr member pointers. if (!RD->nullFieldOffsetIsZero()) { - mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false); + mangleIntegerLiteral(llvm::APSInt::get(-1), + cast(Parm), &T); return; } } } - mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false); + mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), + cast(Parm), &T); break; } case TemplateArgument::Expression: - mangleExpression(TA.getAsExpr()); + mangleExpression(TA.getAsExpr(), cast(Parm)); break; case TemplateArgument::Pack: { ArrayRef TemplateArgs = TA.getPackAsArray(); @@ -1814,8 +1828,7 @@ if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS); Extra.mangleSourceName("_AS"); - Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS), - /*IsBoolean*/ false); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS)); } else { switch (AS) { default: @@ -2700,8 +2713,7 @@ Stream << "?$"; Extra.mangleSourceName("__vector"); Extra.mangleType(QualType(ET, 0), Range, QMM_Escape); - Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()), - /*IsBoolean=*/false); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements())); mangleArtificialTagType(TTK_Union, TemplateMangling, {"__clang"}); } @@ -2940,7 +2952,7 @@ Stream << "?$"; Extra.mangleSourceName("ocl_pipe"); Extra.mangleType(ElementType, Range, QMM_Escape); - Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()), true); + Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly())); mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"}); } @@ -2980,8 +2992,7 @@ Extra.mangleSourceName("_UExtInt"); else Extra.mangleSourceName("_ExtInt"); - Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()), - /*IsBoolean=*/false); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits())); mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"}); } Index: clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s + +template +class AutoParmTemplate { +public: + AutoParmTemplate() {} +}; + +template +class AutoParmsTemplate { +public: + AutoParmsTemplate() {} +}; + +void template_mangling() { + AutoParmTemplate<0> auto_int; + // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$H0A@@@QAE@XZ" + AutoParmTemplate auto_bool; + // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$_N0A@@@QAE@XZ" + AutoParmTemplate<'a'> auto_char; + // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$D0GB@@@QAE@XZ" + AutoParmTemplate<9223372036854775807LL> int64_max; + // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$_J0HPPPPPPPPPPPPPPP@@@QAE@XZ" + AutoParmTemplate<-9223372036854775807LL - 1LL> int64_min; + // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$_J0?IAAAAAAAAAAAAAAA@@@QAE@XZ" + AutoParmTemplate<(unsigned long long)-1> uint64_neg_1; + // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$_K0?0@@QAE@XZ" + + AutoParmsTemplate<0, false, 'a'> c1; + // CHECK: call {{.*}} @"??0?$AutoParmsTemplate@$H0A@$_N0A@$D0GB@@@QAE@XZ" + AutoParmsTemplate<(unsigned long)1, 9223372036854775807LL> c2; + // CHECK: call {{.*}} @"??0?$AutoParmsTemplate@$K00$_J0HPPPPPPPPPPPPPPP@@@QAE@XZ" +}