diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 23 | ||||
-rw-r--r-- | clang/lib/AST/RawCommentList.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Darwin.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Gnu.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Gnu.h | 6 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Hurd.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Hurd.h | 6 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Linux.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Linux.h | 4 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 52 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 98 |
16 files changed, 153 insertions, 97 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index cb4d61cac2c7..cb7c7fcbd4b8 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -332,13 +332,16 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, } } -bool Decl::isLexicallyWithinFunctionOrMethod() const { +bool Decl::isInLocalScope() const { const DeclContext *LDC = getLexicalDeclContext(); while (true) { if (LDC->isFunctionOrMethod()) return true; if (!isa<TagDecl>(LDC)) return false; + if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC)) + if (CRD->isLambda()) + return true; LDC = LDC->getLexicalParent(); } return false; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c79973507323..7af1edb9565a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8593,6 +8593,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType); +static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, + APValue &Result, + const CXXConstructExpr *CCE, + QualType AllocType); bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { if (!Info.getLangOpts().CPlusPlus2a) @@ -8642,6 +8646,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { const Expr *Init = E->getInitializer(); const InitListExpr *ResizedArrayILE = nullptr; + const CXXConstructExpr *ResizedArrayCCE = nullptr; QualType AllocType = E->getAllocatedType(); if (Optional<const Expr*> ArraySize = E->getArraySize()) { @@ -8685,7 +8690,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { // -- the new-initializer is a braced-init-list and the number of // array elements for which initializers are provided [...] // exceeds the number of elements to initialize - if (Init) { + if (Init && !isa<CXXConstructExpr>(Init)) { auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType()); assert(CAT && "unexpected type for array initializer"); @@ -8708,6 +8713,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { // special handling for this case when we initialize. if (InitBound != AllocBound) ResizedArrayILE = cast<InitListExpr>(Init); + } else if (Init) { + ResizedArrayCCE = cast<CXXConstructExpr>(Init); } AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr, @@ -8772,6 +8779,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE, AllocType)) return false; + } else if (ResizedArrayCCE) { + if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE, + AllocType)) + return false; } else if (Init) { if (!EvaluateInPlace(*Val, Info, Result, Init)) return false; @@ -9597,6 +9608,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, .VisitInitListExpr(ILE, AllocType); } +static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, + APValue &Result, + const CXXConstructExpr *CCE, + QualType AllocType) { + assert(CCE->isRValue() && CCE->getType()->isArrayType() && + "not an array rvalue"); + return ArrayExprEvaluator(Info, This, Result) + .VisitCXXConstructExpr(CCE, This, &Result, AllocType); +} + // Return true iff the given array filler may depend on the element index. static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { // For now, just whitelist non-class value-initialization and initialization diff --git a/clang/lib/AST/RawCommentList.cpp b/clang/lib/AST/RawCommentList.cpp index 83e8a0b942a4..d7124156521c 100644 --- a/clang/lib/AST/RawCommentList.cpp +++ b/clang/lib/AST/RawCommentList.cpp @@ -430,7 +430,7 @@ std::string RawComment::getFormattedText(const SourceManager &SourceMgr, }; auto DropTrailingNewLines = [](std::string &Str) { - while (Str.back() == '\n') + while (!Str.empty() && Str.back() == '\n') Str.pop_back(); }; diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 59631e802373..e97f7e41499d 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -437,7 +437,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD, // Finish the function to maintain CodeGenFunction invariants. // FIXME: Don't emit unreachable code. EmitBlock(createBasicBlock()); - FinishFunction(); + + FinishThunk(); } void CodeGenFunction::generateThunk(llvm::Function *Fn, @@ -564,7 +565,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD, CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn); // Thunks for variadic methods are special because in general variadic - // arguments cannot be perferctly forwarded. In the general case, clang + // arguments cannot be perfectly forwarded. In the general case, clang // implements such thunks by cloning the original function body. However, for // thunks with no return adjustment on targets that support musttail, we can // use musttail to perfectly forward the variadic arguments. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index f8866ac4f7f6..a735bdd814ed 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1847,9 +1847,16 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, else if (const auto *SA = FD->getAttr<SectionAttr>()) F->setSection(SA->getName()); + // If we plan on emitting this inline builtin, we can't treat it as a builtin. if (FD->isInlineBuiltinDeclaration()) { - F->addAttribute(llvm::AttributeList::FunctionIndex, - llvm::Attribute::NoBuiltin); + const FunctionDecl *FDBody; + bool HasBody = FD->hasBody(FDBody); + (void)HasBody; + assert(HasBody && "Inline builtin declarations should always have an " + "available body!"); + if (shouldEmitFunction(FDBody)) + F->addAttribute(llvm::AttributeList::FunctionIndex, + llvm::Attribute::NoBuiltin); } if (FD->isReplaceableGlobalAllocationFunction()) { diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 220bc8f98351..46265c1b9f1a 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1146,6 +1146,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args, addExportedSymbol(CmdArgs, "___gcov_flush"); addExportedSymbol(CmdArgs, "_flush_fn_list"); addExportedSymbol(CmdArgs, "_writeout_fn_list"); + addExportedSymbol(CmdArgs, "_reset_fn_list"); } else { addExportedSymbol(CmdArgs, "___llvm_profile_filename"); addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index da197e476621..e8ef881e89ac 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -309,7 +309,7 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { } } -static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { +static bool getPIE(const ArgList &Args, const ToolChain &TC) { if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) return false; @@ -317,17 +317,16 @@ static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, options::OPT_nopie); if (!A) - return ToolChain.isPIEDefault(); + return TC.isPIEDefault(); return A->getOption().matches(options::OPT_pie); } -static bool getStaticPIE(const ArgList &Args, - const toolchains::Linux &ToolChain) { +static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) { bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); // -no-pie is an alias for -nopie. So, handling -nopie takes care of // -no-pie as well. if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { - const Driver &D = ToolChain.getDriver(); + const Driver &D = TC.getDriver(); const llvm::opt::OptTable &Opts = D.getOpts(); const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie); const char *NoPIEName = Opts.getOptionName(options::OPT_nopie); @@ -346,8 +345,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const toolchains::Linux &ToolChain = - static_cast<const toolchains::Linux &>(getToolChain()); + // FIXME: The Linker class constructor takes a ToolChain and not a + // Generic_ELF, so the static_cast might return a reference to a invalid + // instance (see PR45061). Ideally, the Linker constructor needs to take a + // Generic_ELF instead. + const toolchains::Generic_ELF &ToolChain = + static_cast<const toolchains::Generic_ELF &>(getToolChain()); const Driver &D = ToolChain.getDriver(); const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); @@ -418,8 +421,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (isAndroid) CmdArgs.push_back("--warn-shared-textrel"); - for (const auto &Opt : ToolChain.ExtraOpts) - CmdArgs.push_back(Opt.c_str()); + ToolChain.addExtraOpts(CmdArgs); CmdArgs.push_back("--eh-frame-hdr"); diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h index 083f74c05477..fa50b56bf954 100644 --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -356,6 +356,12 @@ public: void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; + + virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const { + return {}; + } + + virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {} }; } // end namespace toolchains diff --git a/clang/lib/Driver/ToolChains/Hurd.cpp b/clang/lib/Driver/ToolChains/Hurd.cpp index 72166ca9f359..ee91f7d73b9c 100644 --- a/clang/lib/Driver/ToolChains/Hurd.cpp +++ b/clang/lib/Driver/ToolChains/Hurd.cpp @@ -61,8 +61,7 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { return Triple.isArch32Bit() ? "lib" : "lib64"; } -Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) +Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { std::string SysRoot = computeSysRoot(); path_list &Paths = getFilePaths(); @@ -170,3 +169,8 @@ void Hurd::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } + +void Hurd::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} diff --git a/clang/lib/Driver/ToolChains/Hurd.h b/clang/lib/Driver/ToolChains/Hurd.h index 86c6c3f734dd..8f88d7e8e58e 100644 --- a/clang/lib/Driver/ToolChains/Hurd.h +++ b/clang/lib/Driver/ToolChains/Hurd.h @@ -27,9 +27,11 @@ public: AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - virtual std::string computeSysRoot() const; + std::string computeSysRoot() const; - virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; std::vector<std::string> ExtraOpts; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index bff1ab1009be..6532c899492a 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -986,3 +986,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); ToolChain::addProfileRTLibs(Args, CmdArgs); } + +void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index f5518eac218a..923ebecbd215 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -42,7 +42,9 @@ public: llvm::opt::ArgStringList &CmdArgs) const override; virtual std::string computeSysRoot() const; - virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; std::vector<std::string> ExtraOpts; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 70bcd7048c55..8cb786a4d343 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2176,6 +2176,10 @@ static bool isFunctionDeclarationName(const FormatToken &Current, Next = Next->Next; continue; } + if (Next->is(TT_TemplateOpener) && Next->MatchingParen) { + Next = Next->MatchingParen; + continue; + } break; } @@ -2705,20 +2709,40 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, tok::l_square)); if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; - if (Right.isOneOf(tok::star, tok::amp, tok::ampamp) && - (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier()) && - // Space between the type and the * in: - // operator void*() - // operator char*() - // operator /*comment*/ const char*() - // operator volatile /*comment*/ char*() - // operator Foo*() - // dependent on PointerAlignment style. - Left.Previous && - (Left.Previous->endsSequence(tok::kw_operator) || - Left.Previous->endsSequence(tok::kw_const, tok::kw_operator) || - Left.Previous->endsSequence(tok::kw_volatile, tok::kw_operator))) - return (Style.PointerAlignment != FormatStyle::PAS_Left); + if (Right.is(tok::star) && Left.is(tok::star)) + return false; + if (Right.isOneOf(tok::star, tok::amp, tok::ampamp)) { + const FormatToken *Previous = &Left; + while (Previous && !Previous->is(tok::kw_operator)) { + if (Previous->is(tok::identifier) || Previous->isSimpleTypeSpecifier()) { + Previous = Previous->getPreviousNonComment(); + continue; + } + if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) { + Previous = Previous->MatchingParen->getPreviousNonComment(); + continue; + } + if (Previous->is(tok::coloncolon)) { + Previous = Previous->getPreviousNonComment(); + continue; + } + break; + } + // Space between the type and the * in: + // operator void*() + // operator char*() + // operator /*comment*/ const char*() + // operator volatile /*comment*/ char*() + // operator Foo*() + // operator C<T>*() + // operator std::Foo*() + // operator C<T>::D<U>*() + // dependent on PointerAlignment style. + if (Previous && (Previous->endsSequence(tok::kw_operator) || + Previous->endsSequence(tok::kw_const, tok::kw_operator) || + Previous->endsSequence(tok::kw_volatile, tok::kw_operator))) + return (Style.PointerAlignment != FormatStyle::PAS_Left); + } const auto SpaceRequiredForArrayInitializerLSquare = [](const FormatToken &LSquareTok, const FormatStyle &Style) { return Style.SpacesInContainerLiterals || diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index b5d2ab1f31f2..c53c37ee109f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2343,7 +2343,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm); } else if (Expr *Arg = OldParm->getDefaultArg()) { FunctionDecl *OwningFunc = cast<FunctionDecl>(OldParm->getDeclContext()); - if (OwningFunc->isLexicallyWithinFunctionOrMethod()) { + if (OwningFunc->isInLocalScope()) { // Instantiate default arguments for methods of local classes (DR1484) // and non-defining declarations. Sema::ContextRAII SavedContext(*this, OwningFunc); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 37dace3bee7f..f801e79c8902 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4367,7 +4367,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI.ExceptionSpec.Type != EST_None && EPI.ExceptionSpec.Type != EST_DynamicNone && EPI.ExceptionSpec.Type != EST_BasicNoexcept && - !Tmpl->isLexicallyWithinFunctionOrMethod()) { + !Tmpl->isInLocalScope()) { FunctionDecl *ExceptionSpecTemplate = Tmpl; if (EPI.ExceptionSpec.Type == EST_Uninstantiated) ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0305954a278e..bbc6fc6deeef 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4022,50 +4022,8 @@ template<typename Derived> void TreeTransform<Derived>::InventTemplateArgumentLoc( const TemplateArgument &Arg, TemplateArgumentLoc &Output) { - SourceLocation Loc = getDerived().getBaseLocation(); - switch (Arg.getKind()) { - case TemplateArgument::Null: - llvm_unreachable("null template argument in TreeTransform"); - break; - - case TemplateArgument::Type: - Output = TemplateArgumentLoc(Arg, - SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); - - break; - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: { - NestedNameSpecifierLocBuilder Builder; - TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) - Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc); - - if (Arg.getKind() == TemplateArgument::Template) - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc); - else - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc, Loc); - - break; - } - - case TemplateArgument::Expression: - Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); - break; - - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::Pack: - case TemplateArgument::NullPtr: - Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); - break; - } + Output = getSema().getTrivialTemplateArgumentLoc( + Arg, QualType(), getDerived().getBaseLocation()); } template<typename Derived> @@ -4075,12 +4033,45 @@ bool TreeTransform<Derived>::TransformTemplateArgument( const TemplateArgument &Arg = Input.getArgument(); switch (Arg.getKind()) { case TemplateArgument::Null: - case TemplateArgument::Integral: case TemplateArgument::Pack: - case TemplateArgument::Declaration: - case TemplateArgument::NullPtr: llvm_unreachable("Unexpected TemplateArgument"); + case TemplateArgument::Integral: + case TemplateArgument::NullPtr: + case TemplateArgument::Declaration: { + // Transform a resolved template argument straight to a resolved template + // argument. We get here when substituting into an already-substituted + // template type argument during concept satisfaction checking. + QualType T = Arg.getNonTypeTemplateArgumentType(); + QualType NewT = getDerived().TransformType(T); + if (NewT.isNull()) + return true; + + ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration + ? Arg.getAsDecl() + : nullptr; + ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl( + getDerived().getBaseLocation(), D)) + : nullptr; + if (D && !NewD) + return true; + + if (NewT == T && D == NewD) + Output = Input; + else if (Arg.getKind() == TemplateArgument::Integral) + Output = TemplateArgumentLoc( + TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT), + TemplateArgumentLocInfo()); + else if (Arg.getKind() == TemplateArgument::NullPtr) + Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true), + TemplateArgumentLocInfo()); + else + Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT), + TemplateArgumentLocInfo()); + + return false; + } + case TemplateArgument::Type: { TypeSourceInfo *DI = Input.getTypeSourceInfo(); if (!DI) @@ -11837,19 +11828,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { LSI->CallOperator = NewCallOperator; - for (unsigned I = 0, NumParams = NewCallOperator->getNumParams(); - I != NumParams; ++I) { - auto *P = NewCallOperator->getParamDecl(I); - if (P->hasUninstantiatedDefaultArg()) { - EnterExpressionEvaluationContext Eval( - getSema(), - Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, P); - ExprResult R = getDerived().TransformExpr( - E->getCallOperator()->getParamDecl(I)->getDefaultArg()); - P->setDefaultArg(R.get()); - } - } - getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator}); |