summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp53
1 files changed, 38 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 1aa69bd35d67e..96abeed824930 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -199,6 +199,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
case DefaultTemplateArgumentChecking:
case DeclaringSpecialMember:
case DefiningSynthesizedFunction:
+ case ExceptionSpecEvaluation:
return false;
// This function should never be called when Kind's value is Memoization.
@@ -621,6 +622,12 @@ void Sema::PrintInstantiationStack() {
break;
}
+ case CodeSynthesisContext::ExceptionSpecEvaluation:
+ Diags.Report(Active->PointOfInstantiation,
+ diag::note_evaluating_exception_spec_here)
+ << cast<FunctionDecl>(Active->Entity);
+ break;
+
case CodeSynthesisContext::ExceptionSpecInstantiation:
Diags.Report(Active->PointOfInstantiation,
diag::note_template_exception_spec_instantiation_here)
@@ -668,7 +675,7 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
// context, depending on what else is on the stack.
if (isa<TypeAliasTemplateDecl>(Active->Entity))
break;
- // Fall through.
+ LLVM_FALLTHROUGH;
case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
case CodeSynthesisContext::ExceptionSpecInstantiation:
// This is a template instantiation, so there is no SFINAE.
@@ -695,6 +702,12 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
// there is no SFINAE.
return None;
+ case CodeSynthesisContext::ExceptionSpecEvaluation:
+ // FIXME: This should not be treated as a SFINAE context, because
+ // we will cache an incorrect exception specification. However, clang
+ // bootstrap relies this! See PR31692.
+ break;
+
case CodeSynthesisContext::Memoization:
break;
}
@@ -894,7 +907,7 @@ namespace {
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL,
CXXRecordDecl *ThisContext,
- unsigned ThisTypeQuals,
+ Qualifiers ThisTypeQuals,
Fn TransformExceptionSpec);
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
@@ -1154,7 +1167,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
if (!E->isTypeDependent())
return E;
- return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
+ return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
}
ExprResult
@@ -1414,7 +1427,7 @@ template<typename Fn>
QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL,
CXXRecordDecl *ThisContext,
- unsigned ThisTypeQuals,
+ Qualifiers ThisTypeQuals,
Fn TransformExceptionSpec) {
// We need a local instantiation scope for this function prototype.
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
@@ -1653,7 +1666,7 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
SourceLocation Loc,
DeclarationName Entity,
CXXRecordDecl *ThisContext,
- unsigned ThisTypeQuals) {
+ Qualifiers ThisTypeQuals) {
assert(!CodeSynthesisContexts.empty() &&
"Cannot perform an instantiation without some context on the "
"instantiation stack");
@@ -1708,7 +1721,7 @@ void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
Proto->getExtProtoInfo().ExceptionSpec;
SmallVector<QualType, 4> ExceptionStorage;
- if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getLocEnd(),
+ if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getEndLoc(),
ESI, ExceptionStorage, Args))
// On error, recover by dropping the exception specification.
ESI.Type = EST_None;
@@ -1789,7 +1802,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
ExprResult NewArg = SubstExpr(Arg, TemplateArgs);
if (NewArg.isUsable()) {
// It would be nice if we still had this.
- SourceLocation EqualLoc = NewArg.get()->getLocStart();
+ SourceLocation EqualLoc = NewArg.get()->getBeginLoc();
SetParamDefaultArgument(NewParm, NewArg.get(), EqualLoc);
}
} else {
@@ -2135,7 +2148,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl);
CXXRecordDecl *ThisContext =
dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
- CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0,
+ CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
ND && ND->isCXXInstanceMember());
Attr *NewAttr =
@@ -2303,7 +2316,7 @@ bool Sema::InstantiateInClassInitializer(
Diag(PointOfInstantiation,
diag::err_in_class_initializer_not_yet_parsed)
<< OutermostClass << Pattern;
- Diag(Pattern->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed);
+ Diag(Pattern->getEndLoc(), diag::note_in_class_initializer_not_yet_parsed);
Instantiation->setInvalidDecl();
return true;
}
@@ -2330,14 +2343,14 @@ bool Sema::InstantiateInClassInitializer(
// Instantiate the initializer.
ActOnStartCXXInClassMemberInitializer();
- CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), /*TypeQuals=*/0);
+ CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), Qualifiers());
ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
/*CXXDirectInit=*/false);
Expr *Init = NewInit.get();
assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class");
ActOnFinishCXXInClassMemberInitializer(
- Instantiation, Init ? Init->getLocStart() : SourceLocation(), Init);
+ Instantiation, Init ? Init->getBeginLoc() : SourceLocation(), Init);
if (auto *L = getASTMutationListener())
L->DefaultMemberInitializerInstantiated(Instantiation);
@@ -2561,10 +2574,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
for (auto *D : Instantiation->decls()) {
bool SuppressNew = false;
if (auto *Function = dyn_cast<FunctionDecl>(D)) {
- if (FunctionDecl *Pattern
- = Function->getInstantiatedFromMemberFunction()) {
- MemberSpecializationInfo *MSInfo
- = Function->getMemberSpecializationInfo();
+ if (FunctionDecl *Pattern =
+ Function->getInstantiatedFromMemberFunction()) {
+
+ if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ continue;
+
+ MemberSpecializationInfo *MSInfo =
+ Function->getMemberSpecializationInfo();
assert(MSInfo && "No member specialization information?");
if (MSInfo->getTemplateSpecializationKind()
== TSK_ExplicitSpecialization)
@@ -2605,6 +2622,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
continue;
if (Var->isStaticDataMember()) {
+ if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ continue;
+
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
assert(MSInfo && "No member specialization information?");
if (MSInfo->getTemplateSpecializationKind()
@@ -2636,6 +2656,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
}
}
} else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
+ if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>())
+ continue;
+
// Always skip the injected-class-name, along with any
// redeclarations of nested classes, since both would cause us
// to try to instantiate the members of a class twice.