diff options
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 126 |
1 files changed, 107 insertions, 19 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 259c39c7d8e..1f6c2fab1b8 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -35,18 +35,16 @@ using namespace clang; /// but also int expressions which are produced by things like comparisons in /// C. bool Expr::isKnownToHaveBooleanValue() const { + const Expr *E = IgnoreParens(); + // If this value has _Bool type, it is obvious 0/1. - if (getType()->isBooleanType()) return true; + if (E->getType()->isBooleanType()) return true; // If this is a non-scalar-integer type, we don't care enough to try. - if (!getType()->isIntegralOrEnumerationType()) return false; - - if (const ParenExpr *PE = dyn_cast<ParenExpr>(this)) - return PE->getSubExpr()->isKnownToHaveBooleanValue(); + if (!E->getType()->isIntegralOrEnumerationType()) return false; - if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(this)) { + if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { switch (UO->getOpcode()) { case UO_Plus: - case UO_Extension: return UO->getSubExpr()->isKnownToHaveBooleanValue(); default: return false; @@ -55,10 +53,10 @@ bool Expr::isKnownToHaveBooleanValue() const { // Only look through implicit casts. If the user writes // '(int) (a && b)' treat it as an arbitrary int. - if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(this)) + if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) return CE->getSubExpr()->isKnownToHaveBooleanValue(); - if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(this)) { + if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { switch (BO->getOpcode()) { default: return false; case BO_LT: // Relational operators. @@ -84,7 +82,7 @@ bool Expr::isKnownToHaveBooleanValue() const { } } - if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(this)) + if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) return CO->getTrueExpr()->isKnownToHaveBooleanValue() && CO->getFalseExpr()->isKnownToHaveBooleanValue(); @@ -1363,6 +1361,9 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, case ParenExprClass: return cast<ParenExpr>(this)->getSubExpr()-> isUnusedResultAWarning(Loc, R1, R2, Ctx); + case GenericSelectionExprClass: + return cast<GenericSelectionExpr>(this)->getResultExpr()-> + isUnusedResultAWarning(Loc, R1, R2, Ctx); case UnaryOperatorClass: { const UnaryOperator *UO = cast<UnaryOperator>(this); @@ -1573,21 +1574,20 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, /// isOBJCGCCandidate - Check if an expression is objc gc'able. /// returns true, if it is; false otherwise. bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const { - switch (getStmtClass()) { + const Expr *E = IgnoreParens(); + switch (E->getStmtClass()) { default: return false; case ObjCIvarRefExprClass: return true; case Expr::UnaryOperatorClass: - return cast<UnaryOperator>(this)->getSubExpr()->isOBJCGCCandidate(Ctx); - case ParenExprClass: - return cast<ParenExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx); + return cast<UnaryOperator>(E)->getSubExpr()->isOBJCGCCandidate(Ctx); case ImplicitCastExprClass: - return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx); + return cast<ImplicitCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx); case CStyleCastExprClass: - return cast<CStyleCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx); + return cast<CStyleCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx); case DeclRefExprClass: { - const Decl *D = cast<DeclRefExpr>(this)->getDecl(); + const Decl *D = cast<DeclRefExpr>(E)->getDecl(); if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (VD->hasGlobalStorage()) return true; @@ -1600,11 +1600,11 @@ bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const { return false; } case MemberExprClass: { - const MemberExpr *M = cast<MemberExpr>(this); + const MemberExpr *M = cast<MemberExpr>(E); return M->getBase()->isOBJCGCCandidate(Ctx); } case ArraySubscriptExprClass: - return cast<ArraySubscriptExpr>(this)->getBase()->isOBJCGCCandidate(Ctx); + return cast<ArraySubscriptExpr>(E)->getBase()->isOBJCGCCandidate(Ctx); } } @@ -1827,6 +1827,11 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const { return CT_Dependent; return cast<ChooseExpr>(this)->getChosenSubExpr(C)->CanThrow(C); + case GenericSelectionExprClass: + if (cast<GenericSelectionExpr>(this)->isResultDependent()) + return CT_Dependent; + return cast<GenericSelectionExpr>(this)->getResultExpr()->CanThrow(C); + // Some expressions are always dependent. case DependentScopeDeclRefExprClass: case CXXUnresolvedConstructExprClass: @@ -1853,6 +1858,12 @@ Expr* Expr::IgnoreParens() { continue; } } + if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) { + if (!P->isResultDependent()) { + E = P->getResultExpr(); + continue; + } + } return E; } } @@ -1876,6 +1887,12 @@ Expr *Expr::IgnoreParenCasts() { continue; } } + if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) { + if (!P->isResultDependent()) { + E = P->getResultExpr(); + continue; + } + } return E; } } @@ -1900,6 +1917,11 @@ Expr *Expr::IgnoreParenLValueCasts() { E = P->getSubExpr(); continue; } + } else if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) { + if (!P->isResultDependent()) { + E = P->getResultExpr(); + continue; + } } break; } @@ -1923,6 +1945,12 @@ Expr *Expr::IgnoreParenImpCasts() { continue; } } + if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) { + if (!P->isResultDependent()) { + E = P->getResultExpr(); + continue; + } + } return E; } } @@ -1965,6 +1993,13 @@ Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) { } } + if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) { + if (!P->isResultDependent()) { + E = P->getResultExpr(); + continue; + } + } + return E; } } @@ -2156,6 +2191,11 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const { case ParenExprClass: return cast<ParenExpr>(this)->getSubExpr() ->isConstantInitializer(Ctx, IsForRef); + case GenericSelectionExprClass: + if (cast<GenericSelectionExpr>(this)->isResultDependent()) + return false; + return cast<GenericSelectionExpr>(this)->getResultExpr() + ->isConstantInitializer(Ctx, IsForRef); case ChooseExprClass: return cast<ChooseExpr>(this)->getChosenSubExpr(Ctx) ->isConstantInitializer(Ctx, IsForRef); @@ -2242,6 +2282,9 @@ Expr::isNullPointerConstant(ASTContext &Ctx, // Accept ((void*)0) as a null pointer constant, as many other // implementations do. return PE->getSubExpr()->isNullPointerConstant(Ctx, NPC); + } else if (const GenericSelectionExpr *GE = + dyn_cast<GenericSelectionExpr>(this)) { + return GE->getResultExpr()->isNullPointerConstant(Ctx, NPC); } else if (const CXXDefaultArgExpr *DefaultArg = dyn_cast<CXXDefaultArgExpr>(this)) { // See through default argument expressions @@ -2640,6 +2683,51 @@ void ShuffleVectorExpr::setExprs(ASTContext &C, Expr ** Exprs, memcpy(SubExprs, Exprs, sizeof(Expr *) * NumExprs); } +GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context, + SourceLocation GenericLoc, Expr *ControllingExpr, + TypeSourceInfo **AssocTypes, Expr **AssocExprs, + unsigned NumAssocs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, + bool ContainsUnexpandedParameterPack, + unsigned ResultIndex) + : Expr(GenericSelectionExprClass, + AssocExprs[ResultIndex]->getType(), + AssocExprs[ResultIndex]->getValueKind(), + AssocExprs[ResultIndex]->getObjectKind(), + AssocExprs[ResultIndex]->isTypeDependent(), + AssocExprs[ResultIndex]->isValueDependent(), + ContainsUnexpandedParameterPack), + AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), + SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), + ResultIndex(ResultIndex), GenericLoc(GenericLoc), DefaultLoc(DefaultLoc), + RParenLoc(RParenLoc) { + SubExprs[CONTROLLING] = ControllingExpr; + std::copy(AssocTypes, AssocTypes+NumAssocs, this->AssocTypes); + std::copy(AssocExprs, AssocExprs+NumAssocs, SubExprs+END_EXPR); +} + +GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context, + SourceLocation GenericLoc, Expr *ControllingExpr, + TypeSourceInfo **AssocTypes, Expr **AssocExprs, + unsigned NumAssocs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, + bool ContainsUnexpandedParameterPack) + : Expr(GenericSelectionExprClass, + Context.DependentTy, + VK_RValue, + OK_Ordinary, + /*isTypeDependent=*/ true, + /*isValueDependent=*/ true, + ContainsUnexpandedParameterPack), + AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), + SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), + ResultIndex(-1U), GenericLoc(GenericLoc), DefaultLoc(DefaultLoc), + RParenLoc(RParenLoc) { + SubExprs[CONTROLLING] = ControllingExpr; + std::copy(AssocTypes, AssocTypes+NumAssocs, this->AssocTypes); + std::copy(AssocExprs, AssocExprs+NumAssocs, SubExprs+END_EXPR); +} + //===----------------------------------------------------------------------===// // DesignatedInitExpr //===----------------------------------------------------------------------===// |