summaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclBase.cpp5
-rw-r--r--clang/lib/AST/ExprConstant.cpp23
-rw-r--r--clang/lib/AST/RawCommentList.cpp2
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp11
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.cpp1
-rw-r--r--clang/lib/Driver/ToolChains/Gnu.cpp20
-rw-r--r--clang/lib/Driver/ToolChains/Gnu.h6
-rw-r--r--clang/lib/Driver/ToolChains/Hurd.cpp8
-rw-r--r--clang/lib/Driver/ToolChains/Hurd.h6
-rw-r--r--clang/lib/Driver/ToolChains/Linux.cpp5
-rw-r--r--clang/lib/Driver/ToolChains/Linux.h4
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp52
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp2
-rw-r--r--clang/lib/Sema/TreeTransform.h98
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});