Hi,
This is an attempt to implement instantiation of constructor initializers,
when the class is dependent.


- Anders Johnsen
Index: include/clang/AST/DeclCXX.h
===================================================================
--- include/clang/AST/DeclCXX.h	(revision 80240)
+++ include/clang/AST/DeclCXX.h	(working copy)
@@ -839,18 +839,21 @@
   /// IdLoc - Location of the id in ctor-initializer list.
   SourceLocation IdLoc;
 
+  /// RParenLoc - Location of the right paren of the ctor-initializer.
+  SourceLocation RParenLoc;
+
 public:
   /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
   explicit 
   CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
                              CXXConstructorDecl *C,
-                             SourceLocation L);
+                             SourceLocation L, SourceLocation R);
 
   /// CXXBaseOrMemberInitializer - Creates a new member initializer.
   explicit 
   CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
                              CXXConstructorDecl *C,
-                             SourceLocation L);
+                             SourceLocation L, SourceLocation R);
 
   /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
   ~CXXBaseOrMemberInitializer();
@@ -921,6 +924,7 @@
   const CXXConstructorDecl *getConstructor() const { return CtorToCall; }
   
   SourceLocation getSourceLocation() const { return IdLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
   
   /// arg_begin() - Retrieve an iterator to the first initializer argument.
   arg_iterator       arg_begin()       { return Args; }
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp	(revision 80240)
+++ lib/Sema/SemaDeclCXX.cpp	(working copy)
@@ -797,7 +797,7 @@
   }
   // FIXME: Perform direct initialization of the member.
   return new (Context) CXXBaseOrMemberInitializer(Member, (Expr **)Args, 
-                                                  NumArgs, C, IdLoc);
+                                                  NumArgs, C, IdLoc, RParenLoc);
 }
 
 Sema::MemInitResult
@@ -880,7 +880,7 @@
   }
 
   return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, 
-                                                  NumArgs, C, IdLoc);
+                                                  NumArgs, C, IdLoc, RParenLoc);
 }
 
 void
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp	(revision 80240)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp	(working copy)
@@ -865,14 +865,14 @@
   assert(!Function->getBody() && "Already instantiated!");
   
   // Find the function body that we'll be substituting.
-  const FunctionDecl *PatternDecl = 0;
+  FunctionDecl *PatternDecl = 0;
   if (FunctionTemplateDecl *Primary = Function->getPrimaryTemplate())
     PatternDecl = Primary->getTemplatedDecl();
   else 
     PatternDecl = Function->getInstantiatedFromMemberFunction();
   Stmt *Pattern = 0;
   if (PatternDecl)
-    Pattern = PatternDecl->getBody(PatternDecl);
+    Pattern = PatternDecl->getBody((const FunctionDecl*&)PatternDecl);
 
   if (!Pattern)
     return;
@@ -905,9 +905,65 @@
   DeclContext *PreviousContext = CurContext;
   CurContext = Function;
 
+  const TemplateArgumentList TempArgList = getTemplateInstantiationArgs(Function);
+
+  CXXConstructorDecl *Constructor;
+  if ((Constructor = dyn_cast<CXXConstructorDecl>(PatternDecl))) {
+    CXXConstructorDecl *NewConstructor = cast<CXXConstructorDecl>(Function);
+    // Duplicate and Instantiate all the Member / Base initializers.
+    llvm::SmallVector<MemInitTy*, 4> NewItems;
+    CXXConstructorDecl::init_iterator InitIter = Constructor->init_begin(),
+                                      InitIterEnd = Constructor->init_end();
+    for (; InitIter != InitIterEnd; ++InitIter) {
+      CXXBaseOrMemberInitializer *Item = *InitIter;
+      SourceLocation Loc = Item->getSourceLocation();
+      SourceLocation RLoc = Item->getRParenLoc();
+
+      // Instantiate all the expression.
+      llvm::SmallVector<Expr*, 4> NewExprs;
+      ExprIterator ExprIter = Item->arg_begin(),
+                   ExprIterEnd = Item->arg_end();
+      for (;ExprIter != ExprIterEnd; ++ExprIter) {
+        OwningExprResult Result = SubstExpr(*ExprIter, TempArgList);
+        if (Result.isInvalid())
+          Function->setInvalidDecl();
+        else
+          NewExprs.push_back((Expr*)Result.take());
+      }
+      
+      MemInitResult MemResult;
+      // Handle Base and Member case explicit.
+      if (Item->isMemberInitializer()) {
+        FieldDecl *Member = Item->getMember();
+        Member = cast<FieldDecl>(FindInstantiatedDecl(Member));
+        MemResult = BuildMemberInitializer(Member,
+                                           NewExprs.data(), 
+                                           (unsigned)NewExprs.size(), 
+                                           Loc,
+                                           RLoc);
+      }
+      if (Item->isBaseInitializer()) {
+        MemResult = BuildBaseInitializer(Item->getBaseClass()->getCanonicalTypeInternal(), 
+                                         NewExprs.data(),
+                                         (unsigned)NewExprs.size(),
+                                         Loc,
+                                         RLoc,
+                                         NewConstructor->getParent());
+      }
+      if (MemResult.isInvalid())
+        Function->setInvalidDecl();
+      else
+        NewItems.push_back((MemInitTy*)MemResult.get());
+    }
+
+    // Assign all the initializers to the new constructor.
+    ActOnMemInitializers(DeclPtrTy::make(Function), PointOfInstantiation, 
+        (MemInitTy**)NewItems.data(), NewItems.size()); 
+  }
+
   // Instantiate the function body.
   OwningStmtResult Body 
-    = SubstStmt(Pattern, getTemplateInstantiationArgs(Function));
+    = SubstStmt(Pattern, TempArgList);
 
   ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body), 
                           /*IsInstantiation=*/true);
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp	(revision 80240)
+++ lib/AST/DeclCXX.cpp	(working copy)
@@ -400,8 +400,8 @@
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
                            CXXConstructorDecl *C,
-                           SourceLocation L) 
-  : Args(0), NumArgs(0), IdLoc(L) {
+                           SourceLocation L, SourceLocation R) 
+  : Args(0), NumArgs(0), IdLoc(L), RParenLoc(R) {
   BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
   assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
   BaseOrMember |= 0x01;
@@ -419,8 +419,8 @@
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
                            CXXConstructorDecl *C,
-                           SourceLocation L)
-  : Args(0), NumArgs(0), IdLoc(L) {
+                           SourceLocation L, SourceLocation R)
+  : Args(0), NumArgs(0), IdLoc(L), RParenLoc(R) {
   BaseOrMember = reinterpret_cast<uintptr_t>(Member);
   assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");  
 
@@ -622,6 +622,7 @@
       CXXBaseOrMemberInitializer *Member = 
         new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
                                            VBaseDecl->getDefaultConstructor(C),
+                                           SourceLocation(),
                                            SourceLocation());
       AllToInit.push_back(Member);
     }
@@ -648,6 +649,7 @@
       CXXBaseOrMemberInitializer *Member = 
       new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
                                          BaseDecl->getDefaultConstructor(C),
+                                         SourceLocation(),
                                          SourceLocation());
       AllToInit.push_back(Member);
     }
@@ -690,6 +692,7 @@
       CXXBaseOrMemberInitializer *Member = 
         new (C) CXXBaseOrMemberInitializer((*Field), 0, 0,
                                            Ctor,
+                                           SourceLocation(),
                                            SourceLocation());
       AllToInit.push_back(Member);
     } 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to