diff options
author | Manuel Klimek <klimek@google.com> | 2011-06-22 20:02:16 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2011-06-22 20:02:16 +0000 |
commit | 0d9106fc97cde979a995e26b18bcd2643f8afb55 (patch) | |
tree | 016f76ad40c436bedd157bcad1d6b5550c835ee5 | |
parent | c09ce1224dedc470fce9747e5936ff83cc6762eb (diff) |
Changes ParenListExpr to always require a type.
Removes dead code found in the process.
Adds a test to verify that ParenListExprs do not have NULL types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133637 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 2 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 35 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 16 | ||||
-rw-r--r-- | test/Sema/paren-list-expr-type.cpp | 17 |
6 files changed, 37 insertions, 42 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 698a2f06f6..09ffc1a4bf 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -3750,7 +3750,7 @@ class ParenListExpr : public Expr { public: ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, - unsigned numexprs, SourceLocation rparenloc); + unsigned numexprs, SourceLocation rparenloc, QualType T); /// \brief Build an empty paren list. explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 2adaba11a0..fdcb77f324 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -3033,11 +3033,11 @@ void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx, ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, - SourceLocation rparenloc) - : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, + SourceLocation rparenloc, QualType T) + : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary, false, false, false), NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { - + assert(!T.isNull() && "ParenListExpr must have a valid type"); Exprs = new (C) Stmt*[nexprs]; for (unsigned i = 0; i != nexprs; ++i) { if (exprs[i]->isTypeDependent()) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index de52b0aa5e..0a7ca4d2f9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1610,7 +1610,8 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args, // Can't check initialization for a member of dependent type or when // any of the arguments are type-dependent expressions. Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs, - RParenLoc); + RParenLoc, + Member->getType().getNonReferenceType()); DiscardCleanupsInEvaluationContext(); } else { @@ -1646,8 +1647,9 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args, // 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); + Init = new (Context) ParenListExpr( + Context, LParenLoc, Args, NumArgs, RParenLoc, + Member->getType().getNonReferenceType()); else Init = MemberInit.get(); } @@ -1703,22 +1705,7 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, if (DelegationInit.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 base - // 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()) { - ExprResult Init - = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, - NumArgs, RParenLoc)); - return new (Context) CXXCtorInitializer(Context, Loc, LParenLoc, - Constructor, Init.takeAs<Expr>(), - RParenLoc); - } - + assert(!CurContext->isDependentContext()); return new (Context) CXXCtorInitializer(Context, Loc, LParenLoc, Constructor, DelegationInit.takeAs<Expr>(), RParenLoc); @@ -1803,7 +1790,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, // any of the arguments are type-dependent expressions. ExprResult BaseInit = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs, - RParenLoc)); + RParenLoc, BaseType)); DiscardCleanupsInEvaluationContext(); @@ -1861,7 +1848,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, if (CurContext->isDependentContext()) { ExprResult Init = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs, - RParenLoc)); + RParenLoc, BaseType)); return new (Context) CXXCtorInitializer(Context, BaseTInfo, BaseSpec->isVirtual(), LParenLoc, @@ -7520,9 +7507,9 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl, // Store the initialization expressions as a ParenListExpr. unsigned NumExprs = Exprs.size(); - VDecl->setInit(new (Context) ParenListExpr(Context, LParenLoc, - (Expr **)Exprs.release(), - NumExprs, RParenLoc)); + VDecl->setInit(new (Context) ParenListExpr( + Context, LParenLoc, (Expr **)Exprs.release(), NumExprs, RParenLoc, + VDecl->getType().getNonReferenceType())); return; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 521f19c8cb..e4eb95379d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5846,7 +5846,8 @@ ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, if (nexprs == 1 && TypeOfCast && !TypeIsVectorType(TypeOfCast)) expr = new (Context) ParenExpr(L, R, exprs[0]); else - expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R); + expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R, + exprs[nexprs-1]->getType()); return Owned(expr); } diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 15007ef7c6..9891500efa 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3915,19 +3915,9 @@ InitializationSequence::Perform(Sema &S, } } - - if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast()) - return ExprResult(Args.release()[0]); - - if (Args.size() == 0) - return S.Owned((Expr *)0); - - unsigned NumArgs = Args.size(); - return S.Owned(new (S.Context) ParenListExpr(S.Context, - SourceLocation(), - (Expr **)Args.release(), - NumArgs, - SourceLocation())); + assert(Kind.getKind() == InitializationKind::IK_Copy || + Kind.isExplicitCast()); + return ExprResult(Args.release()[0]); } // No steps means no initialization. diff --git a/test/Sema/paren-list-expr-type.cpp b/test/Sema/paren-list-expr-type.cpp new file mode 100644 index 0000000000..ad5b7fbf91 --- /dev/null +++ b/test/Sema/paren-list-expr-type.cpp @@ -0,0 +1,17 @@ +// RUN: %clang -cc1 -ast-dump %s | not grep NULL +// Makes sure that we don't introduce null types when handling +// ParenListExpr. + +template<typename T> class X { void f() { X x(*this); } }; + +template<typename T> class Y { Y() : t(1) {} T t; }; + +template<typename T> class Z { Z() : b(true) {} const bool b; }; + +template<typename T> class A : public Z<T> { A() : Z<T>() {} }; + +class C {}; +template<typename T> class D : public C { D(): C() {} }; + +void f() { (int)(1, 2); } + |