//===------- 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. //===----------------------------------------------------------------------===/ // // This file implements semantic analysis for C++ templates. //===----------------------------------------------------------------------===/ #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(IdentifierInfo &II, Scope *S, DeclTy *&Template, const CXXScopeSpec *SS) { NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName); if (IIDecl) { if (isa(IIDecl)) { Template = IIDecl; if (isa(IIDecl)) return TNK_Function_template; else if (isa(IIDecl)) return TNK_Class_template; else if (isa(IIDecl)) return TNK_Template_template_parm; else assert(false && "Unknown TemplateDecl"); } // FIXME: What follows is a gross hack. if (FunctionDecl *FD = dyn_cast(IIDecl)) { if (FD->getType()->isDependentType()) { Template = FD; return TNK_Function_template; } } else if (OverloadedFunctionDecl *Ovl = dyn_cast(IIDecl)) { for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), FEnd = Ovl->function_end(); F != FEnd; ++F) { if ((*F)->getType()->isDependentType()) { Template = Ovl; return TNK_Function_template; } } } } return TNK_Non_template; } /// 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) { 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(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. TemplateDecl *Sema::AdjustDeclIfTemplate(DeclTy *&D) { if(TemplateDecl *Temp = dyn_cast(static_cast(D))) { D = 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. Sema::DeclTy *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); 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. S->AddDecl(Param); IdResolver.AddDecl(Param); } return Param; } /// ActOnTypeParameterDefault - Adds a default argument (the type /// Default) to the given template type parameter (TypeParam). void Sema::ActOnTypeParameterDefault(DeclTy *TypeParam, SourceLocation EqualLoc, SourceLocation DefaultLoc, TypeTy *DefaultT) { TemplateTypeParmDecl *Parm = cast(static_cast(TypeParam)); 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 /// class Array") has been parsed. S is the current scope and D is /// the parsed declarator. Sema::DeclTy *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()); if (T.isNull()) { T = Context.IntTy; // Recover with an 'int' type. 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. S->AddDecl(Param); IdResolver.AddDecl(Param); } return Param; } /// \brief Adds a default argument to the given non-type template /// parameter. void Sema::ActOnNonTypeTemplateParameterDefault(DeclTy *TemplateParamD, SourceLocation EqualLoc, ExprArg DefaultE) { NonTypeTemplateParmDecl *TemplateParm = cast(static_cast(TemplateParamD)); Expr *Default = static_cast(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(DefaultE.release())); } /// ActOnTemplateTemplateParameter - Called when a C++ template template /// parameter (e.g. T in template