[cfe-commits] r80422 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-member-initializers.cpp

Anders Carlsson andersca at mac.com
Fri Aug 28 22:16:23 PDT 2009


Author: andersca
Date: Sat Aug 29 00:16:22 2009
New Revision: 80422

URL: http://llvm.org/viewvc/llvm-project?rev=80422&view=rev
Log:
Instantiate member and base initializers. Patch by Anders Johnsen! (tweaked slightly by me)

Added:
    cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=80422&r1=80421&r2=80422&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Aug 29 00:16:22 2009
@@ -2960,6 +2960,10 @@
                                      VarDecl *Var,
                                      bool Recursive = false);
 
+  void InstantiateMemInitializers(CXXConstructorDecl *New,
+                                  const CXXConstructorDecl *Tmpl,
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+  
   NamedDecl *FindInstantiatedDecl(NamedDecl *D);
   DeclContext *FindInstantiatedContext(DeclContext *DC);
     

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80422&r1=80421&r2=80422&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Aug 29 00:16:22 2009
@@ -992,9 +992,18 @@
   DeclContext *PreviousContext = CurContext;
   CurContext = Function;
 
+  MultiLevelTemplateArgumentList TemplateArgs = 
+    getTemplateInstantiationArgs(Function);
+
+  // If this is a constructor, instantiate the member initializers.
+  if (const CXXConstructorDecl *Ctor = 
+        dyn_cast<CXXConstructorDecl>(PatternDecl)) {
+    InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor,
+                               TemplateArgs);
+  }      
+  
   // Instantiate the function body.
-  OwningStmtResult Body 
-    = SubstStmt(Pattern, getTemplateInstantiationArgs(Function));
+  OwningStmtResult Body = SubstStmt(Pattern, TemplateArgs);
 
   ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body), 
                           /*IsInstantiation=*/true);
@@ -1092,6 +1101,71 @@
   }  
 }
 
+void
+Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
+                                 const CXXConstructorDecl *Tmpl,
+                           const MultiLevelTemplateArgumentList &TemplateArgs) {
+  
+  llvm::SmallVector<MemInitTy*, 4> NewInits;
+
+  // Instantiate all the initializers.
+  for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(),
+       InitsEnd = Tmpl->init_end(); Inits != InitsEnd; ++Inits) {
+    CXXBaseOrMemberInitializer *Init = *Inits;
+
+    ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+    
+    // Instantiate all the arguments.
+    for (ExprIterator Args = Init->arg_begin(), ArgsEnd = Init->arg_end();
+         Args != ArgsEnd; ++Args) {
+      OwningExprResult NewArg = SubstExpr(*Args, TemplateArgs);
+
+      if (NewArg.isInvalid())
+        New->setInvalidDecl();
+      else
+        NewArgs.push_back(NewArg.takeAs<Expr>());
+    }
+
+    MemInitResult NewInit;
+
+    if (Init->isBaseInitializer()) {
+      // FIXME: Type needs to be instantiated.
+      QualType BaseType = 
+        Context.getCanonicalType(QualType(Init->getBaseClass(), 0));
+
+      NewInit = BuildBaseInitializer(BaseType,
+                                     (Expr **)NewArgs.data(), 
+                                     NewArgs.size(),
+                                     Init->getSourceLocation(),
+                                     Init->getRParenLoc(),
+                                     New->getParent());
+    } else if (Init->isMemberInitializer()) {
+      FieldDecl *Member = 
+        cast<FieldDecl>(FindInstantiatedDecl(Init->getMember()));
+      
+      NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(), 
+                                       NewArgs.size(),
+                                       Init->getSourceLocation(),
+                                       Init->getRParenLoc());
+    }
+
+    if (NewInit.isInvalid())
+      New->setInvalidDecl();
+    else {
+      // FIXME: It would be nice if ASTOwningVector had a release function.
+      NewArgs.take();
+      
+      NewInits.push_back((MemInitTy *)NewInit.get());
+    }
+  }
+  
+  // Assign all the initializers to the new constructor.
+  ActOnMemInitializers(DeclPtrTy::make(New), 
+                       /*FIXME: ColonLoc */
+                       SourceLocation(),
+                       NewInits.data(), NewInits.size()); 
+}
+
 static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
   if (D->getKind() != Other->getKind())
     return false;

Added: cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp?rev=80422&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp Sat Aug 29 00:16:22 2009
@@ -0,0 +1,20 @@
+// RUN: clang-cc -fsyntax-only -Wall -verify %s
+
+template<typename T> struct A {
+  A() : a(1) { } // expected-error{{incompatible type passing 'int', expected 'void *'}}
+
+  T a;
+};
+
+A<int> a0;
+A<void*> a1; // expected-note{{in instantiation of member function 'A<void *>::A' requested here}}
+
+template<typename T> struct B {
+  // FIXME: This should warn about initialization order
+  B() : b(1), a(2) { }
+  
+  int a;
+  int b;
+};
+
+B<int> b0;





More information about the cfe-commits mailing list