aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp266
1 files changed, 143 insertions, 123 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 128dc2f7ff40..c7cbc41b3035 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -156,11 +156,11 @@ bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const {
case ExceptionSpecInstantiation:
case DefaultTemplateArgumentInstantiation:
case DefaultFunctionArgumentInstantiation:
- return true;
-
case ExplicitTemplateArgumentSubstitution:
case DeducedTemplateArgumentSubstitution:
case PriorTemplateArgumentSubstitution:
+ return true;
+
case DefaultTemplateArgumentChecking:
return false;
}
@@ -214,12 +214,11 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
}
}
-Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
- SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange)
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ TemplateDecl *Template,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
@@ -232,35 +231,33 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
= ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation;
Inst.PointOfInstantiation = PointOfInstantiation;
Inst.Entity = reinterpret_cast<uintptr_t>(Template);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
Inst.InstantiationRange = InstantiationRange;
SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
}
}
-Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
- SourceLocation PointOfInstantiation,
- FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- ActiveTemplateInstantiation::InstantiationKind Kind,
- sema::TemplateDeductionInfo &DeductionInfo,
- SourceRange InstantiationRange)
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ FunctionTemplateDecl *FunctionTemplate,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ ActiveTemplateInstantiation::InstantiationKind Kind,
+ sema::TemplateDeductionInfo &DeductionInfo,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
{
- Invalid = CheckInstantiationDepth(PointOfInstantiation,
- InstantiationRange);
+ Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
if (!Invalid) {
ActiveTemplateInstantiation Inst;
Inst.Kind = Kind;
Inst.PointOfInstantiation = PointOfInstantiation;
Inst.Entity = reinterpret_cast<uintptr_t>(FunctionTemplate);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
Inst.DeductionInfo = &DeductionInfo;
Inst.InstantiationRange = InstantiationRange;
SemaRef.InNonInstantiationSFINAEContext = false;
@@ -271,54 +268,49 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
}
}
-Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
- SourceLocation PointOfInstantiation,
- ClassTemplatePartialSpecializationDecl *PartialSpec,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- sema::TemplateDeductionInfo &DeductionInfo,
- SourceRange InstantiationRange)
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ ClassTemplatePartialSpecializationDecl *PartialSpec,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ sema::TemplateDeductionInfo &DeductionInfo,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
{
- Invalid = false;
-
- ActiveTemplateInstantiation Inst;
- Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
- Inst.PointOfInstantiation = PointOfInstantiation;
- Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
- Inst.DeductionInfo = &DeductionInfo;
- Inst.InstantiationRange = InstantiationRange;
- SemaRef.InNonInstantiationSFINAEContext = false;
- SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-
- assert(!Inst.isInstantiationRecord());
- ++SemaRef.NonInstantiationEntries;
+ Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+ if (!Invalid) {
+ ActiveTemplateInstantiation Inst;
+ Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec);
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
+ Inst.DeductionInfo = &DeductionInfo;
+ Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
+ SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+ }
}
-Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
- SourceLocation PointOfInstantiation,
- ParmVarDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange)
+Sema::InstantiatingTemplate::
+InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ ParmVarDecl *Param,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
{
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-
if (!Invalid) {
ActiveTemplateInstantiation Inst;
Inst.Kind
= ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
Inst.PointOfInstantiation = PointOfInstantiation;
Inst.Entity = reinterpret_cast<uintptr_t>(Param);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
Inst.InstantiationRange = InstantiationRange;
SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
@@ -327,66 +319,57 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Sema::InstantiatingTemplate::
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- NamedDecl *Template,
- NonTypeTemplateParmDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange)
+ NamedDecl *Template, NonTypeTemplateParmDecl *Param,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
{
- Invalid = false;
-
- ActiveTemplateInstantiation Inst;
- Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
- Inst.PointOfInstantiation = PointOfInstantiation;
- Inst.Template = Template;
- Inst.Entity = reinterpret_cast<uintptr_t>(Param);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
- Inst.InstantiationRange = InstantiationRange;
- SemaRef.InNonInstantiationSFINAEContext = false;
- SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-
- assert(!Inst.isInstantiationRecord());
- ++SemaRef.NonInstantiationEntries;
+ Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+ if (!Invalid) {
+ ActiveTemplateInstantiation Inst;
+ Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Template = Template;
+ Inst.Entity = reinterpret_cast<uintptr_t>(Param);
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
+ Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
+ SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+ }
}
Sema::InstantiatingTemplate::
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- NamedDecl *Template,
- TemplateTemplateParmDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange)
+ NamedDecl *Template, TemplateTemplateParmDecl *Param,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
{
- Invalid = false;
- ActiveTemplateInstantiation Inst;
- Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
- Inst.PointOfInstantiation = PointOfInstantiation;
- Inst.Template = Template;
- Inst.Entity = reinterpret_cast<uintptr_t>(Param);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
- Inst.InstantiationRange = InstantiationRange;
- SemaRef.InNonInstantiationSFINAEContext = false;
- SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-
- assert(!Inst.isInstantiationRecord());
- ++SemaRef.NonInstantiationEntries;
+ Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+ if (!Invalid) {
+ ActiveTemplateInstantiation Inst;
+ Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Template = Template;
+ Inst.Entity = reinterpret_cast<uintptr_t>(Param);
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
+ Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
+ SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+ }
}
Sema::InstantiatingTemplate::
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- NamedDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange)
+ TemplateDecl *Template, NamedDecl *Param,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ SourceRange InstantiationRange)
: SemaRef(SemaRef),
SavedInNonInstantiationSFINAEContext(
SemaRef.InNonInstantiationSFINAEContext)
@@ -398,8 +381,8 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
Inst.PointOfInstantiation = PointOfInstantiation;
Inst.Template = Template;
Inst.Entity = reinterpret_cast<uintptr_t>(Param);
- Inst.TemplateArgs = TemplateArgs;
- Inst.NumTemplateArgs = NumTemplateArgs;
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
Inst.InstantiationRange = InstantiationRange;
SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
@@ -638,8 +621,13 @@ llvm::Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
++Active)
{
switch(Active->Kind) {
- case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
case ActiveTemplateInstantiation::TemplateInstantiation:
+ // An instantiation of an alias template may or may not be a SFINAE
+ // context, depending on what else is on the stack.
+ if (isa<TypeAliasTemplateDecl>(reinterpret_cast<Decl *>(Active->Entity)))
+ break;
+ // Fall through.
+ case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
case ActiveTemplateInstantiation::ExceptionSpecInstantiation:
// This is a template instantiation, so there is no SFINAE.
return llvm::Optional<TemplateDeductionInfo *>();
@@ -850,10 +838,23 @@ namespace {
return move(Result);
}
+ ExprResult TransformLambdaExpr(LambdaExpr *E) {
+ LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+ return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E);
+ }
+
+ ExprResult TransformLambdaScope(LambdaExpr *E,
+ CXXMethodDecl *CallOperator) {
+ CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(),
+ TSK_ImplicitInstantiation);
+ return TreeTransform<TemplateInstantiator>::
+ TransformLambdaScope(E, CallOperator);
+ }
+
private:
ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm,
SourceLocation loc,
- const TemplateArgument &arg);
+ TemplateArgument arg);
};
}
@@ -1088,7 +1089,11 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
llvm::APInt LengthI(32, Length + 1);
- QualType ResTy = getSema().Context.CharTy.withConst();
+ QualType ResTy;
+ if (IT == PredefinedExpr::LFunction)
+ ResTy = getSema().Context.WCharTy.withConst();
+ else
+ ResTy = getSema().Context.CharTy.withConst();
ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI,
ArrayType::Normal, 0);
PredefinedExpr *PE =
@@ -1138,10 +1143,18 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
NonTypeTemplateParmDecl *parm,
SourceLocation loc,
- const TemplateArgument &arg) {
+ TemplateArgument arg) {
ExprResult result;
QualType type;
+ // If the argument is a pack expansion, the parameter must actually be a
+ // parameter pack, and we should substitute the pattern itself, producing
+ // an expression which contains an unexpanded parameter pack.
+ if (arg.isPackExpansion()) {
+ assert(parm->isParameterPack() && "pack expansion for non-pack");
+ arg = arg.getPackExpansionPattern();
+ }
+
// The template argument itself might be an expression, in which
// case we just return that expression.
if (arg.getKind() == TemplateArgument::Expression) {
@@ -1378,7 +1391,7 @@ TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
/// substituted. If this type is not dependent, it will be returned
/// immediately.
///
-/// \param TemplateArgs the template arguments that will be
+/// \param Args the template arguments that will be
/// substituted for the top-level template parameters within T.
///
/// \param Loc the location in the source code where this substitution
@@ -1590,6 +1603,9 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
NewParm->setUnparsedDefaultArg();
UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
} else if (Expr *Arg = OldParm->getDefaultArg())
+ // FIXME: if we non-lazily instantiated non-dependent default args for
+ // non-dependent parameter types we could remove a bunch of duplicate
+ // conversion warnings for such arguments.
NewParm->setUninstantiatedDefaultArg(Arg);
NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
@@ -1820,8 +1836,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateSpecializationKind TSK,
bool Complain) {
- bool Invalid = false;
-
CXXRecordDecl *PatternDef
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
if (DiagnoseUninstantiableTemplate(*this, PointOfInstantiation, Instantiation,
@@ -1867,7 +1881,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// Do substitution on the base class specifiers.
if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
- Invalid = true;
+ Instantiation->setInvalidDecl();
TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
SmallVector<Decl*, 4> Fields;
@@ -1893,7 +1907,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
continue;
if ((*Member)->isInvalidDecl()) {
- Invalid = true;
+ Instantiation->setInvalidDecl();
continue;
}
@@ -1917,14 +1931,22 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
MSInfo->setPointOfInstantiation(PointOfInstantiation);
}
+ } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) {
+ if (SA->isFailed()) {
+ // A static_assert failed. Bail out; instantiating this
+ // class is probably not meaningful.
+ Instantiation->setInvalidDecl();
+ break;
+ }
}
if (NewMember->isInvalidDecl())
- Invalid = true;
+ Instantiation->setInvalidDecl();
} else {
// FIXME: Eventually, a NULL return will mean that one of the
- // instantiations was a semantic disaster, and we'll want to set Invalid =
- // true. For now, we expect to skip some members that we can't yet handle.
+ // instantiations was a semantic disaster, and we'll want to mark the
+ // declaration invalid.
+ // For now, we expect to skip some members that we can't yet handle.
}
}
@@ -1934,7 +1956,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
CheckCompletedCXXClass(Instantiation);
// Attach any in-class member initializers now the class is complete.
- {
+ if (!FieldsWithMemberInitializers.empty()) {
// C++11 [expr.prim.general]p4:
// Otherwise, if a member-declarator declares a non-static data member
// (9.2) of a class X, the expression this is a prvalue of type "pointer
@@ -1955,9 +1977,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Expr *Init = NewInit.take();
assert(Init && "no-argument initializer in class");
assert(!isa<ParenListExpr>(Init) && "call-style init in class");
- ActOnCXXInClassMemberInitializer(NewField,
- Init->getSourceRange().getBegin(),
- Init);
+ ActOnCXXInClassMemberInitializer(NewField, Init->getLocStart(), Init);
}
}
}
@@ -1976,8 +1996,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Instantiator.disableLateAttributeInstantiation();
LateAttrs.clear();
- if (!FieldsWithMemberInitializers.empty())
- ActOnFinishDelayedMemberInitializers(Instantiation);
+ ActOnFinishDelayedMemberInitializers(Instantiation);
if (TSK == TSK_ImplicitInstantiation) {
Instantiation->setLocation(Pattern->getLocation());
@@ -1985,9 +2004,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Instantiation->setRBraceLoc(Pattern->getRBraceLoc());
}
- if (Instantiation->isInvalidDecl())
- Invalid = true;
- else {
+ if (!Instantiation->isInvalidDecl()) {
+ // Perform any dependent diagnostics from the pattern.
+ PerformDependentDiagnostics(Pattern, TemplateArgs);
+
// Instantiate any out-of-line class template partial
// specializations now.
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
@@ -1997,7 +2017,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
P->first,
P->second)) {
- Invalid = true;
+ Instantiation->setInvalidDecl();
break;
}
}
@@ -2006,7 +2026,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// Exit the scope of this instantiation.
SavedContext.pop();
- if (!Invalid) {
+ if (!Instantiation->isInvalidDecl()) {
Consumer.HandleTagDeclDefinition(Instantiation);
// Always emit the vtable for an explicit instantiation definition
@@ -2015,7 +2035,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
MarkVTableUsed(PointOfInstantiation, Instantiation, true);
}
- return Invalid;
+ return Instantiation->isInvalidDecl();
}
/// \brief Instantiate the definition of an enum from a given pattern.