[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