diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-09-26 02:36:12 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-09-26 02:36:12 +0000 |
commit | d7a6b1640e565487d163023a6a2e83f55476ae96 (patch) | |
tree | d5f4472454c04080fc1f329d70b8c71c91b24aa0 /lib/Sema/SemaTemplateDeduction.cpp | |
parent | 073819806ba2441e2a3e550107f1e756a6ee3ad0 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index b97a12a2cb..6b58087819 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -158,9 +158,6 @@ static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) { /// \brief Determine whether two declaration pointers refer to the same /// declaration. static bool isSameDeclaration(Decl *X, Decl *Y) { - if (!X || !Y) - return !X && !Y; - if (NamedDecl *NX = dyn_cast<NamedDecl>(X)) X = NX->getUnderlyingDecl(); if (NamedDecl *NY = dyn_cast<NamedDecl>(Y)) @@ -262,7 +259,27 @@ checkDeducedTemplateArguments(ASTContext &Context, // If we deduced two declarations, make sure they they refer to the // same declaration. if (Y.getKind() == TemplateArgument::Declaration && - isSameDeclaration(X.getAsDecl(), Y.getAsDecl())) + isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) && + X.isDeclForReferenceParam() == Y.isDeclForReferenceParam()) + return X; + + // All other combinations are incompatible. + return DeducedTemplateArgument(); + + case TemplateArgument::NullPtr: + // If we deduced a null pointer and a dependent expression, keep the + // null pointer. + if (Y.getKind() == TemplateArgument::Expression) + return X; + + // If we deduced a null pointer and an integral constant, keep the + // integral constant. + if (Y.getKind() == TemplateArgument::Integral) + return Y; + + // If we deduced two null pointers, make sure they have the same type. + if (Y.getKind() == TemplateArgument::NullPtr && + Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType())) return X; // All other combinations are incompatible. @@ -356,13 +373,15 @@ DeduceNonTypeTemplateArgument(Sema &S, static Sema::TemplateDeductionResult DeduceNonTypeTemplateArgument(Sema &S, NonTypeTemplateParmDecl *NTTP, - Decl *D, + ValueDecl *D, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced) { assert(NTTP->getDepth() == 0 && "Cannot deduce non-type template argument with depth > 0"); - DeducedTemplateArgument NewDeduced(D? D->getCanonicalDecl() : 0); + D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : 0; + TemplateArgument New(D, NTTP->getType()->isReferenceType()); + DeducedTemplateArgument NewDeduced(New); DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, Deduced[NTTP->getIndex()], NewDeduced); @@ -615,7 +634,7 @@ FinishArgumentPackDeduction(Sema &S, if (NewlyDeducedPacks[I].empty()) { // If we deduced an empty argument pack, create it now. - NewPack = DeducedTemplateArgument(TemplateArgument(0, 0)); + NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack()); } else { TemplateArgument *ArgumentPack = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()]; @@ -1599,7 +1618,17 @@ DeduceTemplateArguments(Sema &S, case TemplateArgument::Declaration: if (Arg.getKind() == TemplateArgument::Declaration && - isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl())) + isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()) && + Param.isDeclForReferenceParam() == Arg.isDeclForReferenceParam()) + return Sema::TDK_Success; + + Info.FirstArg = Param; + Info.SecondArg = Arg; + return Sema::TDK_NonDeducedMismatch; + + case TemplateArgument::NullPtr: + if (Arg.getKind() == TemplateArgument::NullPtr && + S.Context.hasSameType(Param.getNullPtrType(), Arg.getNullPtrType())) return Sema::TDK_Success; Info.FirstArg = Param; @@ -1870,7 +1899,11 @@ static bool isSameTemplateArg(ASTContext &Context, Context.getCanonicalType(Y.getAsType()); case TemplateArgument::Declaration: - return isSameDeclaration(X.getAsDecl(), Y.getAsDecl()); + return isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) && + X.isDeclForReferenceParam() == Y.isDeclForReferenceParam(); + + case TemplateArgument::NullPtr: + return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType()); case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: @@ -1940,6 +1973,14 @@ getTrivialTemplateArgumentLoc(Sema &S, return TemplateArgumentLoc(TemplateArgument(E), E); } + case TemplateArgument::NullPtr: { + Expr *E + = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc) + .takeAs<Expr>(); + return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true), + E); + } + case TemplateArgument::Integral: { Expr *E = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>(); @@ -2613,7 +2654,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, == Param) Builder.push_back(TemplateArgument(ExplicitArgs, NumExplicitArgs)); else - Builder.push_back(TemplateArgument(0, 0)); + Builder.push_back(TemplateArgument::getEmptyPack()); continue; } @@ -4510,6 +4551,11 @@ MarkUsedTemplateParameters(ASTContext &Ctx, case TemplateArgument::Declaration: break; + case TemplateArgument::NullPtr: + MarkUsedTemplateParameters(Ctx, TemplateArg.getNullPtrType(), OnlyDeduced, + Depth, Used); + break; + case TemplateArgument::Type: MarkUsedTemplateParameters(Ctx, TemplateArg.getAsType(), OnlyDeduced, Depth, Used); |