summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp132
1 files changed, 104 insertions, 28 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 33e83d0..d1428c5 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -339,7 +339,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
D->getLocation(), D->getIdentifier(),
DI->getType(), DI,
D->getStorageClass());
- Var->setThreadSpecified(D->isThreadSpecified());
+ Var->setTSCSpec(D->getTSCSpec());
Var->setInitStyle(D->getInitStyle());
Var->setCXXForRangeDecl(D->isCXXForRangeDecl());
Var->setConstexpr(D->isConstexpr());
@@ -525,6 +525,53 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
return Field;
}
+Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) {
+ bool Invalid = false;
+ TypeSourceInfo *DI = D->getTypeSourceInfo();
+
+ if (DI->getType()->isVariablyModifiedType()) {
+ SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified)
+ << D->getName();
+ Invalid = true;
+ } else if (DI->getType()->isInstantiationDependentType()) {
+ DI = SemaRef.SubstType(DI, TemplateArgs,
+ D->getLocation(), D->getDeclName());
+ if (!DI) {
+ DI = D->getTypeSourceInfo();
+ Invalid = true;
+ } else if (DI->getType()->isFunctionType()) {
+ // C++ [temp.arg.type]p3:
+ // If a declaration acquires a function type through a type
+ // dependent on a template-parameter and this causes a
+ // declaration that does not use the syntactic form of a
+ // function declarator to have function type, the program is
+ // ill-formed.
+ SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
+ << DI->getType();
+ Invalid = true;
+ }
+ } else {
+ SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
+ }
+
+ MSPropertyDecl *Property = new (SemaRef.Context)
+ MSPropertyDecl(Owner, D->getLocation(),
+ D->getDeclName(), DI->getType(), DI,
+ D->getLocStart(),
+ D->getGetterId(), D->getSetterId());
+
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs,
+ StartingScope);
+
+ if (Invalid)
+ Property->setInvalidDecl();
+
+ Property->setAccess(D->getAccess());
+ Owner->addDecl(Property);
+
+ return Property;
+}
+
Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
NamedDecl **NamedChain =
new (SemaRef.Context)NamedDecl*[D->getChainingSize()];
@@ -754,7 +801,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition(
// FIXME: Fixup LBraceLoc
SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(),
Enum->getRBraceLoc(), Enum,
- Enumerators.data(), Enumerators.size(),
+ Enumerators,
0, 0);
}
@@ -1105,12 +1152,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
// this declaration.
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
if (FunctionTemplate && !TemplateParams) {
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
void *InsertPos = 0;
FunctionDecl *SpecFunc
- = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ = FunctionTemplate->findSpecialization(Innermost.begin(), Innermost.size(),
InsertPos);
// If we already have a function template specialization, return it.
@@ -1162,7 +1208,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
FunctionDecl *Function =
FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
D->getNameInfo(), T, TInfo,
- D->getStorageClass(),
+ D->getCanonicalDecl()->getStorageClass(),
D->isInlineSpecified(), D->hasWrittenPrototype(),
D->isConstexpr());
@@ -1235,12 +1281,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
}
} else if (FunctionTemplate) {
// Record this function template specialization.
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
Function->setFunctionTemplateSpecialization(FunctionTemplate,
TemplateArgumentList::CreateCopy(SemaRef.Context,
- Innermost.first,
- Innermost.second),
+ Innermost.begin(),
+ Innermost.size()),
/*InsertPos=*/0);
} else if (isFriend) {
// Note, we need this connection even if the friend doesn't have a body.
@@ -1413,12 +1458,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
// We are creating a function template specialization from a function
// template. Check whether there is already a function template
// specialization for this particular set of template arguments.
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
void *InsertPos = 0;
FunctionDecl *SpecFunc
- = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ = FunctionTemplate->findSpecialization(Innermost.begin(),
+ Innermost.size(),
InsertPos);
// If we already have a function template specialization, return it.
@@ -1513,6 +1558,36 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Constructor->isExplicit(),
Constructor->isInlineSpecified(),
false, Constructor->isConstexpr());
+
+ // Claim that the instantiation of a constructor or constructor template
+ // inherits the same constructor that the template does.
+ if (CXXConstructorDecl *Inh = const_cast<CXXConstructorDecl *>(
+ Constructor->getInheritedConstructor())) {
+ // If we're instantiating a specialization of a function template, our
+ // "inherited constructor" will actually itself be a function template.
+ // Instantiate a declaration of it, too.
+ if (FunctionTemplate) {
+ assert(!TemplateParams && Inh->getDescribedFunctionTemplate() &&
+ !Inh->getParent()->isDependentContext() &&
+ "inheriting constructor template in dependent context?");
+ Sema::InstantiatingTemplate Inst(SemaRef, Constructor->getLocation(),
+ Inh);
+ if (Inst)
+ return 0;
+ Sema::ContextRAII SavedContext(SemaRef, Inh->getDeclContext());
+ LocalInstantiationScope LocalScope(SemaRef);
+
+ // Use the same template arguments that we deduced for the inheriting
+ // constructor. There's no way they could be deduced differently.
+ MultiLevelTemplateArgumentList InheritedArgs;
+ InheritedArgs.addOuterTemplateArguments(TemplateArgs.getInnermost());
+ Inh = cast_or_null<CXXConstructorDecl>(
+ SemaRef.SubstDecl(Inh, Inh->getDeclContext(), InheritedArgs));
+ if (!Inh)
+ return 0;
+ }
+ cast<CXXConstructorDecl>(Method)->setInheritedConstructor(Inh);
+ }
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
@@ -1526,10 +1601,10 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Conversion->isConstexpr(),
Conversion->getLocEnd());
} else {
+ StorageClass SC = D->isStatic() ? SC_Static : SC_None;
Method = CXXMethodDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
- D->getStorageClass(),
- D->isInlineSpecified(),
+ SC, D->isInlineSpecified(),
D->isConstexpr(), D->getLocEnd());
}
@@ -1565,12 +1640,11 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Method->setDescribedFunctionTemplate(FunctionTemplate);
} else if (FunctionTemplate) {
// Record this function template specialization.
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
Method->setFunctionTemplateSpecialization(FunctionTemplate,
TemplateArgumentList::CreateCopy(SemaRef.Context,
- Innermost.first,
- Innermost.second),
+ Innermost.begin(),
+ Innermost.size()),
/*InsertPos=*/0);
} else if (!isFriend) {
// Record that this is an instantiation of a member function.
@@ -2688,15 +2762,16 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
FunctionDecl *ExceptionSpecTemplate = Tmpl;
if (EPI.ExceptionSpecType == EST_Uninstantiated)
ExceptionSpecTemplate = EPI.ExceptionSpecTemplate;
- assert(EPI.ExceptionSpecType != EST_Unevaluated &&
- "instantiating implicitly-declared special member");
+ ExceptionSpecificationType NewEST = EST_Uninstantiated;
+ if (EPI.ExceptionSpecType == EST_Unevaluated)
+ NewEST = EST_Unevaluated;
// Mark the function has having an uninstantiated exception specification.
const FunctionProtoType *NewProto
= New->getType()->getAs<FunctionProtoType>();
assert(NewProto && "Template instantiation without function prototype?");
EPI = NewProto->getExtProtoInfo();
- EPI.ExceptionSpecType = EST_Uninstantiated;
+ EPI.ExceptionSpecType = NewEST;
EPI.ExceptionSpecDecl = New;
EPI.ExceptionSpecTemplate = ExceptionSpecTemplate;
New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(),
@@ -2733,7 +2808,6 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
if (Tmpl->isVirtualAsWritten())
New->setVirtualAsWritten(true);
- // FIXME: attributes
// FIXME: New needs a pointer to Tmpl
return false;
}
@@ -2820,13 +2894,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
return;
}
- // C++0x [temp.explicit]p9:
- // Except for inline functions, other explicit instantiation declarations
- // have the effect of suppressing the implicit instantiation of the entity
- // to which they refer.
+ // C++1y [temp.explicit]p10:
+ // Except for inline functions, declarations with types deduced from their
+ // initializer or return value, and class template specializations, other
+ // explicit instantiation declarations have the effect of suppressing the
+ // implicit instantiation of the entity to which they refer.
if (Function->getTemplateSpecializationKind()
== TSK_ExplicitInstantiationDeclaration &&
- !PatternDecl->isInlined())
+ !PatternDecl->isInlined() &&
+ !PatternDecl->getResultType()->isUndeducedType())
return;
if (PatternDecl->isInlined())
OpenPOWER on IntegriCloud