diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp index 36687a8e761e85..c87b3ea7e26163 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp @@ -54,7 +54,9 @@ AST_MATCHER(QualType, isEnableIf) { AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument, clang::ast_matchers::internal::Matcher, TypeMatcher) { return Node.hasDefaultArgument() && - TypeMatcher.matches(Node.getDefaultArgument(), Finder, Builder); + TypeMatcher.matches( + Node.getDefaultArgument().getArgument().getAsType(), Finder, + Builder); } AST_MATCHER(TemplateDecl, hasAssociatedConstraints) { return Node.hasAssociatedConstraints(); diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp index 09aaf3e31d5dd7..75f1107904fcec 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp @@ -19,10 +19,11 @@ namespace { AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument, ast_matchers::internal::Matcher, InnerMatcher) { if (Node.getIdentifier() != nullptr || !Node.hasDefaultArgument() || - Node.getDefaultArgumentInfo() == nullptr) + Node.getDefaultArgument().getArgument().isNull()) return false; - TypeLoc DefaultArgTypeLoc = Node.getDefaultArgumentInfo()->getTypeLoc(); + TypeLoc DefaultArgTypeLoc = + Node.getDefaultArgument().getTypeSourceInfo()->getTypeLoc(); return InnerMatcher.matches(DefaultArgTypeLoc, Finder, Builder); } diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp index 7a021fe14436a1..ea4d99586c7110 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp @@ -177,9 +177,11 @@ matchTrailingTemplateParam(const FunctionTemplateDecl *FunctionTemplate) { dyn_cast(LastParam)) { if (LastTemplateParam->hasDefaultArgument() && LastTemplateParam->getIdentifier() == nullptr) { - return {matchEnableIfSpecialization( - LastTemplateParam->getDefaultArgumentInfo()->getTypeLoc()), - LastTemplateParam}; + return { + matchEnableIfSpecialization(LastTemplateParam->getDefaultArgument() + .getTypeSourceInfo() + ->getTypeLoc()), + LastTemplateParam}; } } return {}; diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 06b949bc4a2b55..2ec0994e846e94 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -247,8 +247,12 @@ fetchTemplateParameters(const TemplateParameterList *Params, if (!TTP->getName().empty()) P.Name = TTP->getNameAsString(); - if (TTP->hasDefaultArgument()) - P.Default = TTP->getDefaultArgument().getAsString(PP); + if (TTP->hasDefaultArgument()) { + P.Default.emplace(); + llvm::raw_string_ostream Out(*P.Default); + TTP->getDefaultArgument().getArgument().print(PP, Out, + /*IncludeType=*/false); + } } else if (const auto *NTTP = dyn_cast(Param)) { P.Type = printType(NTTP, PP); diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index bf7c204e4ad73a..98db1cb5789909 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -695,7 +695,7 @@ class ASTNodeTraverser if (const auto *TC = D->getTypeConstraint()) Visit(TC->getImmediatelyDeclaredConstraint()); if (D->hasDefaultArgument()) - Visit(D->getDefaultArgument(), SourceRange(), + Visit(D->getDefaultArgument().getArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index f3d6a321ecf104..07b08b5ed43ca4 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1185,7 +1185,7 @@ class TemplateTypeParmDecl final : public TypeDecl, /// The default template argument, if any. using DefArgStorage = - DefaultArgStorage; + DefaultArgStorage; DefArgStorage DefaultArgument; TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, @@ -1225,13 +1225,9 @@ class TemplateTypeParmDecl final : public TypeDecl, bool hasDefaultArgument() const { return DefaultArgument.isSet(); } /// Retrieve the default argument, if any. - QualType getDefaultArgument() const { - return DefaultArgument.get()->getType(); - } - - /// Retrieves the default argument's source information, if any. - TypeSourceInfo *getDefaultArgumentInfo() const { - return DefaultArgument.get(); + const TemplateArgumentLoc &getDefaultArgument() const { + static const TemplateArgumentLoc NoneLoc; + return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc; } /// Retrieves the location of the default argument declaration. @@ -1244,9 +1240,8 @@ class TemplateTypeParmDecl final : public TypeDecl, } /// Set the default argument for this template parameter. - void setDefaultArgument(TypeSourceInfo *DefArg) { - DefaultArgument.set(DefArg); - } + void setDefaultArgument(const ASTContext &C, + const TemplateArgumentLoc &DefArg); /// Set that this default argument was inherited from another /// parameter. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index f5cefedb07e0eb..659e4cdd1037b1 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1960,7 +1960,7 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); TRY_TO(TraverseTemplateTypeParamDeclConstraints(D)); if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc())); + TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); }) DEF_TRAVERSE_DECL(TypedefDecl, { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 01ddba5eaf01dc..9b1c998d4a254f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -10067,7 +10067,9 @@ class Sema final : public SemaBase { bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateArgumentLoc &Output); + TemplateArgumentLoc &Output, + SourceLocation Loc = {}, + const DeclarationName &Entity = {}); bool SubstTemplateArguments(ArrayRef Args, const MultiLevelTemplateArgumentList &TemplateArgs, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 52eab5feb062bc..f9902a978aa34a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -6494,7 +6494,8 @@ bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X, if (!TTPX->hasDefaultArgument() || !TTPY->hasDefaultArgument()) return false; - return hasSameType(TTPX->getDefaultArgument(), TTPY->getDefaultArgument()); + return hasSameType(TTPX->getDefaultArgument().getArgument().getAsType(), + TTPY->getDefaultArgument().getArgument().getAsType()); } if (auto *NTTPX = dyn_cast(X)) { diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 9ff8e1ea78d852..a47dd72a5679cd 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5917,11 +5917,11 @@ ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } if (D->hasDefaultArgument()) { - Expected ToDefaultArgOrErr = - import(D->getDefaultArgumentInfo()); + Expected ToDefaultArgOrErr = + import(D->getDefaultArgument()); if (!ToDefaultArgOrErr) return ToDefaultArgOrErr.takeError(); - ToD->setDefaultArgument(*ToDefaultArgOrErr); + ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr); } return ToD; diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index c5868256b440d9..bf32aafc3d0af4 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1883,7 +1883,8 @@ void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) { if (TTP->hasDefaultArgument()) { Out << " = "; - Out << TTP->getDefaultArgument().getAsString(Policy); + TTP->getDefaultArgument().getArgument().print(Policy, Out, + /*IncludeType=*/false); } } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 26765a5da1dc64..46bb3e8e51389f 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -669,23 +669,30 @@ TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, } SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { - return hasDefaultArgument() - ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc() - : SourceLocation(); + return hasDefaultArgument() ? getDefaultArgument().getLocation() + : SourceLocation(); } SourceRange TemplateTypeParmDecl::getSourceRange() const { if (hasDefaultArgument() && !defaultArgumentWasInherited()) return SourceRange(getBeginLoc(), - getDefaultArgumentInfo()->getTypeLoc().getEndLoc()); + getDefaultArgument().getSourceRange().getEnd()); // TypeDecl::getSourceRange returns a range containing name location, which is // wrong for unnamed template parameters. e.g: // it will return <[[typename>]] instead of <[[typename]]> - else if (getDeclName().isEmpty()) + if (getDeclName().isEmpty()) return SourceRange(getBeginLoc()); return TypeDecl::getSourceRange(); } +void TemplateTypeParmDecl::setDefaultArgument( + const ASTContext &C, const TemplateArgumentLoc &DefArg) { + if (DefArg.getArgument().isNull()) + DefaultArgument.set(nullptr); + else + DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); +} + unsigned TemplateTypeParmDecl::getDepth() const { return getTypeForDecl()->castAs()->getDepth(); } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 42608476b1c195..efd3a639d746b3 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -1028,7 +1028,7 @@ void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { if (D->hasDefaultArgument()) JOS.attributeObject("defaultArg", [=] { - Visit(D->getDefaultArgument(), SourceRange(), + Visit(D->getDefaultArgument().getArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), D->defaultArgumentWasInherited() ? "inherited from" : "previous"); }); diff --git a/clang/lib/AST/ODRDiagsEmitter.cpp b/clang/lib/AST/ODRDiagsEmitter.cpp index 5b1cdc16e2ea2c..97b6c14d9ede61 100644 --- a/clang/lib/AST/ODRDiagsEmitter.cpp +++ b/clang/lib/AST/ODRDiagsEmitter.cpp @@ -1409,13 +1409,15 @@ bool ODRDiagsEmitter::diagnoseMismatch( } if (HasFirstDefaultArgument && HasSecondDefaultArgument) { - QualType FirstType = FirstTTPD->getDefaultArgument(); - QualType SecondType = SecondTTPD->getDefaultArgument(); - if (computeODRHash(FirstType) != computeODRHash(SecondType)) { + TemplateArgument FirstTA = + FirstTTPD->getDefaultArgument().getArgument(); + TemplateArgument SecondTA = + SecondTTPD->getDefaultArgument().getArgument(); + if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) { DiagTemplateError(FunctionTemplateParameterDifferentDefaultArgument) - << (i + 1) << FirstType; + << (i + 1) << FirstTA; DiagTemplateNote(FunctionTemplateParameterDifferentDefaultArgument) - << (i + 1) << SecondType; + << (i + 1) << SecondTA; return true; } } diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 6f04739cf6693d..18b1e17e0fee5d 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -462,7 +462,7 @@ class ODRDeclVisitor : public ConstDeclVisitor { D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); Hash.AddBoolean(hasDefaultArgument); if (hasDefaultArgument) { - AddTemplateArgument(D->getDefaultArgument()); + AddTemplateArgument(D->getDefaultArgument().getArgument()); } Hash.AddBoolean(D->isParameterPack()); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 87f0a8728d8506..981f09410401b0 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2273,8 +2273,8 @@ bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, if (auto *TTPD = dyn_cast(Param)) { return TTPD->hasDefaultArgument() && - isSubstitutedTemplateArgument(Ctx, Arg, TTPD->getDefaultArgument(), - Args, Depth); + isSubstitutedTemplateArgument( + Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth); } else if (auto *TTPD = dyn_cast(Param)) { return TTPD->hasDefaultArgument() && isSubstitutedTemplateArgument( diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 98b9343924a835..d88e4e0df8ef89 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -999,11 +999,11 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( DeclarationFragments::FragmentKind::GenericParameter); if (TemplateParam->hasDefaultArgument()) { - DeclarationFragments After; + const auto Default = TemplateParam->getDefaultArgument(); Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) - .append(getFragmentsForType(TemplateParam->getDefaultArgument(), - TemplateParam->getASTContext(), After)); - Fragments.append(std::move(After)); + .append(getFragmentsForTemplateArguments( + {Default.getArgument()}, TemplateParam->getASTContext(), + {Default})); } } else if (const auto *NTP = dyn_cast(ParameterArray[i])) { diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index 8eb88f5a1e94ee..058f4aef918a8f 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -703,7 +703,8 @@ class IndexingDeclVisitor : public ConstDeclVisitor { IndexCtx.handleDecl(TP); if (const auto *TTP = dyn_cast(TP)) { if (TTP->hasDefaultArgument()) - IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent); + handleTemplateArgumentLoc(TTP->getDefaultArgument(), Parent, + TP->getLexicalDeclContext()); if (auto *C = TTP->getTypeConstraint()) IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(), Parent, TTP->getLexicalDeclContext()); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index bb283c54b3d29c..fa8c852ea9e9f2 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -308,17 +308,18 @@ struct BuiltinTypeDeclBuilder { return *this; } - TemplateParameterListBuilder addTemplateArgumentList(); - BuiltinTypeDeclBuilder &addSimpleTemplateParams(ArrayRef Names); + TemplateParameterListBuilder addTemplateArgumentList(Sema &S); + BuiltinTypeDeclBuilder &addSimpleTemplateParams(Sema &S, + ArrayRef Names); }; struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &Builder; - ASTContext &AST; + Sema &S; llvm::SmallVector Params; - TemplateParameterListBuilder(BuiltinTypeDeclBuilder &RB) - : Builder(RB), AST(RB.Record->getASTContext()) {} + TemplateParameterListBuilder(Sema &S, BuiltinTypeDeclBuilder &RB) + : Builder(RB), S(S) {} ~TemplateParameterListBuilder() { finalizeTemplateArgs(); } @@ -328,12 +329,15 @@ struct TemplateParameterListBuilder { return *this; unsigned Position = static_cast(Params.size()); auto *Decl = TemplateTypeParmDecl::Create( - AST, Builder.Record->getDeclContext(), SourceLocation(), + S.Context, Builder.Record->getDeclContext(), SourceLocation(), SourceLocation(), /* TemplateDepth */ 0, Position, - &AST.Idents.get(Name, tok::TokenKind::identifier), /* Typename */ false, + &S.Context.Idents.get(Name, tok::TokenKind::identifier), + /* Typename */ false, /* ParameterPack */ false); if (!DefaultValue.isNull()) - Decl->setDefaultArgument(AST.getTrivialTypeSourceInfo(DefaultValue)); + Decl->setDefaultArgument( + S.Context, S.getTrivialTemplateArgumentLoc(DefaultValue, QualType(), + SourceLocation())); Params.emplace_back(Decl); return *this; @@ -342,11 +346,11 @@ struct TemplateParameterListBuilder { BuiltinTypeDeclBuilder &finalizeTemplateArgs() { if (Params.empty()) return Builder; - auto *ParamList = - TemplateParameterList::Create(AST, SourceLocation(), SourceLocation(), - Params, SourceLocation(), nullptr); + auto *ParamList = TemplateParameterList::Create(S.Context, SourceLocation(), + SourceLocation(), Params, + SourceLocation(), nullptr); Builder.Template = ClassTemplateDecl::Create( - AST, Builder.Record->getDeclContext(), SourceLocation(), + S.Context, Builder.Record->getDeclContext(), SourceLocation(), DeclarationName(Builder.Record->getIdentifier()), ParamList, Builder.Record); Builder.Record->setDescribedClassTemplate(Builder.Template); @@ -359,20 +363,22 @@ struct TemplateParameterListBuilder { Params.clear(); QualType T = Builder.Template->getInjectedClassNameSpecialization(); - T = AST.getInjectedClassNameType(Builder.Record, T); + T = S.Context.getInjectedClassNameType(Builder.Record, T); return Builder; } }; } // namespace -TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() { - return TemplateParameterListBuilder(*this); +TemplateParameterListBuilder +BuiltinTypeDeclBuilder::addTemplateArgumentList(Sema &S) { + return TemplateParameterListBuilder(S, *this); } BuiltinTypeDeclBuilder & -BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef Names) { - TemplateParameterListBuilder Builder = this->addTemplateArgumentList(); +BuiltinTypeDeclBuilder::addSimpleTemplateParams(Sema &S, + ArrayRef Names) { + TemplateParameterListBuilder Builder = this->addTemplateArgumentList(S); for (StringRef Name : Names) Builder.addTypeParameter(Name); return Builder.finalizeTemplateArgs(); @@ -426,7 +432,9 @@ void HLSLExternalSemaSource::defineHLSLVectorAlias() { auto *TypeParam = TemplateTypeParmDecl::Create( AST, HLSLNamespace, SourceLocation(), SourceLocation(), 0, 0, &AST.Idents.get("element", tok::TokenKind::identifier), false, false); - TypeParam->setDefaultArgument(AST.getTrivialTypeSourceInfo(AST.FloatTy)); + TypeParam->setDefaultArgument( + AST, SemaPtr->getTrivialTemplateArgumentLoc( + TemplateArgument(AST.FloatTy), QualType(), SourceLocation())); TemplateParams.emplace_back(TypeParam); @@ -492,7 +500,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { CXXRecordDecl *Decl; Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") - .addSimpleTemplateParams({"element_type"}) + .addSimpleTemplateParams(*SemaPtr, {"element_type"}) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, @@ -503,7 +511,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer") - .addSimpleTemplateParams({"element_type"}) + .addSimpleTemplateParams(*SemaPtr, {"element_type"}) .Record; onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 02d9b64c2b14b1..0b26cb4a872b1f 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1071,7 +1071,8 @@ NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename, return Param; } - Param->setDefaultArgument(DefaultTInfo); + Param->setDefaultArgument( + Context, TemplateArgumentLoc(DefaultTInfo->getType(), DefaultTInfo)); } return Param; @@ -2318,11 +2319,11 @@ transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC, SemaRef.SubstTypeConstraint(NewTTP, TC, Args, /*EvaluateConstraint=*/true); if (TTP->hasDefaultArgument()) { - TypeSourceInfo *InstantiatedDefaultArg = - SemaRef.SubstType(TTP->getDefaultArgumentInfo(), Args, - TTP->getDefaultArgumentLoc(), TTP->getDeclName()); - if (InstantiatedDefaultArg) - NewTTP->setDefaultArgument(InstantiatedDefaultArg); + TemplateArgumentLoc InstantiatedDefaultArg; + if (!SemaRef.SubstTemplateArgument( + TTP->getDefaultArgument(), Args, InstantiatedDefaultArg, + TTP->getDefaultArgumentLoc(), TTP->getDeclName())) + NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg); } SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP); return NewTTP; @@ -3575,10 +3576,9 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, = dyn_cast(*NewParam)) { // Check the presence of a default argument here. if (NewTypeParm->hasDefaultArgument() && - DiagnoseDefaultTemplateArgument(*this, TPC, - NewTypeParm->getLocation(), - NewTypeParm->getDefaultArgumentInfo()->getTypeLoc() - .getSourceRange())) + DiagnoseDefaultTemplateArgument( + *this, TPC, NewTypeParm->getLocation(), + NewTypeParm->getDefaultArgument().getSourceRange())) NewTypeParm->removeDefaultArgument(); // Merge default arguments for template type parameters. @@ -6040,22 +6040,26 @@ bool Sema::CheckTemplateTypeArgument( /// /// \param Converted the list of template arguments provided for template /// parameters that precede \p Param in the template parameter list. -/// \returns the substituted template argument, or NULL if an error occurred. -static TypeSourceInfo *SubstDefaultTemplateArgument( +/// +/// \param Output the resulting substituted template argument. +/// +/// \returns true if an error occurred. +static bool SubstDefaultTemplateArgument( Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, TemplateTypeParmDecl *Param, ArrayRef SugaredConverted, - ArrayRef CanonicalConverted) { - TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo(); + ArrayRef CanonicalConverted, + TemplateArgumentLoc &Output) { + Output = Param->getDefaultArgument(); // If the argument type is dependent, instantiate it now based // on the previously-computed template arguments. - if (ArgType->getType()->isInstantiationDependentType()) { + if (Output.getArgument().isInstantiationDependent()) { Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template, SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) - return nullptr; + return true; // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists(Template, SugaredConverted, @@ -6068,12 +6072,14 @@ static TypeSourceInfo *SubstDefaultTemplateArgument( ForLambdaCallOperator = Rec->isLambda(); Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext(), !ForLambdaCallOperator); - ArgType = - SemaRef.SubstType(ArgType, TemplateArgLists, - Param->getDefaultArgumentLoc(), Param->getDeclName()); + + if (SemaRef.SubstTemplateArgument(Output, TemplateArgLists, Output, + Param->getDefaultArgumentLoc(), + Param->getDeclName())) + return true; } - return ArgType; + return false; } /// Substitute template arguments into the default template argument for @@ -6196,13 +6202,12 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable( return TemplateArgumentLoc(); HasDefaultArg = true; - TypeSourceInfo *DI = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, TypeParm, SugaredConverted, - CanonicalConverted); - if (DI) - return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); - - return TemplateArgumentLoc(); + TemplateArgumentLoc Output; + if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, + TypeParm, SugaredConverted, + CanonicalConverted, Output)) + return TemplateArgumentLoc(); + return Output; } if (NonTypeTemplateParmDecl *NonTypeParm @@ -6785,14 +6790,10 @@ bool Sema::CheckTemplateArgumentList( return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP, NewArgs); - TypeSourceInfo *ArgType = SubstDefaultTemplateArgument( - *this, Template, TemplateLoc, RAngleLoc, TTP, SugaredConverted, - CanonicalConverted); - if (!ArgType) + if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, + TTP, SugaredConverted, + CanonicalConverted, Arg)) return true; - - Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()), - ArgType); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*Param)) { if (!hasReachableDefaultArgument(NTTP)) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 41fd210f29d097..0c348633576d64 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -519,18 +519,14 @@ static NamedDecl *getTemplateParameterWithDefault(Sema &S, NamedDecl *A, switch (A->getKind()) { case Decl::TemplateTypeParm: { auto *T = cast(A); - // FIXME: A TemplateTypeParmDecl's DefaultArgument can't hold a full - // TemplateArgument, so there is currently no way to specify a pack as a - // default argument for these. - if (T->isParameterPack()) - return A; auto *R = TemplateTypeParmDecl::Create( S.Context, A->getDeclContext(), SourceLocation(), SourceLocation(), T->getDepth(), T->getIndex(), T->getIdentifier(), - T->wasDeclaredWithTypename(), /*ParameterPack=*/false, + T->wasDeclaredWithTypename(), T->isParameterPack(), T->hasTypeConstraint()); R->setDefaultArgument( - S.Context.getTrivialTypeSourceInfo(Default.getAsType())); + S.Context, + S.getTrivialTemplateArgumentLoc(Default, QualType(), SourceLocation())); if (R->hasTypeConstraint()) { auto *C = R->getTypeConstraint(); R->setTypeConstraint(C->getConceptReference(), diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 07626058c79776..abb8a260faab9d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1619,11 +1619,6 @@ namespace { case TemplateArgument::Pack: // Literally rewrite the template argument pack, instead of unpacking // it. - assert( - SemaRef.CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::BuildingDeductionGuides && - "Transforming a template argument pack is only allowed in building " - "deduction guide"); for (auto &pack : Arg.getPackAsArray()) { TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc( pack, QualType(), SourceLocation{}); @@ -4375,9 +4370,9 @@ Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) { bool Sema::SubstTemplateArgument( const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateArgumentLoc &Output) { - TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(), - DeclarationName()); + TemplateArgumentLoc &Output, SourceLocation Loc, + const DeclarationName &Entity) { + TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity); return Instantiator.TransformTemplateArgument(Input, Output); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 381d79b2fcd466..38a300332068fa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2956,11 +2956,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( } } if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { - TypeSourceInfo *InstantiatedDefaultArg = - SemaRef.SubstType(D->getDefaultArgumentInfo(), TemplateArgs, - D->getDefaultArgumentLoc(), D->getDeclName()); - if (InstantiatedDefaultArg) - Inst->setDefaultArgument(InstantiatedDefaultArg); + TemplateArgumentLoc Output; + if (!SemaRef.SubstTemplateArgument(D->getDefaultArgument(), TemplateArgs, + Output)) + Inst->setDefaultArgument(SemaRef.getASTContext(), Output); } // Introduce this template parameter's instantiation into the instantiation diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index a6254b70560c36..d7a9e31b477f88 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2695,7 +2695,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } if (Record.readInt()) - D->setDefaultArgument(readTypeSourceInfo()); + D->setDefaultArgument(Reader.getContext(), + Record.readTemplateArgumentLoc()); } void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index c2f1d1b44241cc..b2a214e935aadd 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1899,7 +1899,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { !D->defaultArgumentWasInherited(); Record.push_back(OwnsDefaultArg); if (OwnsDefaultArg) - Record.AddTypeSourceInfo(D->getDefaultArgumentInfo()); + Record.AddTemplateArgumentLoc(D->getDefaultArgument()); if (!TC && !OwnsDefaultArg && D->getDeclContext() == D->getLexicalDeclContext() && diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index f00ba9e3acfc84..d0d654568d8475 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -776,10 +776,9 @@ bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { } // Visit the default argument. - if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo()) - if (Visit(DefArg->getTypeLoc())) - return true; + if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() && + VisitTemplateArgumentLoc(D->getDefaultArgument())) + return true; return false; } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 4ee64de697d37a..ba630002c055a3 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -1188,7 +1188,7 @@ TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) { FromTU, templateTypeParmDecl(hasName("T"))); TemplateTypeParmDecl *To = Import(From, Lang_CXX03); ASSERT_TRUE(To->hasDefaultArgument()); - QualType ToArg = To->getDefaultArgument(); + QualType ToArg = To->getDefaultArgument().getArgument().getAsType(); ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy)); }