Testing and some minor fixes for explicit template instantiation.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84129 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 85b4fd6..e028186 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -233,9 +233,9 @@
 }
 
 MemberSpecializationInfo *
-ASTContext::getInstantiatedFromStaticDataMember(VarDecl *Var) {
+ASTContext::getInstantiatedFromStaticDataMember(const VarDecl *Var) {
   assert(Var->isStaticDataMember() && "Not a static data member");
-  llvm::DenseMap<VarDecl *, MemberSpecializationInfo *>::iterator Pos
+  llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>::iterator Pos
     = InstantiatedFromStaticDataMember.find(Var);
   if (Pos == InstantiatedFromStaticDataMember.end())
     return 0;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 429729e..a908299 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -380,7 +380,7 @@
   return 0;
 }
 
-TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() {
+TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
   if (MemberSpecializationInfo *MSI
         = getASTContext().getInstantiatedFromStaticDataMember(this))
     return MSI->getTemplateSpecializationKind();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index acb2a67..419c8a1 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1836,7 +1836,7 @@
   if (RD->isAbstract())
     AbstractClassUsageDiagnoser(*this, RD);
 
-  if (!RD->isDependentType())
+  if (!RD->isDependentType() && !RD->isInvalidDecl())
     AddImplicitlyDeclaredMembersToClass(RD);
 }
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index d56b4e1..457b219 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3647,6 +3647,19 @@
     return true;
   }
 
+  // C++0x [temp.explicit]p1:
+  //   [...] An explicit instantiation of a function template shall not use the
+  //   inline or constexpr specifiers.
+  // Presumably, this also applies to member functions of class templates as
+  // well.
+  if (D.getDeclSpec().isInlineSpecified() && getLangOptions().CPlusPlus0x)
+    Diag(D.getDeclSpec().getInlineSpecLoc(), 
+         diag::err_explicit_instantiation_inline)
+      << CodeModificationHint::CreateRemoval(
+                              SourceRange(D.getDeclSpec().getInlineSpecLoc()));
+  
+  // FIXME: check for constexpr specifier.
+  
   // Determine what kind of explicit instantiation we have.
   TemplateSpecializationKind TSK
     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 65260c8..24b8370 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -808,9 +808,12 @@
   ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
               Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
               0);
-
+  if (Instantiation->isInvalidDecl())
+    Invalid = true;
+  
   // Add any implicitly-declared members that we might need.
-  AddImplicitlyDeclaredMembersToClass(Instantiation);
+  if (!Invalid)
+    AddImplicitlyDeclaredMembersToClass(Instantiation);
 
   // Exit the scope of this instantiation.
   CurContext = PreviousContext;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 33fa288..28c0fa6 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -246,8 +246,10 @@
                                             D->getTypeSpecStartLoc(),
                                             D->getAccess(),
                                             0);
-  if (!Field)
+  if (!Field) {
+    cast<Decl>(Owner)->setInvalidDecl();
     return 0;
+  }
 
   if (Invalid)
     Field->setInvalidDecl();