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();