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/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e1b56ad..7c8b4b1 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -943,6 +943,8 @@
   
   if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
     return getTypedefType(Typedef);
+  else if (TemplateTypeParmDecl *TP = dyn_cast<TemplateTypeParmDecl>(Decl))
+    return getTemplateTypeParmType(TP);
   else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast<ObjCInterfaceDecl>(Decl))
     return getObjCInterfaceType(ObjCInterface);
 
@@ -982,6 +984,16 @@
   return QualType(Decl->TypeForDecl, 0);
 }
 
+/// getTemplateTypeParmType - Return the unique reference to the type
+/// for the specified template type parameter declaration. 
+QualType ASTContext::getTemplateTypeParmType(TemplateTypeParmDecl *Decl) {
+  if (!Decl->TypeForDecl) {
+    Decl->TypeForDecl = new TemplateTypeParmType(Decl);
+    Types.push_back(Decl->TypeForDecl);
+  }
+  return QualType(Decl->TypeForDecl, 0);
+}
+
 /// getObjCInterfaceType - Return the unique reference to the type for the
 /// specified ObjC interface decl.
 QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 5cb2a3e..7b5df1c 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -239,6 +239,8 @@
   case CXXField:            nCXXFieldDecls++; break;
   case CXXRecord:           nCXXSUC++; break;
   // FIXME: Statistics for C++ decls.
+  case TemplateTypeParm:
+  case NonTypeTemplateParm:
   case CXXMethod:
   case CXXConstructor:
   case CXXDestructor:
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 6be9eaf..a26803c 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -19,7 +19,23 @@
 //===----------------------------------------------------------------------===//
 // Decl Allocation/Deallocation Method Implementations
 //===----------------------------------------------------------------------===//
- 
+
+TemplateTypeParmDecl *
+TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
+			     SourceLocation L, IdentifierInfo *Id,
+			     bool Typename) {
+  void *Mem = C.getAllocator().Allocate<TemplateTypeParmDecl>();
+  return new (Mem) TemplateTypeParmDecl(DC, L, Id, Typename);
+}
+
+NonTypeTemplateParmDecl *
+NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, 
+				SourceLocation L, IdentifierInfo *Id,
+				QualType T, SourceLocation TypeSpecStartLoc) {
+  void *Mem = C.getAllocator().Allocate<NonTypeTemplateParmDecl>();
+  return new (Mem) NonTypeTemplateParmDecl(DC, L, Id, T, TypeSpecStartLoc);
+}
+
 CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                                    SourceLocation L, IdentifierInfo *Id,
                                    QualType T, bool Mut, Expr *BW) {
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index 8a4612b..29714c0 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -88,6 +88,10 @@
       Dcl = TypedefDecl::CreateImpl(D, C);
       break;
       
+    case TemplateTypeParm:
+      Dcl = TemplateTypeParmDecl::CreateImpl(D, C);
+      break;
+
     case FileScopeAsm:
       Dcl = FileScopeAsmDecl::CreateImpl(D, C);
       break;
@@ -630,6 +634,27 @@
 }
 
 //===----------------------------------------------------------------------===//
+//      TemplateTypeParmDecl Serialization.
+//===----------------------------------------------------------------------===//
+
+void TemplateTypeParmDecl::EmitImpl(Serializer& S) const {
+  S.EmitBool(Typename);
+  ScopedDecl::EmitInRec(S);
+  ScopedDecl::EmitOutRec(S);
+}
+
+TemplateTypeParmDecl *
+TemplateTypeParmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
+  bool Typename = D.ReadBool();
+  void *Mem = C.getAllocator().Allocate<TemplateTypeParmDecl>();
+  TemplateTypeParmDecl *decl
+    = new (Mem) TemplateTypeParmDecl(0, SourceLocation(), NULL, Typename);
+  decl->ScopedDecl::ReadInRec(D, C);
+  decl->ScopedDecl::ReadOutRec(D, C);
+  return decl;
+}
+
+//===----------------------------------------------------------------------===//
 //      LinkageSpec Serialization.
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index e4386ec..a3264b0 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -341,6 +341,12 @@
 /// DeclCanBeLvalue - Determine whether the given declaration can be
 /// an lvalue. This is a helper routine for isLvalue.
 static bool DeclCanBeLvalue(const NamedDecl *Decl, ASTContext &Ctx) {
+  // C++ [temp.param]p6:
+  //   A non-type non-reference template-parameter is not an lvalue.
+  if (const NonTypeTemplateParmDecl *NTTParm 
+        = dyn_cast<NonTypeTemplateParmDecl>(Decl))
+    return NTTParm->getType()->isReferenceType();
+
   return isa<VarDecl>(Decl) || isa<CXXFieldDecl>(Decl) ||
     // C++ 3.10p2: An lvalue refers to an object or function.
     (Ctx.getLangOptions().CPlusPlus &&
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 6aa3c8e..303fc7e 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -443,6 +443,11 @@
   return dyn_cast<ObjCQualifiedIdType>(CanonicalType);
 }
 
+const TemplateTypeParmType *Type::getAsTemplateTypeParmType() const {
+  // There is no sugar for template type parameters, so just return
+  // the canonical type pointer if it is the right class.
+  return dyn_cast<TemplateTypeParmType>(CanonicalType);
+}
 
 bool Type::isIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
@@ -1002,6 +1007,12 @@
   InnerString = getDecl()->getIdentifier()->getName() + InnerString;
 }
 
+void TemplateTypeParmType::getAsStringInternal(std::string &InnerString) const {
+  if (!InnerString.empty())    // Prefix the basic type, e.g. 'parmname X'.
+    InnerString = ' ' + InnerString;
+  InnerString = getDecl()->getIdentifier()->getName() + InnerString;
+}
+
 void ObjCInterfaceType::getAsStringInternal(std::string &InnerString) const {
   if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
     InnerString = ' ' + InnerString;
diff --git a/lib/AST/TypeSerialization.cpp b/lib/AST/TypeSerialization.cpp
index db93e4b..3bdc946 100644
--- a/lib/AST/TypeSerialization.cpp
+++ b/lib/AST/TypeSerialization.cpp
@@ -110,6 +110,10 @@
       D.RegisterPtr(PtrID,TypedefType::CreateImpl(Context,D));
       break;
       
+    case Type::TemplateTypeParm:
+      D.RegisterPtr(PtrID,TemplateTypeParmType::CreateImpl(Context, D));
+      break;
+
     case Type::VariableArray:
       D.RegisterPtr(PtrID,VariableArrayType::CreateImpl(Context,D));
       break;
@@ -272,6 +276,25 @@
 }
   
 //===----------------------------------------------------------------------===//
+// TemplateTypeParmType
+//===----------------------------------------------------------------------===//
+
+void TemplateTypeParmType::EmitImpl(Serializer& S) const {
+  S.EmitPtr(getDecl());
+}
+
+Type* TemplateTypeParmType::CreateImpl(ASTContext& Context, Deserializer& D) {
+  std::vector<Type*>& Types = 
+    const_cast<std::vector<Type*>&>(Context.getTypes());
+  
+  TemplateTypeParmType* T = new TemplateTypeParmType(NULL);
+  Types.push_back(T);
+  
+  D.ReadPtr(T->Decl); // May be backpatched.
+  return T;
+}
+  
+//===----------------------------------------------------------------------===//
 // VariableArrayType
 //===----------------------------------------------------------------------===//