diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 126 | ||||
-rw-r--r-- | clang/lib/AST/ExprClassification.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 22 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 17 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 12 |
6 files changed, 167 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 //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index e94ae82786b..803bc561bae 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -233,6 +233,14 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ParenExprClass: return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr()); + // C1X 6.5.1.1p4: [A generic selection] is an lvalue, a function designator, + // or a void expression if its result expression is, respectively, an + // lvalue, a function designator, or a void expression. + case Expr::GenericSelectionExprClass: + if (cast<GenericSelectionExpr>(E)->isResultDependent()) + return Cl::CL_PRValue; + return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr()); + case Expr::BinaryOperatorClass: case Expr::CompoundAssignOperatorClass: // C doesn't have any binary expressions that are lvalues. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index cdd7efaaf55..0ec122dc353 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -274,6 +274,9 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitGenericSelectionExpr(GenericSelectionExpr *E) { + return Visit(E->getResultExpr()); + } bool VisitDeclRefExpr(DeclRefExpr *E) { if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified()) return true; @@ -372,6 +375,9 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitGenericSelectionExpr(GenericSelectionExpr *E) { + return Visit(E->getResultExpr()); + } bool VisitDeclRefExpr(DeclRefExpr *E); bool VisitPredefinedExpr(PredefinedExpr *E) { return Success(E); } bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); @@ -501,6 +507,9 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitGenericSelectionExpr(GenericSelectionExpr *E) { + return Visit(E->getResultExpr()); + } bool VisitBinaryOperator(const BinaryOperator *E); bool VisitCastExpr(CastExpr* E); @@ -717,6 +726,8 @@ namespace { APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + APValue VisitGenericSelectionExpr(GenericSelectionExpr *E) + { return Visit(E->getResultExpr()); } APValue VisitUnaryExtension(const UnaryOperator *E) { return Visit(E->getSubExpr()); } APValue VisitUnaryPlus(const UnaryOperator *E) @@ -975,6 +986,9 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitGenericSelectionExpr(GenericSelectionExpr *E) { + return Visit(E->getResultExpr()); + } bool VisitIntegerLiteral(const IntegerLiteral *E) { return Success(E->getValue(), E); @@ -1918,6 +1932,9 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitGenericSelectionExpr(GenericSelectionExpr *E) { + return Visit(E->getResultExpr()); + } bool VisitCallExpr(const CallExpr *E); bool VisitUnaryOperator(const UnaryOperator *E); @@ -2251,6 +2268,9 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitGenericSelectionExpr(GenericSelectionExpr *E) { + return Visit(E->getResultExpr()); + } bool VisitImaginaryLiteral(ImaginaryLiteral *E); @@ -2839,6 +2859,8 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::ParenExprClass: return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx); + case Expr::GenericSelectionExprClass: + return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx); case Expr::IntegerLiteralClass: case Expr::CharacterLiteralClass: case Expr::CXXBoolLiteralExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index be17ccf2d82..752163a4bdb 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1750,6 +1750,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::ChooseExprClass: case Expr::CompoundLiteralExprClass: case Expr::ExtVectorElementExprClass: + case Expr::GenericSelectionExprClass: case Expr::ObjCEncodeExprClass: case Expr::ObjCIsaExprClass: case Expr::ObjCIvarRefExprClass: diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 37010a0358d..89631261dcc 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -737,6 +737,23 @@ void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ PrintExpr(Node->getArgumentExpr()); } } + +void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { + OS << "_Generic("; + PrintExpr(Node->getControllingExpr()); + for (unsigned i = 0; i != Node->getNumAssocs(); ++i) { + OS << ", "; + QualType T = Node->getAssocType(i); + if (T.isNull()) + OS << "default"; + else + OS << T.getAsString(Policy); + OS << ": "; + PrintExpr(Node->getAssocExpr(i)); + } + OS << ")"; +} + void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { PrintExpr(Node->getLHS()); OS << "["; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 92292cea719..dbcb7e4fe60 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -434,6 +434,18 @@ void StmtProfiler::VisitBlockDeclRefExpr(BlockDeclRefExpr *S) { ID.AddBoolean(S->isConstQualAdded()); } +void StmtProfiler::VisitGenericSelectionExpr(GenericSelectionExpr *S) { + VisitExpr(S); + for (unsigned i = 0; i != S->getNumAssocs(); ++i) { + QualType T = S->getAssocType(i); + if (T.isNull()) + ID.AddPointer(0); + else + VisitType(T); + VisitExpr(S->getAssocExpr(i)); + } +} + static Stmt::StmtClass DecodeOperatorCall(CXXOperatorCallExpr *S, UnaryOperatorKind &UnaryOp, BinaryOperatorKind &BinaryOp) { |