SemaTemplate.cpp revision 47b9a1ca55e61e37f5a368740e29de190345acc6
1//===------- 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"
15#include "clang/AST/Expr.h"
16#include "clang/Parse/DeclSpec.h"
17#include "clang/Basic/LangOptions.h"
18
19using namespace clang;
20
21/// 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
30  if (SS) {
31    if (SS->isInvalid())
32      return 0;
33    DC = static_cast<DeclContext*>(SS->getScopeRep());
34  }
35  NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
36
37  if (IIDecl) {
38    // FIXME: We need to represent templates via some kind of
39    // TemplateDecl, because what follows is a hack that only works in
40    // one specific case.
41    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) {
42      if (FD->getType()->isDependentType())
43        return FD;
44    } else if (OverloadedFunctionDecl *Ovl
45                 = dyn_cast<OverloadedFunctionDecl>(IIDecl)) {
46      for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
47                                                  FEnd = Ovl->function_end();
48           F != FEnd; ++F) {
49        if ((*F)->getType()->isDependentType())
50          return Ovl;
51      }
52    }
53    return 0;
54  }
55  return 0;
56}
57
58/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
59/// that the template parameter 'PrevDecl' is being shadowed by a new
60/// declaration at location Loc. Returns true to indicate that this is
61/// an error, and false otherwise.
62bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
63  assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
64
65  // Microsoft Visual C++ permits template parameters to be shadowed.
66  if (getLangOptions().Microsoft)
67    return false;
68
69  // C++ [temp.local]p4:
70  //   A template-parameter shall not be redeclared within its
71  //   scope (including nested scopes).
72  Diag(Loc, diag::err_template_param_shadow)
73    << cast<NamedDecl>(PrevDecl)->getDeclName();
74  Diag(PrevDecl->getLocation(), diag::note_template_param_here);
75  return true;
76}
77
78/// ActOnTypeParameter - Called when a C++ template type parameter
79/// (e.g., "typename T") has been parsed. Typename specifies whether
80/// the keyword "typename" was used to declare the type parameter
81/// (otherwise, "class" was used), and KeyLoc is the location of the
82/// "class" or "typename" keyword. ParamName is the name of the
83/// parameter (NULL indicates an unnamed template parameter) and
84/// ParamName is the location of the parameter name (if any).
85/// If the type parameter has a default argument, it will be added
86/// later via ActOnTypeParameterDefault.
87Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
88				       SourceLocation KeyLoc,
89				       IdentifierInfo *ParamName,
90				       SourceLocation ParamNameLoc,
91                                       unsigned Depth, unsigned Position) {
92  assert(S->isTemplateParamScope() &&
93	 "Template type parameter not in template parameter scope!");
94  bool Invalid = false;
95
96  if (ParamName) {
97    NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
98    if (PrevDecl && PrevDecl->isTemplateParameter())
99      Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
100							   PrevDecl);
101  }
102
103  TemplateTypeParmDecl *Param
104    = TemplateTypeParmDecl::Create(Context, CurContext,
105				   ParamNameLoc, ParamName, Typename);
106  if (Invalid)
107    Param->setInvalidDecl();
108
109  if (ParamName) {
110    // Add the template parameter into the current scope.
111    S->AddDecl(Param);
112    IdResolver.AddDecl(Param);
113  }
114
115  return Param;
116}
117
118/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
119/// template parameter (e.g., "int Size" in "template<int Size>
120/// class Array") has been parsed. S is the current scope and D is
121/// the parsed declarator.
122Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
123                                                  unsigned Depth,
124                                                  unsigned Position) {
125  QualType T = GetTypeForDeclarator(D, S);
126
127  assert(S->isTemplateParamScope() &&
128	 "Template type parameter not in template parameter scope!");
129  bool Invalid = false;
130
131  IdentifierInfo *ParamName = D.getIdentifier();
132  if (ParamName) {
133    NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
134    if (PrevDecl && PrevDecl->isTemplateParameter())
135      Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
136							   PrevDecl);
137  }
138
139  NonTypeTemplateParmDecl *Param
140    = NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
141				      ParamName, T);
142  if (Invalid)
143    Param->setInvalidDecl();
144
145  if (D.getIdentifier()) {
146    // Add the template parameter into the current scope.
147    S->AddDecl(Param);
148    IdResolver.AddDecl(Param);
149  }
150  return Param;
151}
152
153/// ActOnTemplateParameterList - Builds a TemplateParameterList that
154/// contains the template parameters in Params/NumParams.
155Sema::TemplateParamsTy *
156Sema::ActOnTemplateParameterList(unsigned Depth,
157                                 SourceLocation ExportLoc,
158                                 SourceLocation TemplateLoc,
159                                 SourceLocation LAngleLoc,
160                                 DeclTy **Params, unsigned NumParams,
161                                 SourceLocation RAngleLoc) {
162  if (ExportLoc.isValid())
163    Diag(ExportLoc, diag::note_template_export_unsupported);
164
165  return TemplateParameterList::Create(Context, (Decl**)Params, NumParams);
166}
167