[cfe-commits] r71713 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/temp_explicit.cpp
Douglas Gregor
dgregor at apple.com
Wed May 13 13:28:36 PDT 2009
Author: dgregor
Date: Wed May 13 15:28:22 2009
New Revision: 71713
URL: http://llvm.org/viewvc/llvm-project?rev=71713&view=rev
Log:
Explicit instantiations of templates now instantiate the definitions
of class members (recursively). Only member classes are actually
instantiated; the instantiation logic for member functions and
variables are just stubs.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/temp_explicit.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=71713&r1=71712&r2=71713&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed May 13 15:28:22 2009
@@ -2116,6 +2116,14 @@
ClassTemplateSpecializationDecl *ClassTemplateSpec,
bool ExplicitInstantiation);
+ void InstantiateClassMembers(SourceLocation PointOfInstantiation,
+ CXXRecordDecl *Instantiation,
+ const TemplateArgumentList &TemplateArgs);
+
+ void InstantiateClassTemplateSpecializationMembers(
+ SourceLocation PointOfInstantiation,
+ ClassTemplateSpecializationDecl *ClassTemplateSpec);
+
NestedNameSpecifier *
InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range,
@@ -2125,6 +2133,9 @@
InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
const TemplateArgumentList &TemplateArgs);
+ void InstantiateFunctionDefinition(FunctionDecl *Function);
+ void InstantiateVariableDefinition(VarDecl *Var);
+
// Simple function for cloning expressions.
template<typename T>
OwningExprResult Clone(T *E) {
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=71713&r1=71712&r2=71713&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed May 13 15:28:22 2009
@@ -2335,9 +2335,10 @@
InstantiateClassTemplateSpecialization(Specialization, true))
return true;
- // FIXME: Instantiate all of the members of the template (that
- // haven't already been instantiated!).
-
+ // Instantiate the members of this class template specialization.
+ InstantiatingTemplate Inst(*this, TemplateLoc, Specialization);
+ InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization);
+
return DeclPtrTy::make(Specialization);
}
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=71713&r1=71712&r2=71713&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed May 13 15:28:22 2009
@@ -749,6 +749,10 @@
// Exit the scope of this instantiation.
CurContext = PreviousContext;
+ // If this is an explicit instantiation, instantiate our members, too.
+ if (!Invalid && ExplicitInstantiation)
+ InstantiateClassMembers(PointOfInstantiation, Instantiation, TemplateArgs);
+
return Invalid;
}
@@ -787,6 +791,53 @@
ExplicitInstantiation);
}
+/// \brief Instantiate the definitions of all of the member of the
+/// given class, which is an instantiation of a class template or a
+/// member class of a template.
+void
+Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
+ CXXRecordDecl *Instantiation,
+ const TemplateArgumentList &TemplateArgs) {
+ for (DeclContext::decl_iterator D = Instantiation->decls_begin(Context),
+ DEnd = Instantiation->decls_end(Context);
+ D != DEnd; ++D) {
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(*D)) {
+ if (!Function->getBody(Context))
+ InstantiateFunctionDefinition(Function);
+ } else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
+ const VarDecl *Def = 0;
+ if (!Var->getDefinition(Def))
+ InstantiateVariableDefinition(Var);
+ } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(*D)) {
+ if (!Record->isInjectedClassName() && !Record->getDefinition(Context)) {
+ assert(Record->getInstantiatedFromMemberClass() &&
+ "Missing instantiated-from-template information");
+ InstantiateClass(Record->getLocation(), Record,
+ Record->getInstantiatedFromMemberClass(),
+ TemplateArgs, true);
+ }
+ }
+ }
+}
+
+/// \brief Instantiate the definitions of all of the members of the
+/// given class template specialization, which was named as part of an
+/// explicit instantiation.
+void Sema::InstantiateClassTemplateSpecializationMembers(
+ SourceLocation PointOfInstantiation,
+ ClassTemplateSpecializationDecl *ClassTemplateSpec) {
+ // C++0x [temp.explicit]p7:
+ // An explicit instantiation that names a class template
+ // specialization is an explicit instantion of the same kind
+ // (declaration or definition) of each of its members (not
+ // including members inherited from base classes) that has not
+ // been previously explicitly specialized in the translation unit
+ // containing the explicit instantiation, except as described
+ // below.
+ InstantiateClassMembers(PointOfInstantiation, ClassTemplateSpec,
+ ClassTemplateSpec->getTemplateArgs());
+}
+
/// \brief Instantiate a nested-name-specifier.
NestedNameSpecifier *
Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=71713&r1=71712&r2=71713&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed May 13 15:28:22 2009
@@ -550,3 +550,20 @@
// FIXME: New needs a pointer to Tmpl
return false;
}
+
+/// \brief Instantiate the definition of the given function from its
+/// template.
+///
+/// \param Function the already-instantiated declaration of a
+/// function.
+void Sema::InstantiateFunctionDefinition(FunctionDecl *Function) {
+ // FIXME: Implement this!
+}
+
+/// \brief Instantiate the definition of the given variable from its
+/// template.
+///
+/// \param Var the already-instantiated declaration of a variable.
+void Sema::InstantiateVariableDefinition(VarDecl *Var) {
+ // FIXME: Implement this!
+}
Modified: cfe/trunk/test/SemaTemplate/temp_explicit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_explicit.cpp?rev=71713&r1=71712&r2=71713&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_explicit.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_explicit.cpp Wed May 13 15:28:22 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify -pedantic %s
+// RUN: clang-cc -fsyntax-only -pedantic -verify %s
//
// Tests explicit instantiation of templates.
template<typename T, typename U = T> class X0 { };
@@ -46,3 +46,28 @@
template struct X2<int>; // okay
template struct X2<int&>; // expected-note{{in instantiation of}}
+
+// Check that explicit instantiations instantiate member classes.
+template<typename T> struct X3 {
+ struct Inner { // expected-note{{here}}
+ void f(T*); // expected-error{{pointer to a reference}}
+ };
+};
+
+void f1(X3<int&>); // okay, Inner, not instantiated
+
+template struct X3<int&>; // expected-note{{instantiation}}
+
+template<typename T> struct X4 {
+ struct Inner { // expected-note 2{{here}}
+ struct VeryInner { // expected-note 2{{here}}
+ void f(T*); // expected-error 2{{pointer to a reference}}
+ };
+ };
+};
+
+void f2(X4<int&>); // okay, Inner, not instantiated
+void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated
+
+template struct X4<int&>; // expected-note{{instantiation}}
+template struct X4<float&>; // expected-note{{instantiation}}
More information about the cfe-commits
mailing list