Representation of template type parameters and non-type template
parameters, with some semantic analysis:
  - Template parameters are introduced into template parameter scope
  - Complain about template parameter shadowing (except in Microsoft mode)

Note that we leak template parameter declarations like crazy, a
problem we'll remedy once we actually create proper declarations for
templates. 

Next up: dependent types and value-dependent/type-dependent
expressions.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60597 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
new file mode 100644
index 0000000..749d181
--- /dev/null
+++ b/lib/Sema/SemaTemplate.cpp
@@ -0,0 +1,116 @@
+//===------- 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/Parse/DeclSpec.h"
+#include "clang/Basic/LangOptions.h"
+
+using namespace clang;
+
+/// isTemplateParameterDecl - Determines whether the given declaration
+/// 'D' names a template parameter.
+bool Sema::isTemplateParameterDecl(Decl *D) {
+  return isa<TemplateTypeParmDecl>(D) || isa<NonTypeTemplateParmDecl>(D);
+}
+
+/// 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(isTemplateParameterDecl(PrevDecl) && "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<NamedDecl>(PrevDecl)->getDeclName();
+  Diag(PrevDecl->getLocation(), diag::note_template_param_here);
+  return true;
+}
+
+/// 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) {
+  assert(S->isTemplateParamScope() && 
+	 "Template type parameter not in template parameter scope!");
+  bool Invalid = false;
+
+  if (ParamName) {
+    Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
+    if (PrevDecl && isTemplateParameterDecl(PrevDecl))
+      Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
+							   PrevDecl);
+  }
+
+  TemplateTypeParmDecl *Param
+    = TemplateTypeParmDecl::Create(Context, CurContext, 
+				   ParamNameLoc, ParamName, Typename);
+  if (Invalid)
+    Param->setInvalidDecl();
+
+  if (ParamName) {
+    // Add the template parameter into the current scope.
+    S->AddDecl(Param);
+    IdResolver.AddDecl(Param);
+  }
+
+  return Param;
+}
+
+/// ActOnNonTypeTemplateParameter - Called when a C++ non-type
+/// template parameter (e.g., "int Size" in "template<int Size>
+/// class Array") has been parsed. S is the current scope and D is
+/// the parsed declarator.
+Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D) {
+  QualType T = GetTypeForDeclarator(D, S);
+
+  assert(S->isTemplateParamScope() && 
+	 "Template type parameter not in template parameter scope!");
+  bool Invalid = false;
+
+  IdentifierInfo *ParamName = D.getIdentifier();
+  if (ParamName) {
+    Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
+    if (PrevDecl && isTemplateParameterDecl(PrevDecl))
+      Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
+							   PrevDecl);
+  }
+
+  NonTypeTemplateParmDecl *Param
+    = NonTypeTemplateParmDecl::Create(Context, CurContext, D.getIdentifierLoc(),
+				      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;
+}