aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-12-06 09:23:57 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-12-06 09:23:57 +0000
commit894aed964fae942b62326881dc106801dabfd04c (patch)
tree8dd26ced4a80783e0ba22307728777ff45ae6163
parent4765fa05b5652fcc4356371c2f481d0ea9a1b007 (diff)
Un-templatetize this method. It's definition is out of line in the .cpp file,
so that's not a valid thing to do at all. Instead, switch to a ValueDecl argument, the template isn't really necessary here. When handling the types explicitly in the code, it becomes awkward to cerate the CXXBaseOrMemberInitializer object in so many places. Re-flow the code to calculate the Init expression first, and then create the initializer. If this is too gross, we can factor the init expression logic into helper functions, but it's not past my threshold yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120997 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp106
2 files changed, 53 insertions, 56 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 9adffe0494..cf770c66eb 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2530,8 +2530,7 @@ public:
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc);
- template<typename T>
- MemInitResult BuildMemberInitializer(T *Member, Expr **Args,
+ MemInitResult BuildMemberInitializer(ValueDecl *Member, Expr **Args,
unsigned NumArgs, SourceLocation IdLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8be402fb5b..02688b8f65 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1259,18 +1259,19 @@ static bool InitExprContainsUninitializedFields(const Stmt *S,
return false;
}
-template <typename T>
MemInitResult
-Sema::BuildMemberInitializer(T *Member, Expr **Args,
+Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args,
unsigned NumArgs, SourceLocation IdLoc,
SourceLocation LParenLoc,
SourceLocation RParenLoc) {
- assert((isa<FieldDecl>(Member) || isa<IndirectFieldDecl>(Member)) ||
+ FieldDecl *DirectMember = dyn_cast<FieldDecl>(Member);
+ IndirectFieldDecl *IndirectMember = dyn_cast<IndirectFieldDecl>(Member);
+ assert((DirectMember || IndirectMember) &&
"Member must be a FieldDecl or IndirectFieldDecl");
if (Member->isInvalidDecl())
return true;
-
+
// Diagnose value-uses of fields to initialize themselves, e.g.
// foo(foo)
// where foo is not also a parameter to the constructor.
@@ -1292,12 +1293,12 @@ Sema::BuildMemberInitializer(T *Member, Expr **Args,
for (unsigned i = 0; i < NumArgs; i++)
HasDependentArg |= Args[i]->isTypeDependent();
+ Expr *Init;
if (Member->getType()->isDependentType() || HasDependentArg) {
// Can't check initialization for a member of dependent type or when
// any of the arguments are type-dependent expressions.
- Expr *Init
- = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc);
+ Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+ RParenLoc);
// Erase any temporaries within this evaluation context; we're not
// going to track them in the AST, since we'll be rebuilding the
@@ -1305,57 +1306,54 @@ Sema::BuildMemberInitializer(T *Member, Expr **Args,
ExprTemporaries.erase(
ExprTemporaries.begin() + ExprEvalContexts.back().NumTemporaries,
ExprTemporaries.end());
-
- return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
- LParenLoc,
- Init,
- RParenLoc);
-
+ } else {
+ // Initialize the member.
+ InitializedEntity MemberEntity =
+ DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
+ : InitializedEntity::InitializeMember(IndirectMember, 0);
+ InitializationKind Kind =
+ InitializationKind::CreateDirect(IdLoc, LParenLoc, RParenLoc);
+
+ InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
+
+ ExprResult MemberInit =
+ InitSeq.Perform(*this, MemberEntity, Kind,
+ MultiExprArg(*this, Args, NumArgs), 0);
+ if (MemberInit.isInvalid())
+ return true;
+
+ CheckImplicitConversions(MemberInit.get(), LParenLoc);
+
+ // C++0x [class.base.init]p7:
+ // The initialization of each base and member constitutes a
+ // full-expression.
+ MemberInit = MaybeCreateExprWithCleanups(MemberInit.get());
+ if (MemberInit.isInvalid())
+ return true;
+
+ // If we are in a dependent context, template instantiation will
+ // perform this type-checking again. Just save the arguments that we
+ // received in a ParenListExpr.
+ // FIXME: This isn't quite ideal, since our ASTs don't capture all
+ // of the information that we have about the member
+ // initializer. However, deconstructing the ASTs is a dicey process,
+ // and this approach is far more likely to get the corner cases right.
+ if (CurContext->isDependentContext())
+ Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+ RParenLoc);
+ else
+ Init = MemberInit.get();
}
-
- // Initialize the member.
- InitializedEntity MemberEntity =
- InitializedEntity::InitializeMember(Member, 0);
- InitializationKind Kind =
- InitializationKind::CreateDirect(IdLoc, LParenLoc, RParenLoc);
-
- InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
-
- ExprResult MemberInit =
- InitSeq.Perform(*this, MemberEntity, Kind,
- MultiExprArg(*this, Args, NumArgs), 0);
- if (MemberInit.isInvalid())
- return true;
- CheckImplicitConversions(MemberInit.get(), LParenLoc);
-
- // C++0x [class.base.init]p7:
- // The initialization of each base and member constitutes a
- // full-expression.
- MemberInit = MaybeCreateExprWithCleanups(MemberInit.get());
- if (MemberInit.isInvalid())
- return true;
-
- // If we are in a dependent context, template instantiation will
- // perform this type-checking again. Just save the arguments that we
- // received in a ParenListExpr.
- // FIXME: This isn't quite ideal, since our ASTs don't capture all
- // of the information that we have about the member
- // initializer. However, deconstructing the ASTs is a dicey process,
- // and this approach is far more likely to get the corner cases right.
- if (CurContext->isDependentContext()) {
- Expr *Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc);
- return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
- LParenLoc,
- Init,
+ if (DirectMember) {
+ return new (Context) CXXBaseOrMemberInitializer(Context, DirectMember,
+ IdLoc, LParenLoc, Init,
+ RParenLoc);
+ } else {
+ return new (Context) CXXBaseOrMemberInitializer(Context, IndirectMember,
+ IdLoc, LParenLoc, Init,
RParenLoc);
}
-
- return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
- LParenLoc,
- MemberInit.get(),
- RParenLoc);
}
MemInitResult