aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp199
1 files changed, 123 insertions, 76 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 00401560c6a0..10e411f5825a 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -823,7 +823,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
// Check for redefinition of this class template.
if (TUK == TUK_Definition) {
- if (TagDecl *Def = PrevRecordDecl->getDefinition(Context)) {
+ if (TagDecl *Def = PrevRecordDecl->getDefinition()) {
Diag(NameLoc, diag::err_redefinition) << Name;
Diag(Def->getLocation(), diag::note_previous_definition);
// FIXME: Would it make sense to try to "forget" the previous
@@ -1235,18 +1235,14 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
// such a member, the member declaration shall be preceded by a
// template<> for each enclosing class template that is
// explicitly specialized.
- // We interpret this as forbidding typedefs of template
- // specializations in the scope specifiers of out-of-line decls.
- if (const TypedefType *TT = dyn_cast<TypedefType>(T)) {
- const Type *UnderlyingT = TT->LookThroughTypedefs().getTypePtr();
- if (isa<TemplateSpecializationType>(UnderlyingT))
- // FIXME: better source location information.
- Diag(DeclStartLoc, diag::err_typedef_in_def_scope) << QualType(T,0);
- T = UnderlyingT;
- }
+ //
+ // Following the existing practice of GNU and EDG, we allow a typedef of a
+ // template specialization type.
+ if (const TypedefType *TT = dyn_cast<TypedefType>(T))
+ T = TT->LookThroughTypedefs().getTypePtr();
if (const TemplateSpecializationType *SpecType
- = dyn_cast<TemplateSpecializationType>(T)) {
+ = dyn_cast<TemplateSpecializationType>(T)) {
TemplateDecl *Template = SpecType->getTemplateName().getAsTemplateDecl();
if (!Template)
continue; // FIXME: should this be an error? probably...
@@ -1525,17 +1521,19 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
Qualifier = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
QualifierRange = SS.getRange();
}
+
+ // We don't want lookup warnings at this point.
+ R.suppressDiagnostics();
bool Dependent
= UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(),
&TemplateArgs);
UnresolvedLookupExpr *ULE
- = UnresolvedLookupExpr::Create(Context, Dependent,
+ = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
Qualifier, QualifierRange,
R.getLookupName(), R.getNameLoc(),
RequiresADL, TemplateArgs);
- for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
- ULE->addDecl(*I);
+ ULE->addDecls(R.begin(), R.end());
return Owned(ULE);
}
@@ -2305,7 +2303,17 @@ bool Sema::CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
} else
DRE = dyn_cast<DeclRefExpr>(Arg);
- if (!DRE || !isa<ValueDecl>(DRE->getDecl()))
+ if (!DRE)
+ return Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_not_decl_ref)
+ << Arg->getSourceRange();
+
+ // Stop checking the precise nature of the argument if it is value dependent,
+ // it should be checked when instantiated.
+ if (Arg->isValueDependent())
+ return false;
+
+ if (!isa<ValueDecl>(DRE->getDecl()))
return Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_object_or_func_form)
<< Arg->getSourceRange();
@@ -2324,7 +2332,7 @@ bool Sema::CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
// Functions must have external linkage.
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (Func->getLinkage() != NamedDecl::ExternalLinkage) {
+ if (!isExternalLinkage(Func->getLinkage())) {
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_function_not_extern)
<< Func << Arg->getSourceRange();
@@ -2339,7 +2347,7 @@ bool Sema::CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
}
if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
- if (Var->getLinkage() != NamedDecl::ExternalLinkage) {
+ if (!isExternalLinkage(Var->getLinkage())) {
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_object_not_extern)
<< Var << Arg->getSourceRange();
@@ -2656,9 +2664,13 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
return true;
- if (Entity)
- Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
- Converted = TemplateArgument(Entity);
+ if (Arg->isValueDependent()) {
+ Converted = TemplateArgument(Arg);
+ } else {
+ if (Entity)
+ Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
+ Converted = TemplateArgument(Entity);
+ }
return false;
}
@@ -2696,9 +2708,13 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
return true;
- if (Entity)
- Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
- Converted = TemplateArgument(Entity);
+ if (Arg->isValueDependent()) {
+ Converted = TemplateArgument(Arg);
+ } else {
+ if (Entity)
+ Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
+ Converted = TemplateArgument(Entity);
+ }
return false;
}
@@ -2712,7 +2728,8 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
assert(ParamRefType->getPointeeType()->isObjectType() &&
"Only object references allowed here");
- if (!Context.hasSameUnqualifiedType(ParamRefType->getPointeeType(), ArgType)) {
+ QualType ReferredType = ParamRefType->getPointeeType();
+ if (!Context.hasSameUnqualifiedType(ReferredType, ArgType)) {
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_no_ref_bind)
<< InstantiatedParamType << Arg->getType()
@@ -2722,7 +2739,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
}
unsigned ParamQuals
- = Context.getCanonicalType(ParamType).getCVRQualifiers();
+ = Context.getCanonicalType(ReferredType).getCVRQualifiers();
unsigned ArgQuals = Context.getCanonicalType(ArgType).getCVRQualifiers();
if ((ParamQuals | ArgQuals) != ParamQuals) {
@@ -2738,8 +2755,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
return true;
- Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
- Converted = TemplateArgument(Entity);
+ if (Arg->isValueDependent()) {
+ Converted = TemplateArgument(Arg);
+ } else {
+ Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
+ Converted = TemplateArgument(Entity);
+ }
return false;
}
@@ -3375,12 +3396,23 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// FIXME: Diagnose friend partial specializations
- // FIXME: Template parameter list matters, too
- ClassTemplatePartialSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- Context);
- } else
+ if (!Name.isDependent() &&
+ !TemplateSpecializationType::anyDependentTemplateArguments(
+ TemplateArgs.getArgumentArray(),
+ TemplateArgs.size())) {
+ Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
+ << ClassTemplate->getDeclName();
+ isPartialSpecialization = false;
+ } else {
+ // FIXME: Template parameter list matters, too
+ ClassTemplatePartialSpecializationDecl::Profile(ID,
+ Converted.getFlatArguments(),
+ Converted.flatSize(),
+ Context);
+ }
+ }
+
+ if (!isPartialSpecialization)
ClassTemplateSpecializationDecl::Profile(ID,
Converted.getFlatArguments(),
Converted.flatSize(),
@@ -3410,7 +3442,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
QualType CanonType;
if (PrevDecl &&
(PrevDecl->getSpecializationKind() == TSK_Undeclared ||
- TUK == TUK_Friend)) {
+ TUK == TUK_Friend)) {
// Since the only prior class template specialization with these
// arguments was referenced but not declared, or we're only
// referencing this specialization as a friend, reuse that
@@ -3423,8 +3455,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
} else if (isPartialSpecialization) {
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
- CanonType = Context.getTemplateSpecializationType(
- TemplateName(ClassTemplate),
+ TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
+ CanonType = Context.getTemplateSpecializationType(CanonTemplate,
Converted.getFlatArguments(),
Converted.flatSize());
@@ -3532,7 +3564,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// Check that this isn't a redefinition of this specialization.
if (TUK == TUK_Definition) {
- if (RecordDecl *Def = Specialization->getDefinition(Context)) {
+ if (RecordDecl *Def = Specialization->getDefinition()) {
SourceRange Range(TemplateNameLoc, RAngleLoc);
Diag(TemplateNameLoc, diag::err_redefinition)
<< Context.getTypeDeclType(Specialization) << Range;
@@ -3619,6 +3651,16 @@ Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
return DeclPtrTy();
}
+/// \brief Strips various properties off an implicit instantiation
+/// that has just been explicitly specialized.
+static void StripImplicitInstantiation(NamedDecl *D) {
+ D->invalidateAttrs();
+
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ FD->setInlineSpecified(false);
+ }
+}
+
/// \brief Diagnose cases where we have an explicit template specialization
/// before/after an explicit template instantiation, producing diagnostics
/// for those cases where they are required and determining whether the
@@ -3669,6 +3711,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
if (PrevPointOfInstantiation.isInvalid()) {
// The declaration itself has not actually been instantiated, so it is
// still okay to specialize it.
+ StripImplicitInstantiation(PrevDecl);
return false;
}
// Fall through
@@ -3817,8 +3860,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
LookupResult &Previous) {
// The set of function template specializations that could match this
// explicit function template specialization.
- typedef llvm::SmallVector<FunctionDecl *, 8> CandidateSet;
- CandidateSet Candidates;
+ UnresolvedSet<8> Candidates;
DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
@@ -3837,7 +3879,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
// Perform template argument deduction to determine whether we may be
// specializing this template.
// FIXME: It is somewhat wasteful to build
- TemplateDeductionInfo Info(Context);
+ TemplateDeductionInfo Info(Context, FD->getLocation());
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
= DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs,
@@ -3851,22 +3893,24 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
}
// Record this candidate.
- Candidates.push_back(Specialization);
+ Candidates.addDecl(Specialization, I.getAccess());
}
}
// Find the most specialized function template.
- FunctionDecl *Specialization = getMostSpecialized(Candidates.data(),
- Candidates.size(),
- TPOC_Other,
- FD->getLocation(),
+ UnresolvedSetIterator Result
+ = getMostSpecialized(Candidates.begin(), Candidates.end(),
+ TPOC_Other, FD->getLocation(),
PartialDiagnostic(diag::err_function_template_spec_no_match)
<< FD->getDeclName(),
PartialDiagnostic(diag::err_function_template_spec_ambiguous)
<< FD->getDeclName() << (ExplicitTemplateArgs != 0),
PartialDiagnostic(diag::note_function_template_spec_matched));
- if (!Specialization)
+ if (Result == Candidates.end())
return true;
+
+ // Ignore access information; it doesn't figure into redeclaration checking.
+ FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
// FIXME: Check if the prior specialization has a point of instantiation.
// If so, we have run afoul of .
@@ -3887,15 +3931,15 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
FunctionTemplateSpecializationInfo *SpecInfo
= Specialization->getTemplateSpecializationInfo();
assert(SpecInfo && "Function template specialization info missing?");
- if (SpecInfo->getPointOfInstantiation().isValid()) {
- Diag(FD->getLocation(), diag::err_specialization_after_instantiation)
- << FD;
- Diag(SpecInfo->getPointOfInstantiation(),
- diag::note_instantiation_required_here)
- << (Specialization->getTemplateSpecializationKind()
- != TSK_ImplicitInstantiation);
+
+ bool SuppressNew = false;
+ if (CheckSpecializationInstantiationRedecl(FD->getLocation(),
+ TSK_ExplicitSpecialization,
+ Specialization,
+ SpecInfo->getTemplateSpecializationKind(),
+ SpecInfo->getPointOfInstantiation(),
+ SuppressNew))
return true;
- }
// Mark the prior declaration as an explicit specialization, so that later
// clients know that this is an explicit specialization.
@@ -3904,8 +3948,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
// Turn the given function declaration into a function template
// specialization, with the template arguments from the previous
// specialization.
- FD->setFunctionTemplateSpecialization(Context,
- Specialization->getPrimaryTemplate(),
+ FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
new (Context) TemplateArgumentList(
*Specialization->getTemplateSpecializationArgs()),
/*InsertPos=*/0,
@@ -3997,14 +4040,15 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
// instantiation to take place, in every translation unit in which such a
// use occurs; no diagnostic is required.
assert(MSInfo && "Member specialization info missing?");
- if (MSInfo->getPointOfInstantiation().isValid()) {
- Diag(Member->getLocation(), diag::err_specialization_after_instantiation)
- << Member;
- Diag(MSInfo->getPointOfInstantiation(),
- diag::note_instantiation_required_here)
- << (MSInfo->getTemplateSpecializationKind() != TSK_ImplicitInstantiation);
+
+ bool SuppressNew = false;
+ if (CheckSpecializationInstantiationRedecl(Member->getLocation(),
+ TSK_ExplicitSpecialization,
+ Instantiation,
+ MSInfo->getTemplateSpecializationKind(),
+ MSInfo->getPointOfInstantiation(),
+ SuppressNew))
return true;
- }
// Check the scope of this explicit specialization.
if (CheckTemplateSpecializationScope(*this,
@@ -4288,13 +4332,13 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// instantiation.
ClassTemplateSpecializationDecl *Def
= cast_or_null<ClassTemplateSpecializationDecl>(
- Specialization->getDefinition(Context));
+ Specialization->getDefinition());
if (!Def)
InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
// Instantiate the members of this class template specialization.
Def = cast_or_null<ClassTemplateSpecializationDecl>(
- Specialization->getDefinition(Context));
+ Specialization->getDefinition());
if (Def)
InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
@@ -4371,7 +4415,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Verify that it is okay to explicitly instantiate here.
CXXRecordDecl *PrevDecl
= cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration());
- if (!PrevDecl && Record->getDefinition(Context))
+ if (!PrevDecl && Record->getDefinition())
PrevDecl = Record;
if (PrevDecl) {
MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
@@ -4388,13 +4432,13 @@ Sema::ActOnExplicitInstantiation(Scope *S,
}
CXXRecordDecl *RecordDef
- = cast_or_null<CXXRecordDecl>(Record->getDefinition(Context));
+ = cast_or_null<CXXRecordDecl>(Record->getDefinition());
if (!RecordDef) {
// C++ [temp.explicit]p3:
// A definition of a member class of a class template shall be in scope
// at the point of an explicit instantiation of the member class.
CXXRecordDecl *Def
- = cast_or_null<CXXRecordDecl>(Pattern->getDefinition(Context));
+ = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
if (!Def) {
Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member)
<< 0 << Record->getDeclName() << Record->getDeclContext();
@@ -4407,7 +4451,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
TSK))
return true;
- RecordDef = cast_or_null<CXXRecordDecl>(Record->getDefinition(Context));
+ RecordDef = cast_or_null<CXXRecordDecl>(Record->getDefinition());
if (!RecordDef)
return true;
}
@@ -4568,7 +4612,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// A member function [...] of a class template can be explicitly
// instantiated from the member definition associated with its class
// template.
- llvm::SmallVector<FunctionDecl *, 8> Matches;
+ UnresolvedSet<8> Matches;
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
P != PEnd; ++P) {
NamedDecl *Prev = *P;
@@ -4577,7 +4621,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
Matches.clear();
- Matches.push_back(Method);
+ Matches.addDecl(Method, P.getAccess());
if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
break;
}
@@ -4588,7 +4632,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
if (!FunTmpl)
continue;
- TemplateDeductionInfo Info(Context);
+ TemplateDeductionInfo Info(Context, D.getIdentifierLoc());
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
= DeduceTemplateArguments(FunTmpl,
@@ -4599,19 +4643,22 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
continue;
}
- Matches.push_back(Specialization);
+ Matches.addDecl(Specialization, P.getAccess());
}
// Find the most specialized function template specialization.
- FunctionDecl *Specialization
- = getMostSpecialized(Matches.data(), Matches.size(), TPOC_Other,
+ UnresolvedSetIterator Result
+ = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other,
D.getIdentifierLoc(),
PartialDiagnostic(diag::err_explicit_instantiation_not_known) << Name,
PartialDiagnostic(diag::err_explicit_instantiation_ambiguous) << Name,
PartialDiagnostic(diag::note_explicit_instantiation_candidate));
- if (!Specialization)
+ if (Result == Matches.end())
return true;
+
+ // Ignore access control bits, we don't need them for redeclaration checking.
+ FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) {
Diag(D.getIdentifierLoc(),