Implement basic template instantiation for fields. Reshuffle checking
for FieldDecls so that the parser and the template instantiation make
use of the same semantic checking module.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66685 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index d630e80..5800ab9 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -664,7 +664,7 @@
   // instantiation. Should this be a typedef or something like it?
 
   RecordDecl *Pattern = Template->getTemplatedDecl();
-
+  llvm::SmallVector<DeclTy *, 32> Fields;
   for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
                               MemberEnd = Pattern->decls_end();
        Member != MemberEnd; ++Member) {
@@ -690,18 +690,53 @@
                               Typedef->getIdentifier(),
                               T);
       ClassTemplateSpec->addDecl(New);
+    } 
+    else if (FieldDecl *Field = dyn_cast<FieldDecl>(*Member)) {
+      // FIXME: Simplified instantiation of fields needs to be made
+      // "real".
+      QualType T = Field->getType();
+      if (T->isDependentType())  {
+        T = InstantiateType(T, ClassTemplateSpec->getTemplateArgs(),
+                            ClassTemplateSpec->getNumTemplateArgs(),
+                            Field->getLocation(),
+                            Field->getDeclName());
+        if (!T.isNull() && T->isFunctionType()) {
+          // C++ [temp.arg.type]p3:
+          //   If a declaration acquires a function type through a type
+          //   dependent on a template-parameter and this causes a
+          //   declaration that does not use the syntactic form of a
+          //   function declarator to have function type, the program is
+          //   ill-formed.
+          Diag(Field->getLocation(), diag::err_field_instantiates_to_function) 
+            << T;
+          T = QualType();
+        }
+      }
+
+      FieldDecl *New = CheckFieldDecl(Field->getDeclName(), T,
+                                      ClassTemplateSpec, 
+                                      Field->getLocation(),
+                                      Field->isMutable(),
+                                      Field->getBitWidth(),
+                                      0);
+      if (New) {
+        ClassTemplateSpec->addDecl(New);
+        Fields.push_back(New);
+
+        if (New->isInvalidDecl())
+          Invalid = true;
+      }
     }
   }
 
-  // FIXME: Instantiate all of the members.
-  
+  // Finish checking fields.
+  ActOnFields(0, ClassTemplateSpec->getLocation(), ClassTemplateSpec,
+              &Fields[0], Fields.size(), SourceLocation(), SourceLocation(),
+              0);
+
   // Add any implicitly-declared members that we might need.
   AddImplicitlyDeclaredMembersToClass(ClassTemplateSpec);
 
-  // Finish the definition of this instantiation.
-  // FIXME: ActOnFields does more checking, which we'll eventually need.
-  ClassTemplateSpec->completeDefinition(Context);
-
   // Exit the scope of this instantiation.
   CurContext = PreviousContext;