diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 |
commit | 53992adde3eda3ccf9da63bc7e45673f043de18f (patch) | |
tree | 3558f327a6f9ab59c5d7a06528d84e1560445247 /lib/AST/Expr.cpp | |
parent | 7e411337c0ed226dace6e07f1420486768161308 (diff) | |
download | FreeBSD-src-53992adde3eda3ccf9da63bc7e45673f043de18f.zip FreeBSD-src-53992adde3eda3ccf9da63bc7e45673f043de18f.tar.gz |
Update clang to r104832.
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 419 |
1 files changed, 34 insertions, 385 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 00662a5..c38cec3 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -27,6 +27,8 @@ #include <algorithm> using namespace clang; +void Expr::ANCHOR() {} // key function for Expr class. + /// isKnownToHaveBooleanValue - Return true if this is an integer expression /// that is known to return 0 or 1. This happens for _Bool/bool expressions /// but also int expressions which are produced by things like comparisons in @@ -161,8 +163,19 @@ void DeclRefExpr::computeDependence() { if (const Expr *Init = Var->getAnyInitializer()) if (Init->isValueDependent()) ValueDependent = true; - } - } + } + // (VD) - FIXME: Missing from the standard: + // - a member function or a static data member of the current + // instantiation + else if (Var->isStaticDataMember() && + Var->getDeclContext()->isDependentContext()) + ValueDependent = true; + } + // (VD) - FIXME: Missing from the standard: + // - a member function or a static data member of the current + // instantiation + else if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) + ValueDependent = true; // (TD) - a nested-name-specifier or a qualified-id that names a // member of an unknown specialization. // (handled by DependentScopeDeclRefExpr) @@ -976,6 +989,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, return true; } case CompoundAssignOperatorClass: + case VAArgExprClass: return false; case ConditionalOperatorClass: { @@ -1557,6 +1571,18 @@ Expr *Expr::IgnoreParenCasts() { } } +Expr *Expr::IgnoreParenImpCasts() { + Expr *E = this; + while (true) { + if (ParenExpr *P = dyn_cast<ParenExpr>(E)) + E = P->getSubExpr(); + else if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E)) + E = P->getSubExpr(); + else + return E; + } +} + /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the /// value (including ptr->int casts of the same size). Strip off any /// ParenExpr or CastExprs, returning their operand. @@ -1757,385 +1783,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const { return isEvaluatable(Ctx); } -/// isIntegerConstantExpr - this recursive routine will test if an expression is -/// an integer constant expression. - -/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero, -/// comma, etc -/// -/// FIXME: Handle offsetof. Two things to do: Handle GCC's __builtin_offsetof -/// to support gcc 4.0+ and handle the idiom GCC recognizes with a null pointer -/// cast+dereference. - -// CheckICE - This function does the fundamental ICE checking: the returned -// ICEDiag contains a Val of 0, 1, or 2, and a possibly null SourceLocation. -// Note that to reduce code duplication, this helper does no evaluation -// itself; the caller checks whether the expression is evaluatable, and -// in the rare cases where CheckICE actually cares about the evaluated -// value, it calls into Evalute. -// -// Meanings of Val: -// 0: This expression is an ICE if it can be evaluated by Evaluate. -// 1: This expression is not an ICE, but if it isn't evaluated, it's -// a legal subexpression for an ICE. This return value is used to handle -// the comma operator in C99 mode. -// 2: This expression is not an ICE, and is not a legal subexpression for one. - -struct ICEDiag { - unsigned Val; - SourceLocation Loc; - - public: - ICEDiag(unsigned v, SourceLocation l) : Val(v), Loc(l) {} - ICEDiag() : Val(0) {} -}; - -ICEDiag NoDiag() { return ICEDiag(); } - -static ICEDiag CheckEvalInICE(const Expr* E, ASTContext &Ctx) { - Expr::EvalResult EVResult; - if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects || - !EVResult.Val.isInt()) { - return ICEDiag(2, E->getLocStart()); - } - return NoDiag(); -} - -static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { - assert(!E->isValueDependent() && "Should not see value dependent exprs!"); - if (!E->getType()->isIntegralType()) { - return ICEDiag(2, E->getLocStart()); - } - - switch (E->getStmtClass()) { -#define STMT(Node, Base) case Expr::Node##Class: -#define EXPR(Node, Base) -#include "clang/AST/StmtNodes.def" - case Expr::PredefinedExprClass: - case Expr::FloatingLiteralClass: - case Expr::ImaginaryLiteralClass: - case Expr::StringLiteralClass: - case Expr::ArraySubscriptExprClass: - case Expr::MemberExprClass: - case Expr::CompoundAssignOperatorClass: - case Expr::CompoundLiteralExprClass: - case Expr::ExtVectorElementExprClass: - case Expr::InitListExprClass: - case Expr::DesignatedInitExprClass: - case Expr::ImplicitValueInitExprClass: - case Expr::ParenListExprClass: - case Expr::VAArgExprClass: - case Expr::AddrLabelExprClass: - case Expr::StmtExprClass: - case Expr::CXXMemberCallExprClass: - case Expr::CXXDynamicCastExprClass: - case Expr::CXXTypeidExprClass: - case Expr::CXXNullPtrLiteralExprClass: - case Expr::CXXThisExprClass: - case Expr::CXXThrowExprClass: - case Expr::CXXNewExprClass: - case Expr::CXXDeleteExprClass: - case Expr::CXXPseudoDestructorExprClass: - case Expr::UnresolvedLookupExprClass: - case Expr::DependentScopeDeclRefExprClass: - case Expr::CXXConstructExprClass: - case Expr::CXXBindTemporaryExprClass: - case Expr::CXXBindReferenceExprClass: - case Expr::CXXExprWithTemporariesClass: - case Expr::CXXTemporaryObjectExprClass: - case Expr::CXXUnresolvedConstructExprClass: - case Expr::CXXDependentScopeMemberExprClass: - case Expr::UnresolvedMemberExprClass: - case Expr::ObjCStringLiteralClass: - case Expr::ObjCEncodeExprClass: - case Expr::ObjCMessageExprClass: - case Expr::ObjCSelectorExprClass: - case Expr::ObjCProtocolExprClass: - case Expr::ObjCIvarRefExprClass: - case Expr::ObjCPropertyRefExprClass: - case Expr::ObjCImplicitSetterGetterRefExprClass: - case Expr::ObjCSuperExprClass: - case Expr::ObjCIsaExprClass: - case Expr::ShuffleVectorExprClass: - case Expr::BlockExprClass: - case Expr::BlockDeclRefExprClass: - case Expr::NoStmtClass: - return ICEDiag(2, E->getLocStart()); - - case Expr::GNUNullExprClass: - // GCC considers the GNU __null value to be an integral constant expression. - return NoDiag(); - - case Expr::ParenExprClass: - return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx); - case Expr::IntegerLiteralClass: - case Expr::CharacterLiteralClass: - case Expr::CXXBoolLiteralExprClass: - case Expr::CXXZeroInitValueExprClass: - case Expr::TypesCompatibleExprClass: - case Expr::UnaryTypeTraitExprClass: - return NoDiag(); - case Expr::CallExprClass: - case Expr::CXXOperatorCallExprClass: { - const CallExpr *CE = cast<CallExpr>(E); - if (CE->isBuiltinCall(Ctx)) - return CheckEvalInICE(E, Ctx); - return ICEDiag(2, E->getLocStart()); - } - case Expr::DeclRefExprClass: - if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl())) - return NoDiag(); - if (Ctx.getLangOptions().CPlusPlus && - E->getType().getCVRQualifiers() == Qualifiers::Const) { - const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl(); - - // Parameter variables are never constants. Without this check, - // getAnyInitializer() can find a default argument, which leads - // to chaos. - if (isa<ParmVarDecl>(D)) - return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); - - // C++ 7.1.5.1p2 - // A variable of non-volatile const-qualified integral or enumeration - // type initialized by an ICE can be used in ICEs. - if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) { - Qualifiers Quals = Ctx.getCanonicalType(Dcl->getType()).getQualifiers(); - if (Quals.hasVolatile() || !Quals.hasConst()) - return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); - - // Look for a declaration of this variable that has an initializer. - const VarDecl *ID = 0; - const Expr *Init = Dcl->getAnyInitializer(ID); - if (Init) { - if (ID->isInitKnownICE()) { - // We have already checked whether this subexpression is an - // integral constant expression. - if (ID->isInitICE()) - return NoDiag(); - else - return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); - } - - // It's an ICE whether or not the definition we found is - // out-of-line. See DR 721 and the discussion in Clang PR - // 6206 for details. - - if (Dcl->isCheckingICE()) { - return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); - } - - Dcl->setCheckingICE(); - ICEDiag Result = CheckICE(Init, Ctx); - // Cache the result of the ICE test. - Dcl->setInitKnownICE(Result.Val == 0); - return Result; - } - } - } - return ICEDiag(2, E->getLocStart()); - case Expr::UnaryOperatorClass: { - const UnaryOperator *Exp = cast<UnaryOperator>(E); - switch (Exp->getOpcode()) { - case UnaryOperator::PostInc: - case UnaryOperator::PostDec: - case UnaryOperator::PreInc: - case UnaryOperator::PreDec: - case UnaryOperator::AddrOf: - case UnaryOperator::Deref: - return ICEDiag(2, E->getLocStart()); - case UnaryOperator::Extension: - case UnaryOperator::LNot: - case UnaryOperator::Plus: - case UnaryOperator::Minus: - case UnaryOperator::Not: - case UnaryOperator::Real: - case UnaryOperator::Imag: - return CheckICE(Exp->getSubExpr(), Ctx); - case UnaryOperator::OffsetOf: - break; - } - - // OffsetOf falls through here. - } - case Expr::OffsetOfExprClass: { - // Note that per C99, offsetof must be an ICE. And AFAIK, using - // Evaluate matches the proposed gcc behavior for cases like - // "offsetof(struct s{int x[4];}, x[!.0])". This doesn't affect - // compliance: we should warn earlier for offsetof expressions with - // array subscripts that aren't ICEs, and if the array subscripts - // are ICEs, the value of the offsetof must be an integer constant. - return CheckEvalInICE(E, Ctx); - } - case Expr::SizeOfAlignOfExprClass: { - const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(E); - if (Exp->isSizeOf() && Exp->getTypeOfArgument()->isVariableArrayType()) - return ICEDiag(2, E->getLocStart()); - return NoDiag(); - } - case Expr::BinaryOperatorClass: { - const BinaryOperator *Exp = cast<BinaryOperator>(E); - switch (Exp->getOpcode()) { - case BinaryOperator::PtrMemD: - case BinaryOperator::PtrMemI: - case BinaryOperator::Assign: - case BinaryOperator::MulAssign: - case BinaryOperator::DivAssign: - case BinaryOperator::RemAssign: - case BinaryOperator::AddAssign: - case BinaryOperator::SubAssign: - case BinaryOperator::ShlAssign: - case BinaryOperator::ShrAssign: - case BinaryOperator::AndAssign: - case BinaryOperator::XorAssign: - case BinaryOperator::OrAssign: - return ICEDiag(2, E->getLocStart()); - - case BinaryOperator::Mul: - case BinaryOperator::Div: - case BinaryOperator::Rem: - case BinaryOperator::Add: - case BinaryOperator::Sub: - case BinaryOperator::Shl: - case BinaryOperator::Shr: - case BinaryOperator::LT: - case BinaryOperator::GT: - case BinaryOperator::LE: - case BinaryOperator::GE: - case BinaryOperator::EQ: - case BinaryOperator::NE: - case BinaryOperator::And: - case BinaryOperator::Xor: - case BinaryOperator::Or: - case BinaryOperator::Comma: { - ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); - ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); - if (Exp->getOpcode() == BinaryOperator::Div || - Exp->getOpcode() == BinaryOperator::Rem) { - // Evaluate gives an error for undefined Div/Rem, so make sure - // we don't evaluate one. - if (LHSResult.Val != 2 && RHSResult.Val != 2) { - llvm::APSInt REval = Exp->getRHS()->EvaluateAsInt(Ctx); - if (REval == 0) - return ICEDiag(1, E->getLocStart()); - if (REval.isSigned() && REval.isAllOnesValue()) { - llvm::APSInt LEval = Exp->getLHS()->EvaluateAsInt(Ctx); - if (LEval.isMinSignedValue()) - return ICEDiag(1, E->getLocStart()); - } - } - } - if (Exp->getOpcode() == BinaryOperator::Comma) { - if (Ctx.getLangOptions().C99) { - // C99 6.6p3 introduces a strange edge case: comma can be in an ICE - // if it isn't evaluated. - if (LHSResult.Val == 0 && RHSResult.Val == 0) - return ICEDiag(1, E->getLocStart()); - } else { - // In both C89 and C++, commas in ICEs are illegal. - return ICEDiag(2, E->getLocStart()); - } - } - if (LHSResult.Val >= RHSResult.Val) - return LHSResult; - return RHSResult; - } - case BinaryOperator::LAnd: - case BinaryOperator::LOr: { - ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); - ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); - if (LHSResult.Val == 0 && RHSResult.Val == 1) { - // Rare case where the RHS has a comma "side-effect"; we need - // to actually check the condition to see whether the side - // with the comma is evaluated. - if ((Exp->getOpcode() == BinaryOperator::LAnd) != - (Exp->getLHS()->EvaluateAsInt(Ctx) == 0)) - return RHSResult; - return NoDiag(); - } - - if (LHSResult.Val >= RHSResult.Val) - return LHSResult; - return RHSResult; - } - } - } - case Expr::ImplicitCastExprClass: - case Expr::CStyleCastExprClass: - case Expr::CXXFunctionalCastExprClass: - case Expr::CXXStaticCastExprClass: - case Expr::CXXReinterpretCastExprClass: - case Expr::CXXConstCastExprClass: { - const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr(); - if (SubExpr->getType()->isIntegralType()) - return CheckICE(SubExpr, Ctx); - if (isa<FloatingLiteral>(SubExpr->IgnoreParens())) - return NoDiag(); - return ICEDiag(2, E->getLocStart()); - } - case Expr::ConditionalOperatorClass: { - const ConditionalOperator *Exp = cast<ConditionalOperator>(E); - // If the condition (ignoring parens) is a __builtin_constant_p call, - // then only the true side is actually considered in an integer constant - // expression, and it is fully evaluated. This is an important GNU - // extension. See GCC PR38377 for discussion. - if (const CallExpr *CallCE - = dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts())) - if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) { - Expr::EvalResult EVResult; - if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects || - !EVResult.Val.isInt()) { - return ICEDiag(2, E->getLocStart()); - } - return NoDiag(); - } - ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx); - ICEDiag TrueResult = CheckICE(Exp->getTrueExpr(), Ctx); - ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); - if (CondResult.Val == 2) - return CondResult; - if (TrueResult.Val == 2) - return TrueResult; - if (FalseResult.Val == 2) - return FalseResult; - if (CondResult.Val == 1) - return CondResult; - if (TrueResult.Val == 0 && FalseResult.Val == 0) - return NoDiag(); - // Rare case where the diagnostics depend on which side is evaluated - // Note that if we get here, CondResult is 0, and at least one of - // TrueResult and FalseResult is non-zero. - if (Exp->getCond()->EvaluateAsInt(Ctx) == 0) { - return FalseResult; - } - return TrueResult; - } - case Expr::CXXDefaultArgExprClass: - return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx); - case Expr::ChooseExprClass: { - return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(Ctx), Ctx); - } - } - - // Silence a GCC warning - return ICEDiag(2, E->getLocStart()); -} - -bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, - SourceLocation *Loc, bool isEvaluated) const { - ICEDiag d = CheckICE(this, Ctx); - if (d.Val != 0) { - if (Loc) *Loc = d.Loc; - return false; - } - EvalResult EvalResult; - if (!Evaluate(EvalResult, Ctx)) - llvm_unreachable("ICE cannot be evaluated!"); - assert(!EvalResult.HasSideEffects && "ICE with side effects!"); - assert(EvalResult.Val.isInt() && "ICE that isn't integer!"); - Result = EvalResult.Val.getInt(); - return true; -} - /// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an /// integer constant expression with the value zero, or if this is one that is /// cast to void*. @@ -2433,9 +2080,9 @@ ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { break; case Class: - if (const ObjCInterfaceType *Iface - = getClassReceiver()->getAs<ObjCInterfaceType>()) - return Iface->getDecl(); + if (const ObjCObjectType *Ty + = getClassReceiver()->getAs<ObjCObjectType>()) + return Ty->getInterface(); break; case SuperInstance: @@ -2712,7 +2359,9 @@ Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; } // ObjCImplicitSetterGetterRefExpr Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() { - return &Base; + // If this is accessing a class member, skip that entry. + if (Base) return &Base; + return &Base+1; } Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() { return &Base+1; |