blob: e15343a042f5788131d00bc502eff14a6637495e [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 Gregor279272e2009-02-04 19:02:06 +000016#include "clang/AST/DeclTemplate.h"
Douglas Gregordd861062008-12-05 18:15:24 +000017#include "clang/Parse/DeclSpec.h"
18#include "clang/Basic/LangOptions.h"
19
20using namespace clang;
21
Douglas Gregor2fa10442008-12-18 19:37:40 +000022/// isTemplateName - Determines whether the identifier II is a
23/// template name in the current scope, and returns the template
24/// declaration if II names a template. An optional CXXScope can be
25/// passed to indicate the C++ scope in which the identifier will be
26/// found.
27Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S,
28 const CXXScopeSpec *SS) {
29 DeclContext *DC = 0;
Steve Naroffc349ee22009-01-29 00:07:50 +000030
Douglas Gregor2fa10442008-12-18 19:37:40 +000031 if (SS) {
32 if (SS->isInvalid())
33 return 0;
34 DC = static_cast<DeclContext*>(SS->getScopeRep());
35 }
Douglas Gregor09be81b2009-02-04 17:27:36 +000036 NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
Douglas Gregor2fa10442008-12-18 19:37:40 +000037
38 if (IIDecl) {
39 // FIXME: We need to represent templates via some kind of
40 // TemplateDecl, because what follows is a hack that only works in
41 // one specific case.
Douglas Gregor279272e2009-02-04 19:02:06 +000042 if (isa<TemplateDecl>(IIDecl))
43 return IIDecl;
44
Douglas Gregor2fa10442008-12-18 19:37:40 +000045 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) {
46 if (FD->getType()->isDependentType())
47 return FD;
48 } else if (OverloadedFunctionDecl *Ovl
49 = dyn_cast<OverloadedFunctionDecl>(IIDecl)) {
50 for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
51 FEnd = Ovl->function_end();
52 F != FEnd; ++F) {
53 if ((*F)->getType()->isDependentType())
54 return Ovl;
55 }
56 }
Douglas Gregor2fa10442008-12-18 19:37:40 +000057 }
58 return 0;
59}
60
Douglas Gregordd861062008-12-05 18:15:24 +000061/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
62/// that the template parameter 'PrevDecl' is being shadowed by a new
63/// declaration at location Loc. Returns true to indicate that this is
64/// an error, and false otherwise.
65bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
Douglas Gregor2715a1f2008-12-08 18:40:42 +000066 assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
Douglas Gregordd861062008-12-05 18:15:24 +000067
68 // Microsoft Visual C++ permits template parameters to be shadowed.
69 if (getLangOptions().Microsoft)
70 return false;
71
72 // C++ [temp.local]p4:
73 // A template-parameter shall not be redeclared within its
74 // scope (including nested scopes).
75 Diag(Loc, diag::err_template_param_shadow)
76 << cast<NamedDecl>(PrevDecl)->getDeclName();
77 Diag(PrevDecl->getLocation(), diag::note_template_param_here);
78 return true;
79}
80
Douglas Gregor279272e2009-02-04 19:02:06 +000081/// AdjustDeclForTemplates - If the given decl happens to be a template, reset
82/// the parameter D to reference the templated declaration and return a pointer
83/// to the template declaration. Otherwise, do nothing to D and return null.
84TemplateDecl *Sema::AdjustDeclIfTemplate(DeclTy *&D)
85{
86 if(TemplateDecl *Temp = dyn_cast<TemplateDecl>(static_cast<Decl*>(D))) {
87 D = Temp->getTemplatedDecl();
88 return Temp;
89 }
90 return 0;
91}
92
Douglas Gregordd861062008-12-05 18:15:24 +000093/// ActOnTypeParameter - Called when a C++ template type parameter
94/// (e.g., "typename T") has been parsed. Typename specifies whether
95/// the keyword "typename" was used to declare the type parameter
96/// (otherwise, "class" was used), and KeyLoc is the location of the
97/// "class" or "typename" keyword. ParamName is the name of the
98/// parameter (NULL indicates an unnamed template parameter) and
99/// ParamName is the location of the parameter name (if any).
100/// If the type parameter has a default argument, it will be added
101/// later via ActOnTypeParameterDefault.
102Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
103 SourceLocation KeyLoc,
104 IdentifierInfo *ParamName,
Douglas Gregor52473432008-12-24 02:52:09 +0000105 SourceLocation ParamNameLoc,
106 unsigned Depth, unsigned Position) {
Douglas Gregordd861062008-12-05 18:15:24 +0000107 assert(S->isTemplateParamScope() &&
108 "Template type parameter not in template parameter scope!");
109 bool Invalid = false;
110
111 if (ParamName) {
Douglas Gregor09be81b2009-02-04 17:27:36 +0000112 NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
Douglas Gregor2715a1f2008-12-08 18:40:42 +0000113 if (PrevDecl && PrevDecl->isTemplateParameter())
Douglas Gregordd861062008-12-05 18:15:24 +0000114 Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
115 PrevDecl);
116 }
117
118 TemplateTypeParmDecl *Param
Douglas Gregor279272e2009-02-04 19:02:06 +0000119 = TemplateTypeParmDecl::Create(Context, CurContext, ParamNameLoc,
120 Depth, Position, ParamName, Typename);
Douglas Gregordd861062008-12-05 18:15:24 +0000121 if (Invalid)
122 Param->setInvalidDecl();
123
124 if (ParamName) {
125 // Add the template parameter into the current scope.
126 S->AddDecl(Param);
127 IdResolver.AddDecl(Param);
128 }
129
130 return Param;
131}
132
133/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
134/// template parameter (e.g., "int Size" in "template<int Size>
135/// class Array") has been parsed. S is the current scope and D is
136/// the parsed declarator.
Douglas Gregor52473432008-12-24 02:52:09 +0000137Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
138 unsigned Depth,
139 unsigned Position) {
Douglas Gregordd861062008-12-05 18:15:24 +0000140 QualType T = GetTypeForDeclarator(D, S);
141
Douglas Gregor279272e2009-02-04 19:02:06 +0000142 assert(S->isTemplateParamScope() &&
143 "Non-type template parameter not in template parameter scope!");
Douglas Gregordd861062008-12-05 18:15:24 +0000144 bool Invalid = false;
145
146 IdentifierInfo *ParamName = D.getIdentifier();
147 if (ParamName) {
Douglas Gregor09be81b2009-02-04 17:27:36 +0000148 NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
Douglas Gregor2715a1f2008-12-08 18:40:42 +0000149 if (PrevDecl && PrevDecl->isTemplateParameter())
Douglas Gregordd861062008-12-05 18:15:24 +0000150 Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
Douglas Gregor279272e2009-02-04 19:02:06 +0000151 PrevDecl);
Douglas Gregordd861062008-12-05 18:15:24 +0000152 }
153
154 NonTypeTemplateParmDecl *Param
155 = NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
Douglas Gregor279272e2009-02-04 19:02:06 +0000156 Depth, Position, ParamName, T);
Douglas Gregordd861062008-12-05 18:15:24 +0000157 if (Invalid)
158 Param->setInvalidDecl();
159
160 if (D.getIdentifier()) {
161 // Add the template parameter into the current scope.
162 S->AddDecl(Param);
163 IdResolver.AddDecl(Param);
164 }
165 return Param;
166}
Douglas Gregor52473432008-12-24 02:52:09 +0000167
Douglas Gregor279272e2009-02-04 19:02:06 +0000168
169/// ActOnTemplateTemplateParameter - Called when a C++ template template
170/// parameter (e.g. T in template <template <typename> class T> class array)
171/// has been parsed. S is the current scope.
172Sema::DeclTy *Sema::ActOnTemplateTemplateParameter(Scope* S,
173 SourceLocation TmpLoc,
174 TemplateParamsTy *Params,
175 IdentifierInfo *Name,
176 SourceLocation NameLoc,
177 unsigned Depth,
178 unsigned Position)
179{
180 assert(S->isTemplateParamScope() &&
181 "Template template parameter not in template parameter scope!");
182
183 // Construct the parameter object.
184 TemplateTemplateParmDecl *Param =
185 TemplateTemplateParmDecl::Create(Context, CurContext, TmpLoc, Depth,
186 Position, Name,
187 (TemplateParameterList*)Params);
188
189 // Make sure the parameter is valid.
190 // FIXME: Decl object is not currently invalidated anywhere so this doesn't
191 // do anything yet. However, if the template parameter list or (eventual)
192 // default value is ever invalidated, that will propagate here.
193 bool Invalid = false;
194 if (Invalid) {
195 Param->setInvalidDecl();
196 }
197
198 // If the tt-param has a name, then link the identifier into the scope
199 // and lookup mechanisms.
200 if (Name) {
201 S->AddDecl(Param);
202 IdResolver.AddDecl(Param);
203 }
204
205 return Param;
206}
207
Douglas Gregor52473432008-12-24 02:52:09 +0000208/// ActOnTemplateParameterList - Builds a TemplateParameterList that
209/// contains the template parameters in Params/NumParams.
210Sema::TemplateParamsTy *
211Sema::ActOnTemplateParameterList(unsigned Depth,
212 SourceLocation ExportLoc,
213 SourceLocation TemplateLoc,
214 SourceLocation LAngleLoc,
215 DeclTy **Params, unsigned NumParams,
216 SourceLocation RAngleLoc) {
217 if (ExportLoc.isValid())
218 Diag(ExportLoc, diag::note_template_export_unsupported);
219
220 return TemplateParameterList::Create(Context, (Decl**)Params, NumParams);
221}
Douglas Gregor279272e2009-02-04 19:02:06 +0000222