[cfe-commits] r67623 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-method.cpp
Douglas Gregor
dgregor at apple.com
Tue Mar 24 09:43:20 PDT 2009
Author: dgregor
Date: Tue Mar 24 11:43:20 2009
New Revision: 67623
URL: http://llvm.org/viewvc/llvm-project?rev=67623&view=rev
Log:
Template instantiation for constructors
Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/instantiate-method.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=67623&r1=67622&r2=67623&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 24 11:43:20 2009
@@ -1654,6 +1654,8 @@
return;
}
+ // FIXME: Need to handle dependent types and expressions here.
+
// We will treat direct-initialization as a copy-initialization:
// int x(1); -as-> int x = 1;
// ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
@@ -1672,6 +1674,13 @@
if (const ArrayType *Array = Context.getAsArrayType(DeclInitType))
DeclInitType = Array->getElementType();
+ // FIXME: This isn't the right place to complete the type.
+ if (RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
+ diag::err_typecheck_decl_incomplete_type)) {
+ VDecl->setInvalidDecl();
+ return;
+ }
+
if (VDecl->getType()->isRecordType()) {
CXXConstructorDecl *Constructor
= PerformInitializationByConstructor(DeclInitType,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=67623&r1=67622&r2=67623&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Mar 24 11:43:20 2009
@@ -44,6 +44,7 @@
Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
Decl *VisitEnumDecl(EnumDecl *D);
Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
+ Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
Decl *VisitParmVarDecl(ParmVarDecl *D);
Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
@@ -247,6 +248,50 @@
return Method;
}
+Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+ llvm::SmallVector<ParmVarDecl *, 16> Params;
+ QualType T = InstantiateFunctionType(D, Params);
+ if (T.isNull())
+ return 0;
+
+ // Build the instantiated method declaration.
+ CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
+ QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
+ DeclarationName Name
+ = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
+ CXXConstructorDecl *Constructor
+ = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(),
+ Name, T, D->isExplicit(), D->isInline(),
+ false);
+
+ // Attach the parameters
+ for (unsigned P = 0; P < Params.size(); ++P)
+ Params[P]->setOwningFunction(Constructor);
+ Constructor->setParams(SemaRef.Context, &Params[0], Params.size());
+
+ if (InitMethodInstantiation(Constructor, D))
+ Constructor->setInvalidDecl();
+
+ NamedDecl *PrevDecl
+ = SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true);
+
+ // In C++, the previous declaration we find might be a tag type
+ // (class or enum). In this case, the new declaration will hide the
+ // tag type. Note that this does does not apply if we're declaring a
+ // typedef (C++ [dcl.typedef]p4).
+ if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
+ PrevDecl = 0;
+ bool Redeclaration = false;
+ bool OverloadableAttrRequired = false;
+ if (SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
+ /*FIXME:*/OverloadableAttrRequired))
+ Constructor->setInvalidDecl();
+
+ if (!Constructor->isInvalidDecl())
+ Owner->addDecl(Constructor);
+ return Constructor;
+}
+
Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
llvm::SmallVector<ParmVarDecl *, 16> Params;
QualType T = InstantiateFunctionType(D, Params);
Modified: cfe/trunk/test/SemaTemplate/instantiate-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-method.cpp?rev=67623&r1=67622&r2=67623&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-method.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-method.cpp Tue Mar 24 11:43:20 2009
@@ -41,9 +41,23 @@
template<typename T>
class HasDestructor {
+public:
virtual ~HasDestructor() = 0;
};
int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but
// the code below should probably instantiate by itself.
int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];
+
+
+template<typename T>
+class Constructors {
+public:
+ Constructors(const T&);
+ Constructors(const Constructors &other);
+};
+
+void test_constructors() {
+ Constructors<int> ci1(17);
+ Constructors<int> ci2 = ci1;
+}
More information about the cfe-commits
mailing list