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