blob: d300f283b66da37c0eded48b74def8cef9ac6603 [file] [log] [blame]
Douglas Gregordd861062008-12-05 18:15:24 +00001//===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===/
2
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//+//===----------------------------------------------------------------------===/
9
10//
11// This file implements semantic analysis for C++ templates.
12//+//===----------------------------------------------------------------------===/
13
14#include "Sema.h"
Douglas Gregor1b21c7f2008-12-05 23:32:09 +000015#include "clang/AST/Expr.h"
Douglas Gregordd861062008-12-05 18:15:24 +000016#include "clang/Parse/DeclSpec.h"
17#include "clang/Basic/LangOptions.h"
18
19using namespace clang;
20
Douglas Gregor2fa10442008-12-18 19:37:40 +000021/// isTemplateName - Determines whether the identifier II is a
22/// template name in the current scope, and returns the template
23/// declaration if II names a template. An optional CXXScope can be
24/// passed to indicate the C++ scope in which the identifier will be
25/// found.
26Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S,
27 const CXXScopeSpec *SS) {
28 DeclContext *DC = 0;
29 if (SS) {
30 if (SS->isInvalid())
31 return 0;
32 DC = static_cast<DeclContext*>(SS->getScopeRep());
33 }
34 Decl *IIDecl = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC, false);
35
36 if (IIDecl) {
37 // FIXME: We need to represent templates via some kind of
38 // TemplateDecl, because what follows is a hack that only works in
39 // one specific case.
40 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) {
41 if (FD->getType()->isDependentType())
42 return FD;
43 } else if (OverloadedFunctionDecl *Ovl
44 = dyn_cast<OverloadedFunctionDecl>(IIDecl)) {
45 for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
46 FEnd = Ovl->function_end();
47 F != FEnd; ++F) {
48 if ((*F)->getType()->isDependentType())
49 return Ovl;
50 }
51 }
52 return 0;
53 }
54 return 0;
55}
56
Douglas Gregordd861062008-12-05 18:15:24 +000057/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
58/// that the template parameter 'PrevDecl' is being shadowed by a new
59/// declaration at location Loc. Returns true to indicate that this is
60/// an error, and false otherwise.
61bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
Douglas Gregor2715a1f2008-12-08 18:40:42 +000062 assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
Douglas Gregordd861062008-12-05 18:15:24 +000063
64 // Microsoft Visual C++ permits template parameters to be shadowed.
65 if (getLangOptions().Microsoft)
66 return false;
67
68 // C++ [temp.local]p4:
69 // A template-parameter shall not be redeclared within its
70 // scope (including nested scopes).
71 Diag(Loc, diag::err_template_param_shadow)
72 << cast<NamedDecl>(PrevDecl)->getDeclName();
73 Diag(PrevDecl->getLocation(), diag::note_template_param_here);
74 return true;
75}
76
77/// ActOnTypeParameter - Called when a C++ template type parameter
78/// (e.g., "typename T") has been parsed. Typename specifies whether
79/// the keyword "typename" was used to declare the type parameter
80/// (otherwise, "class" was used), and KeyLoc is the location of the
81/// "class" or "typename" keyword. ParamName is the name of the
82/// parameter (NULL indicates an unnamed template parameter) and
83/// ParamName is the location of the parameter name (if any).
84/// If the type parameter has a default argument, it will be added
85/// later via ActOnTypeParameterDefault.
86Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
87 SourceLocation KeyLoc,
88 IdentifierInfo *ParamName,
89 SourceLocation ParamNameLoc) {
90 assert(S->isTemplateParamScope() &&
91 "Template type parameter not in template parameter scope!");
92 bool Invalid = false;
93
94 if (ParamName) {
95 Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
Douglas Gregor2715a1f2008-12-08 18:40:42 +000096 if (PrevDecl && PrevDecl->isTemplateParameter())
Douglas Gregordd861062008-12-05 18:15:24 +000097 Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
98 PrevDecl);
99 }
100
101 TemplateTypeParmDecl *Param
102 = TemplateTypeParmDecl::Create(Context, CurContext,
103 ParamNameLoc, ParamName, Typename);
104 if (Invalid)
105 Param->setInvalidDecl();
106
107 if (ParamName) {
108 // Add the template parameter into the current scope.
109 S->AddDecl(Param);
110 IdResolver.AddDecl(Param);
111 }
112
113 return Param;
114}
115
116/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
117/// template parameter (e.g., "int Size" in "template<int Size>
118/// class Array") has been parsed. S is the current scope and D is
119/// the parsed declarator.
120Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D) {
121 QualType T = GetTypeForDeclarator(D, S);
122
123 assert(S->isTemplateParamScope() &&
124 "Template type parameter not in template parameter scope!");
125 bool Invalid = false;
126
127 IdentifierInfo *ParamName = D.getIdentifier();
128 if (ParamName) {
129 Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
Douglas Gregor2715a1f2008-12-08 18:40:42 +0000130 if (PrevDecl && PrevDecl->isTemplateParameter())
Douglas Gregordd861062008-12-05 18:15:24 +0000131 Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
132 PrevDecl);
133 }
134
135 NonTypeTemplateParmDecl *Param
136 = NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
137 ParamName, T);
138 if (Invalid)
139 Param->setInvalidDecl();
140
141 if (D.getIdentifier()) {
142 // Add the template parameter into the current scope.
143 S->AddDecl(Param);
144 IdResolver.AddDecl(Param);
145 }
146 return Param;
147}