Fix the AST representation for non-type template arguments to encode
enough information so we can mangle them correctly in cases involving
dependent parameter types. (This specifically impacts cases involving
null pointers and cases involving parameters of reference type.)
Fix the mangler to use this information instead of trying to scavenge
it out of the parameter declaration.
<rdar://problem/12296776>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164656 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 9fd40b2..f19a2aa 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3684,11 +3684,14 @@
return Arg;
case TemplateArgument::Declaration: {
- if (Decl *D = Arg.getAsDecl())
- return TemplateArgument(D->getCanonicalDecl());
- return TemplateArgument((Decl*)0);
+ ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
+ return TemplateArgument(D, Arg.isDeclForReferenceParam());
}
+ case TemplateArgument::NullPtr:
+ return TemplateArgument(getCanonicalType(Arg.getNullPtrType()),
+ /*isNullPtr*/true);
+
case TemplateArgument::Template:
return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index a605f1a..411c337 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -923,7 +923,9 @@
bool isVariadic = DefaultTTPD->isParameterPack();
TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument();
- TemplateDecl *DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
+ TemplateDecl *DefaultTD = 0;
+ if (TA.getKind() != TemplateArgument::Null)
+ DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
if (!Iter.isEnd())
ArgDecl = Iter->getAsTemplate().getAsTemplateDecl();
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 34e6994..a900260 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -288,7 +288,7 @@
case TemplateArgument::Type:
return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
-
+
case TemplateArgument::Integral:
if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(),
Arg2.getIntegralType()))
@@ -297,10 +297,11 @@
return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral());
case TemplateArgument::Declaration:
- if (!Arg1.getAsDecl() || !Arg2.getAsDecl())
- return !Arg1.getAsDecl() && !Arg2.getAsDecl();
return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
-
+
+ case TemplateArgument::NullPtr:
+ return true; // FIXME: Is this correct?
+
case TemplateArgument::Template:
return IsStructurallyEquivalent(Context,
Arg1.getAsTemplate(),
@@ -1976,11 +1977,20 @@
return TemplateArgument(From, ToType);
}
- case TemplateArgument::Declaration:
- if (Decl *To = Importer.Import(From.getAsDecl()))
- return TemplateArgument(To);
+ case TemplateArgument::Declaration: {
+ ValueDecl *FromD = From.getAsDecl();
+ if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD)))
+ return TemplateArgument(To, From.isDeclForReferenceParam());
return TemplateArgument();
-
+ }
+
+ case TemplateArgument::NullPtr: {
+ QualType ToType = Importer.Import(From.getNullPtrType());
+ if (ToType.isNull())
+ return TemplateArgument();
+ return TemplateArgument(ToType, /*isNullPtr*/true);
+ }
+
case TemplateArgument::Template: {
TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
if (ToTemplate.isNull())
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 13f931a..8553e03 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -126,12 +126,12 @@
break;
case TemplateArgument::Declaration:
- // The decl can validly be null as the representation of nullptr
- // arguments, valid only in C++0x.
- if (Decl *D = Args[I].getAsDecl()) {
- if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- LV.mergeWithMin(getLVForDecl(ND, OnlyTemplate));
- }
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl()))
+ LV.mergeWithMin(getLVForDecl(ND, OnlyTemplate));
+ break;
+
+ case TemplateArgument::NullPtr:
+ LV.mergeWithMin(getLVForType(Args[I].getNullPtrType()));
break;
case TemplateArgument::Template:
diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp
index 29d8c62..11e3b52 100644
--- a/lib/AST/DumpXML.cpp
+++ b/lib/AST/DumpXML.cpp
@@ -316,12 +316,12 @@
}
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
+ case TemplateArgument::NullPtr:
// FIXME: Implement!
break;
case TemplateArgument::Declaration: {
- if (Decl *D = A.getAsDecl())
- visitDeclRef(D);
+ visitDeclRef(A.getAsDecl());
break;
}
case TemplateArgument::Integral: {
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 3a16801..d8c6594 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -343,17 +343,10 @@
void mangleCXXDtorType(CXXDtorType T);
void mangleTemplateArgs(const ASTTemplateArgumentListInfo &TemplateArgs);
- void mangleTemplateArgs(TemplateName Template,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs);
- void mangleTemplateArgs(const TemplateParameterList &PL,
- const TemplateArgument *TemplateArgs,
+ void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
- void mangleTemplateArgs(const TemplateParameterList &PL,
- const TemplateArgumentList &AL);
- void mangleTemplateArg(const NamedDecl *P, TemplateArgument A);
- void mangleUnresolvedTemplateArgs(const TemplateArgument *args,
- unsigned numArgs);
+ void mangleTemplateArgs(const TemplateArgumentList &AL);
+ void mangleTemplateArg(TemplateArgument A);
void mangleTemplateParameter(unsigned Index);
@@ -570,8 +563,7 @@
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleUnscopedTemplateName(TD);
- TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
- mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
+ mangleTemplateArgs(*TemplateArgs);
return;
}
@@ -593,8 +585,7 @@
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
mangleUnscopedTemplateName(TD);
- TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
- mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
+ mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
} else {
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
}
@@ -738,8 +729,7 @@
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
- TST->getNumArgs());
+ mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
} else if (const DependentTemplateSpecializationType *DTST
@@ -752,7 +742,7 @@
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(Template, DTST->getArgs(), DTST->getNumArgs());
+ mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
} else {
// We use the QualType mangle type variant here because it handles
// substitutions.
@@ -943,7 +933,7 @@
}
}
- mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
+ mangleTemplateArgs(tst->getArgs(), tst->getNumArgs());
break;
}
@@ -960,7 +950,7 @@
const DependentTemplateSpecializationType *tst
= cast<DependentTemplateSpecializationType>(type);
mangleSourceName(tst->getIdentifier());
- mangleUnresolvedTemplateArgs(tst->getArgs(), tst->getNumArgs());
+ mangleTemplateArgs(tst->getArgs(), tst->getNumArgs());
break;
}
}
@@ -1229,8 +1219,7 @@
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
- TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
- mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
+ mangleTemplateArgs(*TemplateArgs);
}
else {
manglePrefix(DC, NoFunction);
@@ -1247,8 +1236,7 @@
Out << 'N';
mangleTemplatePrefix(TD);
- TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
- mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
+ mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
Out << 'E';
}
@@ -1421,8 +1409,7 @@
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
- TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
- mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
+ mangleTemplateArgs(*TemplateArgs);
}
else if(NoFunction && (isa<FunctionDecl>(ND) || isa<ObjCMethodDecl>(ND)))
return;
@@ -2172,7 +2159,7 @@
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(T->getTemplateName(), T->getArgs(), T->getNumArgs());
+ mangleTemplateArgs(T->getArgs(), T->getNumArgs());
addSubstitution(QualType(T, 0));
}
}
@@ -2198,7 +2185,7 @@
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(Prefix, T->getArgs(), T->getNumArgs());
+ mangleTemplateArgs(T->getArgs(), T->getNumArgs());
Out << 'E';
}
@@ -3053,50 +3040,28 @@
// <template-args> ::= I <template-arg>+ E
Out << 'I';
for (unsigned i = 0, e = TemplateArgs.NumTemplateArgs; i != e; ++i)
- mangleTemplateArg(0, TemplateArgs.getTemplateArgs()[i].getArgument());
+ mangleTemplateArg(TemplateArgs.getTemplateArgs()[i].getArgument());
Out << 'E';
}
-void CXXNameMangler::mangleTemplateArgs(TemplateName Template,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs) {
- if (TemplateDecl *TD = Template.getAsTemplateDecl())
- return mangleTemplateArgs(*TD->getTemplateParameters(), TemplateArgs,
- NumTemplateArgs);
-
- mangleUnresolvedTemplateArgs(TemplateArgs, NumTemplateArgs);
-}
-
-void CXXNameMangler::mangleUnresolvedTemplateArgs(const TemplateArgument *args,
- unsigned numArgs) {
- // <template-args> ::= I <template-arg>+ E
- Out << 'I';
- for (unsigned i = 0; i != numArgs; ++i)
- mangleTemplateArg(0, args[i]);
- Out << 'E';
-}
-
-void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
- const TemplateArgumentList &AL) {
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &AL) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
for (unsigned i = 0, e = AL.size(); i != e; ++i)
- mangleTemplateArg(PL.getParam(i), AL[i]);
+ mangleTemplateArg(AL[i]);
Out << 'E';
}
-void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
- const TemplateArgument *TemplateArgs,
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
for (unsigned i = 0; i != NumTemplateArgs; ++i)
- mangleTemplateArg(PL.getParam(i), TemplateArgs[i]);
+ mangleTemplateArg(TemplateArgs[i]);
Out << 'E';
}
-void CXXNameMangler::mangleTemplateArg(const NamedDecl *P,
- TemplateArgument A) {
+void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
// <template-arg> ::= <type> # type or template
// ::= X <expression> E # expression
// ::= <expr-primary> # simple expressions
@@ -3145,25 +3110,12 @@
mangleIntegerLiteral(A.getIntegralType(), A.getAsIntegral());
break;
case TemplateArgument::Declaration: {
- assert(P && "Missing template parameter for declaration argument");
// <expr-primary> ::= L <mangled-name> E # external name
- // <expr-primary> ::= L <type> 0 E
// Clang produces AST's where pointer-to-member-function expressions
// and pointer-to-function expressions are represented as a declaration not
// an expression. We compensate for it here to produce the correct mangling.
- const NonTypeTemplateParmDecl *Parameter = cast<NonTypeTemplateParmDecl>(P);
-
- // Handle NULL pointer arguments.
- if (!A.getAsDecl()) {
- Out << "L";
- mangleType(Parameter->getType());
- Out << "0E";
- break;
- }
-
-
- NamedDecl *D = cast<NamedDecl>(A.getAsDecl());
- bool compensateMangling = !Parameter->getType()->isReferenceType();
+ ValueDecl *D = A.getAsDecl();
+ bool compensateMangling = !A.isDeclForReferenceParam();
if (compensateMangling) {
Out << 'X';
mangleOperatorName(OO_Amp, 1);
@@ -3186,14 +3138,20 @@
break;
}
-
+ case TemplateArgument::NullPtr: {
+ // <expr-primary> ::= L <type> 0 E
+ Out << 'L';
+ mangleType(A.getNullPtrType());
+ Out << "0E";
+ break;
+ }
case TemplateArgument::Pack: {
// Note: proposal by Mike Herrick on 12/20/10
Out << 'J';
for (TemplateArgument::pack_iterator PA = A.pack_begin(),
PAEnd = A.pack_end();
PA != PAEnd; ++PA)
- mangleTemplateArg(P, *PA);
+ mangleTemplateArg(*PA);
Out << 'E';
}
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 0c3186f..bfd3132 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -1173,6 +1173,10 @@
VisitDecl(Arg.getAsDecl());
break;
+ case TemplateArgument::NullPtr:
+ VisitType(Arg.getNullPtrType());
+ break;
+
case TemplateArgument::Integral:
Arg.getAsIntegral().Profile(ID);
VisitType(Arg.getIntegralType());
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 95ff4ed..968a6be 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -77,7 +77,7 @@
const TemplateArgument *Args,
unsigned NumArgs) {
if (NumArgs == 0)
- return TemplateArgument(0, 0);
+ return getEmptyPack();
TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
std::copy(Args, Args + NumArgs, Storage);
@@ -99,12 +99,11 @@
return true;
case Declaration:
- if (Decl *D = getAsDecl()) {
- if (DeclContext *DC = dyn_cast<DeclContext>(D))
- return DC->isDependentContext();
- return D->getDeclContext()->isDependentContext();
- }
-
+ if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
+ return DC->isDependentContext();
+ return getAsDecl()->getDeclContext()->isDependentContext();
+
+ case NullPtr:
return false;
case Integral:
@@ -141,11 +140,11 @@
return true;
case Declaration:
- if (Decl *D = getAsDecl()) {
- if (DeclContext *DC = dyn_cast<DeclContext>(D))
- return DC->isDependentContext();
- return D->getDeclContext()->isDependentContext();
- }
+ if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
+ return DC->isDependentContext();
+ return getAsDecl()->getDeclContext()->isDependentContext();
+
+ case NullPtr:
return false;
case Integral:
@@ -174,6 +173,7 @@
case Integral:
case Pack:
case Template:
+ case NullPtr:
return false;
case TemplateExpansion:
@@ -195,6 +195,7 @@
case Declaration:
case Integral:
case TemplateExpansion:
+ case NullPtr:
break;
case Type:
@@ -286,12 +287,16 @@
switch (getKind()) {
case Null:
case Type:
- case Declaration:
case Expression:
case Template:
case TemplateExpansion:
+ case NullPtr:
return TypeOrValue == Other.TypeOrValue;
+ case Declaration:
+ return getAsDecl() == Other.getAsDecl() &&
+ isDeclForReferenceParam() && Other.isDeclForReferenceParam();
+
case Integral:
return getIntegralType() == Other.getIntegralType() &&
getAsIntegral() == Other.getAsIntegral();
@@ -319,12 +324,13 @@
case TemplateExpansion:
return TemplateArgument(getAsTemplateOrTemplatePattern());
-
+
case Declaration:
case Integral:
case Pack:
case Null:
case Template:
+ case NullPtr:
return TemplateArgument();
}
@@ -348,18 +354,20 @@
}
case Declaration: {
- if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
- if (ND->getDeclName()) {
- Out << *ND;
- } else {
- Out << "<anonymous>";
- }
+ NamedDecl *ND = cast<NamedDecl>(getAsDecl());
+ if (ND->getDeclName()) {
+ // FIXME: distinguish between pointer and reference args?
+ Out << *ND;
} else {
- Out << "nullptr";
+ Out << "<anonymous>";
}
break;
}
-
+
+ case NullPtr: {
+ Out << "nullptr";
+ }
+
case Template:
getAsTemplate().print(Out, Policy);
break;
@@ -411,6 +419,9 @@
case TemplateArgument::Declaration:
return getSourceDeclExpression()->getSourceRange();
+ case TemplateArgument::NullPtr:
+ return getSourceNullPtrExpression()->getSourceRange();
+
case TemplateArgument::Type:
if (TypeSourceInfo *TSI = getTypeSourceInfo())
return TSI->getTypeLoc().getSourceRange();
@@ -430,6 +441,8 @@
return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
case TemplateArgument::Integral:
+ return getSourceIntegralExpression()->getSourceRange();
+
case TemplateArgument::Pack:
case TemplateArgument::Null:
return SourceRange();
@@ -490,6 +503,7 @@
getTemplateNameLoc());
case TemplateArgument::Declaration:
+ case TemplateArgument::NullPtr:
case TemplateArgument::Template:
case TemplateArgument::Integral:
case TemplateArgument::Pack:
@@ -512,8 +526,9 @@
return DB << Arg.getAsType();
case TemplateArgument::Declaration:
- if (Decl *D = Arg.getAsDecl())
- return DB << D;
+ return DB << Arg.getAsDecl();
+
+ case TemplateArgument::NullPtr:
return DB << "nullptr";
case TemplateArgument::Integral:
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index bd30a65..945e783 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -302,6 +302,9 @@
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::Pack:
+ case TemplateArgument::NullPtr:
+ llvm_unreachable("Impossible TemplateArgument");
+
case TemplateArgument::Expression:
ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
break;
@@ -311,7 +314,7 @@
Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
Loc));
break;
-
+
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion: {
NestedNameSpecifierLocBuilder Builder;