Implement the basics of implicit instantiation of class templates, in
response to attempts to diagnose an "incomplete" type. This will force
us to use DiagnoseIncompleteType more regularly (rather than looking at
isIncompleteType), but that's also a good thing.
Implicit instantiation is still very simplistic, and will create a new
definition for the class template specialization (as it should) but it
only actually instantiates the base classes and attaches
those. Actually instantiating class members will follow.
Also, instantiate the types of non-type template parameters before
checking them, allowing, e.g.,
template<typename T, T Value> struct Constant;
to work properly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65924 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 69cd884..96d17be 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -14,6 +14,7 @@
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/Parse/DeclSpec.h"
using namespace clang;
@@ -473,7 +474,7 @@
/// This routine checks the function type according to C++ rules and
/// under the assumption that the result type and parameter types have
/// just been instantiated from a template. It therefore duplicates
-/// some of the behavior of GetTypeForDeclaration, but in a much
+/// some of the behavior of GetTypeForDeclarator, but in a much
/// simpler form that is only suitable for this narrow use case.
///
/// \param T The return type of the function.
@@ -1033,6 +1034,21 @@
if (!T->isIncompleteType())
return false;
+ // If we have a class template specialization, try to instantiate
+ // it.
+ if (const RecordType *Record = T->getAsRecordType())
+ if (ClassTemplateSpecializationDecl *ClassTemplateSpec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl()))
+ if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
+ // Update the class template specialization's location to
+ // refer to the point of instantiation.
+ if (Loc.isValid())
+ ClassTemplateSpec->setLocation(Loc);
+ return InstantiateClassTemplateSpecialization(ClassTemplateSpec,
+ /*ExplicitInstantiation=*/false);
+ }
+
+
if (PrintType.isNull())
PrintType = T;