blob: 2dcb9fe3361c4d1bdc34298332017a9d2f20eb83 [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 Gregordd861062008-12-05 18:15:24 +000021/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
22/// that the template parameter 'PrevDecl' is being shadowed by a new
23/// declaration at location Loc. Returns true to indicate that this is
24/// an error, and false otherwise.
25bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
Douglas Gregor2715a1f2008-12-08 18:40:42 +000026 assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
Douglas Gregordd861062008-12-05 18:15:24 +000027
28 // Microsoft Visual C++ permits template parameters to be shadowed.
29 if (getLangOptions().Microsoft)
30 return false;
31
32 // C++ [temp.local]p4:
33 // A template-parameter shall not be redeclared within its
34 // scope (including nested scopes).
35 Diag(Loc, diag::err_template_param_shadow)
36 << cast<NamedDecl>(PrevDecl)->getDeclName();
37 Diag(PrevDecl->getLocation(), diag::note_template_param_here);
38 return true;
39}
40
41/// ActOnTypeParameter - Called when a C++ template type parameter
42/// (e.g., "typename T") has been parsed. Typename specifies whether
43/// the keyword "typename" was used to declare the type parameter
44/// (otherwise, "class" was used), and KeyLoc is the location of the
45/// "class" or "typename" keyword. ParamName is the name of the
46/// parameter (NULL indicates an unnamed template parameter) and
47/// ParamName is the location of the parameter name (if any).
48/// If the type parameter has a default argument, it will be added
49/// later via ActOnTypeParameterDefault.
50Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
51 SourceLocation KeyLoc,
52 IdentifierInfo *ParamName,
53 SourceLocation ParamNameLoc) {
54 assert(S->isTemplateParamScope() &&
55 "Template type parameter not in template parameter scope!");
56 bool Invalid = false;
57
58 if (ParamName) {
59 Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
Douglas Gregor2715a1f2008-12-08 18:40:42 +000060 if (PrevDecl && PrevDecl->isTemplateParameter())
Douglas Gregordd861062008-12-05 18:15:24 +000061 Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
62 PrevDecl);
63 }
64
65 TemplateTypeParmDecl *Param
66 = TemplateTypeParmDecl::Create(Context, CurContext,
67 ParamNameLoc, ParamName, Typename);
68 if (Invalid)
69 Param->setInvalidDecl();
70
71 if (ParamName) {
72 // Add the template parameter into the current scope.
73 S->AddDecl(Param);
74 IdResolver.AddDecl(Param);
75 }
76
77 return Param;
78}
79
80/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
81/// template parameter (e.g., "int Size" in "template<int Size>
82/// class Array") has been parsed. S is the current scope and D is
83/// the parsed declarator.
84Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D) {
85 QualType T = GetTypeForDeclarator(D, S);
86
87 assert(S->isTemplateParamScope() &&
88 "Template type parameter not in template parameter scope!");
89 bool Invalid = false;
90
91 IdentifierInfo *ParamName = D.getIdentifier();
92 if (ParamName) {
93 Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
Douglas Gregor2715a1f2008-12-08 18:40:42 +000094 if (PrevDecl && PrevDecl->isTemplateParameter())
Douglas Gregordd861062008-12-05 18:15:24 +000095 Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
96 PrevDecl);
97 }
98
99 NonTypeTemplateParmDecl *Param
100 = NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
101 ParamName, T);
102 if (Invalid)
103 Param->setInvalidDecl();
104
105 if (D.getIdentifier()) {
106 // Add the template parameter into the current scope.
107 S->AddDecl(Param);
108 IdResolver.AddDecl(Param);
109 }
110 return Param;
111}