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.cpp172
1 files changed, 65 insertions, 107 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 7e5377ab9a..336a7bf9d0 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -459,7 +459,9 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
SourceLocation ParamNameLoc,
- unsigned Depth, unsigned Position) {
+ unsigned Depth, unsigned Position,
+ SourceLocation EqualLoc,
+ TypeTy *DefaultArg) {
assert(S->isTemplateParamScope() &&
"Template type parameter not in template parameter scope!");
bool Invalid = false;
@@ -490,42 +492,31 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
IdResolver.AddDecl(Param);
}
- return DeclPtrTy::make(Param);
-}
-
-/// ActOnTypeParameterDefault - Adds a default argument (the type
-/// Default) to the given template type parameter (TypeParam).
-void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
- SourceLocation EqualLoc,
- SourceLocation DefaultLoc,
- TypeTy *DefaultT) {
- TemplateTypeParmDecl *Parm
- = cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
-
- TypeSourceInfo *DefaultTInfo;
- GetTypeFromParser(DefaultT, &DefaultTInfo);
-
- assert(DefaultTInfo && "expected source information for type");
-
- // C++0x [temp.param]p9:
- // A default template-argument may be specified for any kind of
- // template-parameter that is not a template parameter pack.
- if (Parm->isParameterPack()) {
- Diag(DefaultLoc, diag::err_template_param_pack_default_arg);
- return;
- }
-
- // 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, DefaultTInfo)) {
- Parm->setInvalidDecl();
- return;
+ // Handle the default argument, if provided.
+ if (DefaultArg) {
+ TypeSourceInfo *DefaultTInfo;
+ GetTypeFromParser(DefaultArg, &DefaultTInfo);
+
+ assert(DefaultTInfo && "expected source information for type");
+
+ // C++0x [temp.param]p9:
+ // A default template-argument may be specified for any kind of
+ // template-parameter that is not a template parameter pack.
+ if (Ellipsis) {
+ Diag(EqualLoc, diag::err_template_param_pack_default_arg);
+ return DeclPtrTy::make(Param);
+ }
+
+ // Check the template argument itself.
+ if (CheckTemplateArgument(Param, DefaultTInfo)) {
+ Param->setInvalidDecl();
+ return DeclPtrTy::make(Param);;
+ }
+
+ Param->setDefaultArgument(DefaultTInfo, false);
}
-
- Parm->setDefaultArgument(DefaultTInfo, false);
+
+ return DeclPtrTy::make(Param);
}
/// \brief Check that the type of a non-type template parameter is
@@ -580,13 +571,11 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
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.
Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
unsigned Depth,
- unsigned Position) {
+ unsigned Position,
+ SourceLocation EqualLoc,
+ ExprArg DefaultArg) {
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType T = TInfo->getType();
@@ -622,34 +611,21 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
S->AddDecl(DeclPtrTy::make(Param));
IdResolver.AddDecl(Param);
}
- return DeclPtrTy::make(Param);
-}
-
-/// \brief Adds a default argument to the given non-type template
-/// parameter.
-void Sema::ActOnNonTypeTemplateParameterDefault(DeclPtrTy TemplateParamD,
- SourceLocation EqualLoc,
- ExprArg DefaultE) {
- NonTypeTemplateParmDecl *TemplateParm
- = 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.
- TemplateArgument Converted;
- if (CheckTemplateArgument(TemplateParm, TemplateParm->getType(), Default,
- Converted)) {
- TemplateParm->setInvalidDecl();
- return;
+
+ // Check the well-formedness of the default template argument, if provided.
+ if (Expr *Default = static_cast<Expr *>(DefaultArg.get())) {
+ TemplateArgument Converted;
+ if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) {
+ Param->setInvalidDecl();
+ return DeclPtrTy::make(Param);;
+ }
+
+ Param->setDefaultArgument(DefaultArg.takeAs<Expr>(), false);
}
-
- TemplateParm->setDefaultArgument(DefaultE.takeAs<Expr>(), false);
+
+ return DeclPtrTy::make(Param);
}
-
/// 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.
@@ -659,7 +635,9 @@ Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
IdentifierInfo *Name,
SourceLocation NameLoc,
unsigned Depth,
- unsigned Position) {
+ unsigned Position,
+ SourceLocation EqualLoc,
+ const ParsedTemplateArgument &Default) {
assert(S->isTemplateParamScope() &&
"Template template parameter not in template parameter scope!");
@@ -669,53 +647,33 @@ Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
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 the template template parameter has a name, then link the identifier
+ // into the scope and lookup mechanisms.
if (Name) {
S->AddDecl(DeclPtrTy::make(Param));
IdResolver.AddDecl(Param);
}
- return DeclPtrTy::make(Param);
-}
-
-/// \brief Adds a default argument to the given template template
-/// parameter.
-void Sema::ActOnTemplateTemplateParameterDefault(DeclPtrTy TemplateParamD,
- SourceLocation EqualLoc,
- const ParsedTemplateArgument &Default) {
- TemplateTemplateParmDecl *TemplateParm
- = cast<TemplateTemplateParmDecl>(TemplateParamD.getAs<Decl>());
-
- // 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 only that we have a template template argument. We don't want to
- // try to check well-formedness now, because our template template parameter
- // might have dependent types in its template parameters, which we wouldn't
- // be able to match now.
- //
- // If none of the template template parameter's template arguments mention
- // other template parameters, we could actually perform more checking here.
- // However, it isn't worth doing.
- TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default);
- if (DefaultArg.getArgument().getAsTemplate().isNull()) {
- Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template)
- << DefaultArg.getSourceRange();
- return;
+ if (!Default.isInvalid()) {
+ // Check only that we have a template template argument. We don't want to
+ // try to check well-formedness now, because our template template parameter
+ // might have dependent types in its template parameters, which we wouldn't
+ // be able to match now.
+ //
+ // If none of the template template parameter's template arguments mention
+ // other template parameters, we could actually perform more checking here.
+ // However, it isn't worth doing.
+ TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default);
+ if (DefaultArg.getArgument().getAsTemplate().isNull()) {
+ Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template)
+ << DefaultArg.getSourceRange();
+ return DeclPtrTy::make(Param);
+ }
+
+ Param->setDefaultArgument(DefaultArg, false);
}
- TemplateParm->setDefaultArgument(DefaultArg, false);
+ return DeclPtrTy::make(Param);
}
/// ActOnTemplateParameterList - Builds a TemplateParameterList that