Newer
Older
//===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===/
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
Douglas Gregor
committed
//===----------------------------------------------------------------------===/
//
// This file implements semantic analysis for C++ templates.
Douglas Gregor
committed
//===----------------------------------------------------------------------===/
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Basic/LangOptions.h"
using namespace clang;
/// isTemplateName - Determines whether the identifier II is a
/// template name in the current scope, and returns the template
/// declaration if II names a template. An optional CXXScope can be
/// passed to indicate the C++ scope in which the identifier will be
/// found.
TemplateNameKind Sema::isTemplateName(const IdentifierInfo &II, Scope *S,
TemplateTy &TemplateResult,
Douglas Gregor
committed
const CXXScopeSpec *SS) {
NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
TemplateNameKind TNK = TNK_Non_template;
TemplateDecl *Template = 0;
if (IIDecl) {
if ((Template = dyn_cast<TemplateDecl>(IIDecl))) {
if (isa<FunctionTemplateDecl>(IIDecl))
TNK = TNK_Function_template;
else if (isa<ClassTemplateDecl>(IIDecl) ||
isa<TemplateTemplateParmDecl>(IIDecl))
TNK = TNK_Type_template;
else
assert(false && "Unknown template declaration kind");
} else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(IIDecl)) {
// C++ [temp.local]p1:
// Like normal (non-template) classes, class templates have an
// injected-class-name (Clause 9). The injected-class-name
// can be used with or without a template-argument-list. When
// it is used without a template-argument-list, it is
// equivalent to the injected-class-name followed by the
// template-parameters of the class template enclosed in
// <>. When it is used with a template-argument-list, it
// refers to the specified class template specialization,
// which could be the current specialization or another
// specialization.
if (Record->isInjectedClassName()) {
Record = cast<CXXRecordDecl>(Context.getCanonicalDecl(Record));
if ((Template = Record->getDescribedClassTemplate()))
TNK = TNK_Type_template;
else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
Template = Spec->getSpecializedTemplate();
TNK = TNK_Type_template;
// FIXME: What follows is a gross hack.
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) {
if (FD->getType()->isDependentType()) {
TemplateResult = TemplateTy::make(FD);
return TNK_Function_template;
}
} else if (OverloadedFunctionDecl *Ovl
= dyn_cast<OverloadedFunctionDecl>(IIDecl)) {
for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
FEnd = Ovl->function_end();
F != FEnd; ++F) {
if ((*F)->getType()->isDependentType()) {
TemplateResult = TemplateTy::make(Ovl);
return TNK_Function_template;
}
}
}
if (TNK != TNK_Non_template) {
if (SS && SS->isSet() && !SS->isInvalid()) {
NestedNameSpecifier *Qualifier
= static_cast<NestedNameSpecifier *>(SS->getScopeRep());
TemplateResult
= TemplateTy::make(Context.getQualifiedTemplateName(Qualifier,
false,
Template));
} else
TemplateResult = TemplateTy::make(TemplateName(Template));
}
}
return TNK;
}
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
/// that the template parameter 'PrevDecl' is being shadowed by a new
/// declaration at location Loc. Returns true to indicate that this is
/// an error, and false otherwise.
bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
Douglas Gregor
committed
assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
// Microsoft Visual C++ permits template parameters to be shadowed.
if (getLangOptions().Microsoft)
return false;
// C++ [temp.local]p4:
// A template-parameter shall not be redeclared within its
// scope (including nested scopes).
Diag(Loc, diag::err_template_param_shadow)
<< cast<NamedDecl>(PrevDecl)->getDeclName();
Diag(PrevDecl->getLocation(), diag::note_template_param_here);
return true;
}
/// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
/// the parameter D to reference the templated declaration and return a pointer
/// to the template declaration. Otherwise, do nothing to D and return null.
Chris Lattner
committed
TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
if (TemplateDecl *Temp = dyn_cast<TemplateDecl>(D.getAs<Decl>())) {
D = DeclPtrTy::make(Temp->getTemplatedDecl());
return Temp;
}
return 0;
}
/// ActOnTypeParameter - Called when a C++ template type parameter
/// (e.g., "typename T") has been parsed. Typename specifies whether
/// the keyword "typename" was used to declare the type parameter
/// (otherwise, "class" was used), and KeyLoc is the location of the
/// "class" or "typename" keyword. ParamName is the name of the
/// parameter (NULL indicates an unnamed template parameter) and
/// ParamName is the location of the parameter name (if any).
/// If the type parameter has a default argument, it will be added
/// later via ActOnTypeParameterDefault.
Chris Lattner
committed
Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
SourceLocation ParamNameLoc,
unsigned Depth, unsigned Position) {
assert(S->isTemplateParamScope() &&
"Template type parameter not in template parameter scope!");
bool Invalid = false;
if (ParamName) {
NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
Douglas Gregor
committed
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
PrevDecl);
}
SourceLocation Loc = ParamNameLoc;
if (!ParamName)
Loc = KeyLoc;
TemplateTypeParmDecl *Param
= TemplateTypeParmDecl::Create(Context, CurContext, Loc,
Depth, Position, ParamName, Typename);
if (Invalid)
Param->setInvalidDecl();
if (ParamName) {
// Add the template parameter into the current scope.
Chris Lattner
committed
S->AddDecl(DeclPtrTy::make(Param));
IdResolver.AddDecl(Param);
}
Chris Lattner
committed
return DeclPtrTy::make(Param);
/// ActOnTypeParameterDefault - Adds a default argument (the type
/// Default) to the given template type parameter (TypeParam).
Chris Lattner
committed
void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
SourceLocation EqualLoc,
SourceLocation DefaultLoc,
TypeTy *DefaultT) {
TemplateTypeParmDecl *Parm
Chris Lattner
committed
= cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
QualType Default = QualType::getFromOpaquePtr(DefaultT);
// C++ [temp.param]p14:
// A template-parameter shall not be used in its own default argument.
// FIXME: Implement this check! Needs a recursive walk over the types.
// Check the template argument itself.
if (CheckTemplateArgument(Parm, Default, DefaultLoc)) {
Parm->setInvalidDecl();
return;
}
Parm->setDefaultArgument(Default, DefaultLoc, false);
}
/// \brief Check that the type of a non-type template parameter is
/// well-formed.
///
/// \returns the (possibly-promoted) parameter type if valid;
/// otherwise, produces a diagnostic and returns a NULL type.
QualType
Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
// C++ [temp.param]p4:
//
// A non-type template-parameter shall have one of the following
// (optionally cv-qualified) types:
//
// -- integral or enumeration type,
if (T->isIntegralType() || T->isEnumeralType() ||
// -- pointer to object or pointer to function,
(T->isPointerType() &&
(T->getAsPointerType()->getPointeeType()->isObjectType() ||
T->getAsPointerType()->getPointeeType()->isFunctionType())) ||
// -- reference to object or reference to function,
T->isReferenceType() ||
// -- pointer to member.
T->isMemberPointerType() ||
// If T is a dependent type, we can't do the check now, so we
// assume that it is well-formed.
T->isDependentType())
return T;
// C++ [temp.param]p8:
//
// A non-type template-parameter of type "array of T" or
// "function returning T" is adjusted to be of type "pointer to
// T" or "pointer to function returning T", respectively.
else if (T->isArrayType())
// FIXME: Keep the type prior to promotion?
return Context.getArrayDecayedType(T);
else if (T->isFunctionType())
// FIXME: Keep the type prior to promotion?
return Context.getPointerType(T);
Diag(Loc, diag::err_template_nontype_parm_bad_type)
<< T;
return QualType();
}
/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
/// template parameter (e.g., "int Size" in "template<int Size>
/// class Array") has been parsed. S is the current scope and D is
/// the parsed declarator.
Chris Lattner
committed
Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
unsigned Depth,
unsigned Position) {
QualType T = GetTypeForDeclarator(D, S);
assert(S->isTemplateParamScope() &&
"Non-type template parameter not in template parameter scope!");
bool Invalid = false;
IdentifierInfo *ParamName = D.getIdentifier();
if (ParamName) {
NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
PrevDecl);
T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc());
Douglas Gregor
committed
if (T.isNull()) {
T = Context.IntTy; // Recover with an 'int' type.
Douglas Gregor
committed
Invalid = true;
}
NonTypeTemplateParmDecl *Param
= NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
Depth, Position, ParamName, T);
if (Invalid)
Param->setInvalidDecl();
if (D.getIdentifier()) {
// Add the template parameter into the current scope.
Chris Lattner
committed
S->AddDecl(DeclPtrTy::make(Param));
IdResolver.AddDecl(Param);
}
Chris Lattner
committed
return DeclPtrTy::make(Param);
Douglas Gregor
committed
/// \brief Adds a default argument to the given non-type template
/// parameter.
Chris Lattner
committed
void Sema::ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParamD,
SourceLocation EqualLoc,
ExprArg DefaultE) {
NonTypeTemplateParmDecl *TemplateParm
Chris Lattner
committed
= cast<NonTypeTemplateParmDecl>(TemplateParamD.getAs<Decl>());
Expr *Default = static_cast<Expr *>(DefaultE.get());
// C++ [temp.param]p14:
// A template-parameter shall not be used in its own default argument.
// FIXME: Implement this check! Needs a recursive walk over the types.
// Check the well-formedness of the default template argument.
if (CheckTemplateArgument(TemplateParm, TemplateParm->getType(), Default)) {
TemplateParm->setInvalidDecl();
return;
}
TemplateParm->setDefaultArgument(static_cast<Expr *>(DefaultE.release()));
}
/// ActOnTemplateTemplateParameter - Called when a C++ template template
/// parameter (e.g. T in template <template <typename> class T> class array)
/// has been parsed. S is the current scope.
Chris Lattner
committed
Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
SourceLocation TmpLoc,
TemplateParamsTy *Params,
IdentifierInfo *Name,
SourceLocation NameLoc,
unsigned Depth,
unsigned Position)
{
assert(S->isTemplateParamScope() &&
"Template template parameter not in template parameter scope!");
// Construct the parameter object.
TemplateTemplateParmDecl *Param =
TemplateTemplateParmDecl::Create(Context, CurContext, TmpLoc, Depth,
Position, Name,
(TemplateParameterList*)Params);
// Make sure the parameter is valid.
// FIXME: Decl object is not currently invalidated anywhere so this doesn't
// do anything yet. However, if the template parameter list or (eventual)
// default value is ever invalidated, that will propagate here.
bool Invalid = false;
if (Invalid) {
Param->setInvalidDecl();
}
// If the tt-param has a name, then link the identifier into the scope
// and lookup mechanisms.
if (Name) {
Chris Lattner
committed
S->AddDecl(DeclPtrTy::make(Param));
IdResolver.AddDecl(Param);
}
Chris Lattner
committed
return DeclPtrTy::make(Param);
/// \brief Adds a default argument to the given template template
/// parameter.
Chris Lattner
committed
void Sema::ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParamD,
SourceLocation EqualLoc,
ExprArg DefaultE) {
TemplateTemplateParmDecl *TemplateParm
Chris Lattner
committed
= cast<TemplateTemplateParmDecl>(TemplateParamD.getAs<Decl>());
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
// Since a template-template parameter's default argument is an
// id-expression, it must be a DeclRefExpr.
DeclRefExpr *Default
= cast<DeclRefExpr>(static_cast<Expr *>(DefaultE.get()));
// C++ [temp.param]p14:
// A template-parameter shall not be used in its own default argument.
// FIXME: Implement this check! Needs a recursive walk over the types.
// Check the well-formedness of the template argument.
if (!isa<TemplateDecl>(Default->getDecl())) {
Diag(Default->getSourceRange().getBegin(),
diag::err_template_arg_must_be_template)
<< Default->getSourceRange();
TemplateParm->setInvalidDecl();
return;
}
if (CheckTemplateArgument(TemplateParm, Default)) {
TemplateParm->setInvalidDecl();
return;
}
DefaultE.release();
TemplateParm->setDefaultArgument(Default);
}
Douglas Gregor
committed
/// ActOnTemplateParameterList - Builds a TemplateParameterList that
/// contains the template parameters in Params/NumParams.
Sema::TemplateParamsTy *
Sema::ActOnTemplateParameterList(unsigned Depth,
SourceLocation ExportLoc,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
Chris Lattner
committed
DeclPtrTy *Params, unsigned NumParams,
Douglas Gregor
committed
SourceLocation RAngleLoc) {
if (ExportLoc.isValid())
Diag(ExportLoc, diag::note_template_export_unsupported);
return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
(Decl**)Params, NumParams, RAngleLoc);
}
Sema::DeclResult
Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
SourceLocation KWLoc, const CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr,
Anders Carlsson
committed
MultiTemplateParamsArg TemplateParameterLists,
AccessSpecifier AS) {
assert(TemplateParameterLists.size() > 0 && "No template parameter lists?");
assert(TK != TK_Reference && "Can only declare or define class templates");
bool Invalid = false;
// Check that we can declare a template here.
if (CheckTemplateDeclScope(S, TemplateParameterLists))
return true;
TagDecl::TagKind Kind;
switch (TagSpec) {
default: assert(0 && "Unknown tag type!");
case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
case DeclSpec::TST_union: Kind = TagDecl::TK_union; break;
case DeclSpec::TST_class: Kind = TagDecl::TK_class; break;
}
// There is no such thing as an unnamed class template.
if (!Name) {
Diag(KWLoc, diag::err_template_unnamed_class);
return true;
}
// Find any previous declaration with this name.
LookupResult Previous = LookupParsedName(S, &SS, Name, LookupOrdinaryName,
true);
assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?");
NamedDecl *PrevDecl = 0;
if (Previous.begin() != Previous.end())
PrevDecl = *Previous.begin();
DeclContext *SemanticContext = CurContext;
if (SS.isNotEmpty() && !SS.isInvalid()) {
SemanticContext = computeDeclContext(SS);
// FIXME: need to match up several levels of template parameter
// lists here.
}
// FIXME: member templates!
TemplateParameterList *TemplateParams
= static_cast<TemplateParameterList *>(*TemplateParameterLists.release());
// If there is a previous declaration with the same name, check
// whether this is a valid redeclaration.
ClassTemplateDecl *PrevClassTemplate
= dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
if (PrevClassTemplate) {
// Ensure that the template parameter lists are compatible.
if (!TemplateParameterListsAreEqual(TemplateParams,
PrevClassTemplate->getTemplateParameters(),
/*Complain=*/true))
return true;
// C++ [temp.class]p4:
// In a redeclaration, partial specialization, explicit
// specialization or explicit instantiation of a class template,
// the class-key shall agree in kind with the original class
// template declaration (7.1.5.3).
RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl();
if (PrevRecordDecl->getTagKind() != Kind) {
Diag(KWLoc, diag::err_use_with_wrong_tag)
<< Name
<< CodeModificationHint::CreateReplacement(KWLoc,
PrevRecordDecl->getKindName());
Diag(PrevRecordDecl->getLocation(), diag::note_previous_use);
Kind = PrevRecordDecl->getTagKind();
}
// Check for redefinition of this class template.
if (TK == TK_Definition) {
if (TagDecl *Def = PrevRecordDecl->getDefinition(Context)) {
Diag(NameLoc, diag::err_redefinition) << Name;
Diag(Def->getLocation(), diag::note_previous_definition);
// FIXME: Would it make sense to try to "forget" the previous
// definition, as part of error recovery?
return true;
}
}
} else if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
// Just pretend that we didn't see the previous declaration.
PrevDecl = 0;
} else if (PrevDecl) {
// C++ [temp]p5:
// A class template shall not have the same name as any other
// template, class, function, object, enumeration, enumerator,
// namespace, or type in the same scope (3.3), except as specified
// in (14.5.4).
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
return true;
// Check the template parameter list of this declaration, possibly
// merging in the template parameter list from the previous class
// template declaration.
if (CheckTemplateParameterList(TemplateParams,
PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0))
Invalid = true;
// If we had a scope specifier, we better have a previous template
// declaration!
CXXRecordDecl *NewClass =
CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name,
PrevClassTemplate?
PrevClassTemplate->getTemplatedDecl() : 0);
ClassTemplateDecl *NewTemplate
= ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
DeclarationName(Name), TemplateParams,
NewClass, PrevClassTemplate);
NewClass->setDescribedClassTemplate(NewTemplate);
// Set the access specifier.
SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
// Set the lexical context of these templates
NewClass->setLexicalDeclContext(CurContext);
NewTemplate->setLexicalDeclContext(CurContext);
if (TK == TK_Definition)
NewClass->startDefinition();
if (Attr)
ProcessDeclAttributeList(NewClass, Attr);
PushOnScopeChains(NewTemplate, S);
if (Invalid) {
NewTemplate->setInvalidDecl();
NewClass->setInvalidDecl();
}
Chris Lattner
committed
return DeclPtrTy::make(NewTemplate);
Douglas Gregor
committed
}
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
/// \brief Checks the validity of a template parameter list, possibly
/// considering the template parameter list from a previous
/// declaration.
///
/// If an "old" template parameter list is provided, it must be
/// equivalent (per TemplateParameterListsAreEqual) to the "new"
/// template parameter list.
///
/// \param NewParams Template parameter list for a new template
/// declaration. This template parameter list will be updated with any
/// default arguments that are carried through from the previous
/// template parameter list.
///
/// \param OldParams If provided, template parameter list from a
/// previous declaration of the same template. Default template
/// arguments will be merged from the old template parameter list to
/// the new template parameter list.
///
/// \returns true if an error occurred, false otherwise.
bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
TemplateParameterList *OldParams) {
bool Invalid = false;
// C++ [temp.param]p10:
// The set of default template-arguments available for use with a
// template declaration or definition is obtained by merging the
// default arguments from the definition (if in scope) and all
// declarations in scope in the same way default function
// arguments are (8.3.6).
bool SawDefaultArgument = false;
SourceLocation PreviousDefaultArgLoc;
TemplateParameterList::iterator OldParam = NewParams->end();
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
if (OldParams)
OldParam = OldParams->begin();
for (TemplateParameterList::iterator NewParam = NewParams->begin(),
NewParamEnd = NewParams->end();
NewParam != NewParamEnd; ++NewParam) {
// Variables used to diagnose redundant default arguments
bool RedundantDefaultArg = false;
SourceLocation OldDefaultLoc;
SourceLocation NewDefaultLoc;
// Variables used to diagnose missing default arguments
bool MissingDefaultArg = false;
// Merge default arguments for template type parameters.
if (TemplateTypeParmDecl *NewTypeParm
= dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
TemplateTypeParmDecl *OldTypeParm
= OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0;
if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
NewTypeParm->hasDefaultArgument()) {
OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
SawDefaultArgument = true;
RedundantDefaultArg = true;
PreviousDefaultArgLoc = NewDefaultLoc;
} else if (OldTypeParm && OldTypeParm->hasDefaultArgument()) {
// Merge the default argument from the old declaration to the
// new declaration.
SawDefaultArgument = true;
NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgument(),
OldTypeParm->getDefaultArgumentLoc(),
true);
PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc();
} else if (NewTypeParm->hasDefaultArgument()) {
SawDefaultArgument = true;
PreviousDefaultArgLoc = NewTypeParm->getDefaultArgumentLoc();
} else if (SawDefaultArgument)
MissingDefaultArg = true;
}
// Merge default arguments for non-type template parameters
else if (NonTypeTemplateParmDecl *NewNonTypeParm
= dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) {
NonTypeTemplateParmDecl *OldNonTypeParm
= OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0;
if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
NewNonTypeParm->hasDefaultArgument()) {
OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc();
SawDefaultArgument = true;
RedundantDefaultArg = true;
PreviousDefaultArgLoc = NewDefaultLoc;
} else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument()) {
// Merge the default argument from the old declaration to the
// new declaration.
SawDefaultArgument = true;
// FIXME: We need to create a new kind of "default argument"
// expression that points to a previous template template
// parameter.
NewNonTypeParm->setDefaultArgument(
OldNonTypeParm->getDefaultArgument());
PreviousDefaultArgLoc = OldNonTypeParm->getDefaultArgumentLoc();
} else if (NewNonTypeParm->hasDefaultArgument()) {
SawDefaultArgument = true;
PreviousDefaultArgLoc = NewNonTypeParm->getDefaultArgumentLoc();
} else if (SawDefaultArgument)
MissingDefaultArg = true;
}
// Merge default arguments for template template parameters
else {
TemplateTemplateParmDecl *NewTemplateParm
= cast<TemplateTemplateParmDecl>(*NewParam);
TemplateTemplateParmDecl *OldTemplateParm
= OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0;
if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
NewTemplateParm->hasDefaultArgument()) {
OldDefaultLoc = OldTemplateParm->getDefaultArgumentLoc();
NewDefaultLoc = NewTemplateParm->getDefaultArgumentLoc();
SawDefaultArgument = true;
RedundantDefaultArg = true;
PreviousDefaultArgLoc = NewDefaultLoc;
} else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument()) {
// Merge the default argument from the old declaration to the
// new declaration.
SawDefaultArgument = true;
// FIXME: We need to create a new kind of "default argument"
// expression that points to a previous template template
// parameter.
NewTemplateParm->setDefaultArgument(
OldTemplateParm->getDefaultArgument());
PreviousDefaultArgLoc = OldTemplateParm->getDefaultArgumentLoc();
} else if (NewTemplateParm->hasDefaultArgument()) {
SawDefaultArgument = true;
PreviousDefaultArgLoc = NewTemplateParm->getDefaultArgumentLoc();
} else if (SawDefaultArgument)
MissingDefaultArg = true;
}
if (RedundantDefaultArg) {
// C++ [temp.param]p12:
// A template-parameter shall not be given default arguments
// by two different declarations in the same scope.
Diag(NewDefaultLoc, diag::err_template_param_default_arg_redefinition);
Diag(OldDefaultLoc, diag::note_template_param_prev_default_arg);
Invalid = true;
} else if (MissingDefaultArg) {
// C++ [temp.param]p11:
// If a template-parameter has a default template-argument,
// all subsequent template-parameters shall have a default
// template-argument supplied.
Diag((*NewParam)->getLocation(),
diag::err_template_param_default_arg_missing);
Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg);
Invalid = true;
}
// If we have an old template parameter list that we're merging
// in, move on to the next parameter.
if (OldParams)
++OldParam;
}
return Invalid;
}
/// \brief Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis.
static void
translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
SourceLocation *TemplateArgLocs,
llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) {
TemplateArgs.reserve(TemplateArgsIn.size());
void **Args = TemplateArgsIn.getArgs();
bool *ArgIsType = TemplateArgsIn.getArgIsType();
for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
TemplateArgs.push_back(
ArgIsType[Arg]? TemplateArgument(TemplateArgLocs[Arg],
QualType::getFromOpaquePtr(Args[Arg]))
: TemplateArgument(reinterpret_cast<Expr *>(Args[Arg])));
}
}
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
/// \brief Build a canonical version of a template argument list.
///
/// This function builds a canonical version of the given template
/// argument list, where each of the template arguments has been
/// converted into its canonical form. This routine is typically used
/// to canonicalize a template argument list when the template name
/// itself is dependent. When the template name refers to an actual
/// template declaration, Sema::CheckTemplateArgumentList should be
/// used to check and canonicalize the template arguments.
///
/// \param TemplateArgs The incoming template arguments.
///
/// \param NumTemplateArgs The number of template arguments in \p
/// TemplateArgs.
///
/// \param Canonical A vector to be filled with the canonical versions
/// of the template arguments.
///
/// \param Context The ASTContext in which the template arguments live.
static void CanonicalizeTemplateArguments(const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
llvm::SmallVectorImpl<TemplateArgument> &Canonical,
ASTContext &Context) {
Canonical.reserve(NumTemplateArgs);
for (unsigned Idx = 0; Idx < NumTemplateArgs; ++Idx) {
switch (TemplateArgs[Idx].getKind()) {
case TemplateArgument::Expression:
// FIXME: Build canonical expression (!)
Canonical.push_back(TemplateArgs[Idx]);
break;
case TemplateArgument::Declaration:
Canonical.push_back(TemplateArgument(SourceLocation(),
TemplateArgs[Idx].getAsDecl()));
break;
case TemplateArgument::Integral:
Canonical.push_back(TemplateArgument(SourceLocation(),
*TemplateArgs[Idx].getAsIntegral(),
TemplateArgs[Idx].getIntegralType()));
case TemplateArgument::Type: {
QualType CanonType
= Context.getCanonicalType(TemplateArgs[Idx].getAsType());
Canonical.push_back(TemplateArgument(SourceLocation(), CanonType));
}
}
}
}
QualType Sema::CheckTemplateIdType(TemplateName Name,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
TemplateDecl *Template = Name.getAsTemplateDecl();
if (!Template) {
// The template name does not resolve to a template, so we just
// build a dependent template-id type.
// Canonicalize the template arguments to build the canonical
// template-id type.
llvm::SmallVector<TemplateArgument, 16> CanonicalTemplateArgs;
CanonicalizeTemplateArguments(TemplateArgs, NumTemplateArgs,
CanonicalTemplateArgs, Context);
// FIXME: Get the canonical template-name
QualType CanonType
= Context.getTemplateSpecializationType(Name, &CanonicalTemplateArgs[0],
CanonicalTemplateArgs.size());
// Build the dependent template-id type.
return Context.getTemplateSpecializationType(Name, TemplateArgs,
NumTemplateArgs, CanonType);
}
// Check that the template argument list is well-formed for this
// template.
llvm::SmallVector<TemplateArgument, 16> ConvertedTemplateArgs;
if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
TemplateArgs, NumTemplateArgs, RAngleLoc,
ConvertedTemplateArgs))
return QualType();
assert((ConvertedTemplateArgs.size() ==
Template->getTemplateParameters()->size()) &&
"Converted template argument list is too short!");
QualType CanonType;
if (TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs,
NumTemplateArgs)) {
// This class template specialization is a dependent
// type. Therefore, its canonical type is another class template
// specialization type that contains all of the converted
// arguments in canonical form. This ensures that, e.g., A<T> and
// A<T, T> have identical types when A is declared as:
//
// template<typename T, typename U = T> struct A;
CanonType = Context.getTemplateSpecializationType(Name,
&ConvertedTemplateArgs[0],
ConvertedTemplateArgs.size());
} else if (ClassTemplateDecl *ClassTemplate
= dyn_cast<ClassTemplateDecl>(Template)) {
// Find the class template specialization declaration that
// corresponds to these arguments.
llvm::FoldingSetNodeID ID;
ClassTemplateSpecializationDecl::Profile(ID, &ConvertedTemplateArgs[0],
ConvertedTemplateArgs.size());
void *InsertPos = 0;
ClassTemplateSpecializationDecl *Decl
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
if (!Decl) {
// This is the first time we have referenced this class template
// specialization. Create the canonical declaration and add it to
// the set of specializations.
Decl = ClassTemplateSpecializationDecl::Create(Context,
ClassTemplate->getDeclContext(),
TemplateLoc,
ClassTemplate,
&ConvertedTemplateArgs[0],
ConvertedTemplateArgs.size(),
0);
ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
Decl->setLexicalDeclContext(CurContext);
}
CanonType = Context.getTypeDeclType(Decl);
// Build the fully-sugared type for this class template
// specialization, which refers back to the class template
// specialization we created or found.
return Context.getTemplateSpecializationType(Name, TemplateArgs,
NumTemplateArgs, CanonType);
}
Action::TypeResult
Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc) {
TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format.
llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
&TemplateArgs[0], TemplateArgs.size(),
RAngleLoc);
TemplateArgsIn.release();
if (Result.isNull())
return true;
return Result.getAsOpaquePtr();
}
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
/// name and its (presumably dependent) scope specifier. For
/// example, given "MetaFun::template apply", the scope specifier \p
/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
/// of the "template" keyword, and "apply" is the \p Name.
Sema::TemplateTy
Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
const IdentifierInfo &Name,
SourceLocation NameLoc,
const CXXScopeSpec &SS) {
if (!SS.isSet() || SS.isInvalid())
return TemplateTy();
NestedNameSpecifier *Qualifier
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
// FIXME: member of the current instantiation
if (!Qualifier->isDependent()) {
// C++0x [temp.names]p5:
// If a name prefixed by the keyword template is not the name of
// a template, the program is ill-formed. [Note: the keyword
// template may not be applied to non-template members of class
// templates. -end note ] [ Note: as is the case with the
// typename prefix, the template prefix is allowed in cases
// where it is not strictly necessary; i.e., when the
// nested-name-specifier or the expression on the left of the ->
// or . is not dependent on a template-parameter, or the use
// does not appear in the scope of a template. -end note]
//
// Note: C++03 was more strict here, because it banned the use of
// the "template" keyword prior to a template-name that was not a
// dependent name. C++ DR468 relaxed this requirement (the
// "template" keyword is now permitted). We follow the C++0x
// rules, even in C++03 mode, retroactively applying the DR.
TemplateTy Template;
TemplateNameKind TNK = isTemplateName(Name, 0, Template, &SS);
if (TNK == TNK_Non_template) {
Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
<< &Name;
return TemplateTy();
}
return Template;
}
return TemplateTy::make(Context.getDependentTemplateName(Qualifier, &Name));
}
/// \brief Check that the given template argument list is well-formed
/// for specializing the given template.
bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
llvm::SmallVectorImpl<TemplateArgument> &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size();
unsigned NumArgs = NumTemplateArgs;
bool Invalid = false;
if (NumArgs > NumParams ||
NumArgs < Params->getMinRequiredArguments()) {
// FIXME: point at either the first arg beyond what we can handle,
// or the '>', depending on whether we have too many or too few
// arguments.
SourceRange Range;
if (NumArgs > NumParams)
Range = SourceRange(TemplateArgs[NumParams].getLocation(), RAngleLoc);
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
<< (NumArgs > NumParams)
<< (isa<ClassTemplateDecl>(Template)? 0 :
isa<FunctionTemplateDecl>(Template)? 1 :
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
<< Template << Range;
Diag(Template->getLocation(), diag::note_template_decl_here)
<< Params->getSourceRange();
Invalid = true;
}
// C++ [temp.arg]p1:
// [...] The type and form of each template-argument specified in
// a template-id shall match the type and form specified for the
// corresponding parameter declared by the template in its
// template-parameter-list.
unsigned ArgIdx = 0;
for (TemplateParameterList::iterator Param = Params->begin(),
ParamEnd = Params->end();
Param != ParamEnd; ++Param, ++ArgIdx) {
// Decode the template argument
TemplateArgument Arg;
if (ArgIdx >= NumArgs) {
// Retrieve the default template argument from the template
// parameter.
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
if (!TTP->hasDefaultArgument())
break;
QualType ArgType = TTP->getDefaultArgument();
Douglas Gregor
committed
// If the argument type is dependent, instantiate it now based
// on the previously-computed template arguments.
if (ArgType->isDependentType()) {
InstantiatingTemplate Inst(*this, TemplateLoc,
Template, &Converted[0],
Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
Douglas Gregor
committed
ArgType = InstantiateType(ArgType, &Converted[0], Converted.size(),
TTP->getDefaultArgumentLoc(),
TTP->getDeclName());
Douglas Gregor
committed
if (ArgType.isNull())
return true;