zcov: / lib/AST/ExprConstant.cpp


Files: 1 Branches Taken: 70.0% 573 / 818
Generated: 2010-02-10 01:31 Branches Executed: 90.5% 740 / 818
Line Coverage: 82.6% 856 / 1036


Programs: 2 Runs 3018


       1                 : //===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This file implements the Expr constant evaluator.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/AST/APValue.h"
      15                 : #include "clang/AST/ASTContext.h"
      16                 : #include "clang/AST/CharUnits.h"
      17                 : #include "clang/AST/RecordLayout.h"
      18                 : #include "clang/AST/StmtVisitor.h"
      19                 : #include "clang/AST/ASTDiagnostic.h"
      20                 : #include "clang/Basic/Builtins.h"
      21                 : #include "clang/Basic/TargetInfo.h"
      22                 : #include "llvm/ADT/SmallString.h"
      23                 : #include <cstring>
      24                 : 
      25                 : using namespace clang;
      26                 : using llvm::APSInt;
      27                 : using llvm::APFloat;
      28                 : 
      29                 : /// EvalInfo - This is a private struct used by the evaluator to capture
      30                 : /// information about a subexpression as it is folded.  It retains information
      31                 : /// about the AST context, but also maintains information about the folded
      32                 : /// expression.
      33                 : ///
      34                 : /// If an expression could be evaluated, it is still possible it is not a C
      35                 : /// "integer constant expression" or constant expression.  If not, this struct
      36                 : /// captures information about how and why not.
      37                 : ///
      38                 : /// One bit of information passed *into* the request for constant folding
      39                 : /// indicates whether the subexpression is "evaluated" or not according to C
      40                 : /// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
      41                 : /// evaluate the expression regardless of what the RHS is, but C only allows
      42                 : /// certain things in certain situations.
      43                 : struct EvalInfo {
      44                 :   ASTContext &Ctx;
      45                 : 
      46                 :   /// EvalResult - Contains information about the evaluation.
      47                 :   Expr::EvalResult &EvalResult;
      48                 : 
      49                 :   /// AnyLValue - Stack based LValue results are not discarded.
      50                 :   bool AnyLValue;
      51                 : 
      52                 :   EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult,
      53            26184:            bool anylvalue = false)
      54            26184:     : Ctx(ctx), EvalResult(evalresult), AnyLValue(anylvalue) {}
      55                 : };
      56                 : 
      57                 : 
      58                 : static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
      59                 : static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
      60                 : static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
      61                 : static bool EvaluateIntegerOrLValue(const Expr *E, APValue  &Result,
      62                 :                                     EvalInfo &Info);
      63                 : static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
      64                 : static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);
      65                 : 
      66                 : //===----------------------------------------------------------------------===//
      67                 : // Misc utilities
      68                 : //===----------------------------------------------------------------------===//
      69                 : 
      70               10: static bool EvalPointerValueAsBool(APValue& Value, bool& Result) {
      71                 :   // FIXME: Is this accurate for all kinds of bases?  If not, what would
      72                 :   // the check look like?
                        0: branch 1 not taken
                       10: branch 2 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      73               10:   Result = Value.getLValueBase() || !Value.getLValueOffset().isZero();
      74               10:   return true;
      75                 : }
      76                 : 
      77                 : static bool HandleConversionToBool(const Expr* E, bool& Result,
      78             1691:                                    EvalInfo &Info) {
                     1468: branch 3 taken
                      223: branch 4 taken
      79             1691:   if (E->getType()->isIntegralType()) {
      80             1468:     APSInt IntResult;
                      434: branch 1 taken
                     1034: branch 2 taken
      81             1468:     if (!EvaluateInteger(E, IntResult, Info))
      82              434:       return false;
      83             1034:     Result = IntResult != 0;
      84             1034:     return true;
                       22: branch 3 taken
                      201: branch 4 taken
      85              223:   } else if (E->getType()->isRealFloatingType()) {
      86               22:     APFloat FloatResult(0.0);
                       16: branch 1 taken
                        6: branch 2 taken
      87               22:     if (!EvaluateFloat(E, FloatResult, Info))
      88               16:       return false;
      89                6:     Result = !FloatResult.isZero();
      90                6:     return true;
                      192: branch 3 taken
                        9: branch 4 taken
      91              201:   } else if (E->getType()->hasPointerRepresentation()) {
      92              192:     APValue PointerResult;
                      183: branch 1 taken
                        9: branch 2 taken
      93              192:     if (!EvaluatePointer(E, PointerResult, Info))
      94              183:       return false;
      95                9:     return EvalPointerValueAsBool(PointerResult, Result);
                        4: branch 3 taken
                        5: branch 4 taken
      96                9:   } else if (E->getType()->isAnyComplexType()) {
      97                4:     APValue ComplexResult;
                        0: branch 1 not taken
                        4: branch 2 taken
      98                4:     if (!EvaluateComplex(E, ComplexResult, Info))
      99                0:       return false;
                        2: branch 1 taken
                        2: branch 2 taken
     100                4:     if (ComplexResult.isComplexFloat()) {
     101                 :       Result = !ComplexResult.getComplexFloatReal().isZero() ||
                        1: branch 2 taken
                        1: branch 3 taken
                        0: branch 6 not taken
                        1: branch 7 taken
     102                2:                !ComplexResult.getComplexFloatImag().isZero();
     103                 :     } else {
     104                 :       Result = ComplexResult.getComplexIntReal().getBoolValue() ||
                        1: branch 2 taken
                        1: branch 3 taken
                        0: branch 6 not taken
                        1: branch 7 taken
     105                2:                ComplexResult.getComplexIntImag().getBoolValue();
     106                 :     }
     107                4:     return true;
     108                 :   }
     109                 : 
     110                5:   return false;
     111                 : }
     112                 : 
     113                 : static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType,
     114               56:                                    APFloat &Value, ASTContext &Ctx) {
     115               56:   unsigned DestWidth = Ctx.getIntWidth(DestType);
     116                 :   // Determine whether we are converting to unsigned or signed.
     117               56:   bool DestSigned = DestType->isSignedIntegerType();
     118                 : 
     119                 :   // FIXME: Warning for overflow.
     120                 :   uint64_t Space[4];
     121                 :   bool ignored;
     122                 :   (void)Value.convertToInteger(Space, DestWidth, DestSigned,
     123               56:                                llvm::APFloat::rmTowardZero, &ignored);
     124               56:   return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned);
     125                 : }
     126                 : 
     127                 : static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType,
     128              147:                                       APFloat &Value, ASTContext &Ctx) {
     129                 :   bool ignored;
     130              147:   APFloat Result = Value;
     131                 :   Result.convert(Ctx.getFloatTypeSemantics(DestType),
     132              147:                  APFloat::rmNearestTiesToEven, &ignored);
     133                 :   return Result;
     134                 : }
     135                 : 
     136                 : static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType,
     137             2514:                                  APSInt &Value, ASTContext &Ctx) {
     138             2514:   unsigned DestWidth = Ctx.getIntWidth(DestType);
     139             2514:   APSInt Result = Value;
     140                 :   // Figure out if this is a truncate, extend or noop cast.
     141                 :   // If the input is signed, do a sign extend, noop, or truncate.
     142             2514:   Result.extOrTrunc(DestWidth);
     143             2514:   Result.setIsUnsigned(DestType->isUnsignedIntegerType());
     144                 :   return Result;
     145                 : }
     146                 : 
     147                 : static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType,
     148               76:                                     APSInt &Value, ASTContext &Ctx) {
     149                 : 
     150               76:   APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1);
     151                 :   Result.convertFromAPInt(Value, Value.isSigned(),
     152               76:                           APFloat::rmNearestTiesToEven);
     153                 :   return Result;
     154                 : }
     155                 : 
     156                 : namespace {
     157                 : class HasSideEffect
     158                 :   : public StmtVisitor<HasSideEffect, bool> {
     159                 :   EvalInfo &Info;
     160                 : public:
     161                 : 
     162               65:   HasSideEffect(EvalInfo &info) : Info(info) {}
     163                 : 
     164                 :   // Unhandled nodes conservatively default to having side effects.
     165               18:   bool VisitStmt(Stmt *S) {
     166               18:     return true;
     167                 :   }
     168                 : 
     169                8:   bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
     170                8:   bool VisitDeclRefExpr(DeclRefExpr *E) {
                        0: branch 3 not taken
                        8: branch 4 taken
     171                8:     if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
     172                0:       return true;
     173                8:     return false;
     174                 :   }
     175                 :   // We don't want to evaluate BlockExprs multiple times, as they generate
     176                 :   // a ton of code.
     177                0:   bool VisitBlockExpr(BlockExpr *E) { return true; }
     178                0:   bool VisitPredefinedExpr(PredefinedExpr *E) { return false; }
     179                0:   bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E)
     180                0:     { return Visit(E->getInitializer()); }
     181                0:   bool VisitMemberExpr(MemberExpr *E) { return Visit(E->getBase()); }
     182                8:   bool VisitIntegerLiteral(IntegerLiteral *E) { return false; }
     183                0:   bool VisitFloatingLiteral(FloatingLiteral *E) { return false; }
     184                5:   bool VisitStringLiteral(StringLiteral *E) { return false; }
     185                0:   bool VisitCharacterLiteral(CharacterLiteral *E) { return false; }
     186                0:   bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return false; }
     187                2:   bool VisitArraySubscriptExpr(ArraySubscriptExpr *E)
                        2: branch 2 taken
                        0: branch 3 not taken
                        2: branch 6 taken
                        0: branch 7 not taken
     188                2:     { return Visit(E->getLHS()) || Visit(E->getRHS()); }
     189                0:   bool VisitChooseExpr(ChooseExpr *E)
     190                0:     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
     191               37:   bool VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); }
     192                2:   bool VisitBinAssign(BinaryOperator *E) { return true; }
     193                2:   bool VisitCompoundAssignOperator(BinaryOperator *E) { return true; }
     194                4:   bool VisitBinaryOperator(BinaryOperator *E)
                        0: branch 2 not taken
                        4: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     195                4:   { return Visit(E->getLHS()) || Visit(E->getRHS()); }
     196               10:   bool VisitUnaryPreInc(UnaryOperator *E) { return true; }
     197               10:   bool VisitUnaryPostInc(UnaryOperator *E) { return true; }
     198                2:   bool VisitUnaryPreDec(UnaryOperator *E) { return true; }
     199                2:   bool VisitUnaryPostDec(UnaryOperator *E) { return true; }
     200                2:   bool VisitUnaryDeref(UnaryOperator *E) {
                        0: branch 3 not taken
                        2: branch 4 taken
     201                2:     if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified())
     202                0:       return true;
     203                2:     return Visit(E->getSubExpr());
     204                 :   }
     205                0:   bool VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); }
     206                 : };
     207                 : 
     208                 : } // end anonymous namespace
     209                 : 
     210                 : //===----------------------------------------------------------------------===//
     211                 : // LValue Evaluation
     212                 : //===----------------------------------------------------------------------===//
     213                 : namespace {
     214                 : class LValueExprEvaluator
     215                 :   : public StmtVisitor<LValueExprEvaluator, APValue> {
     216                 :   EvalInfo &Info;
     217                 : public:
     218                 : 
     219              748:   LValueExprEvaluator(EvalInfo &info) : Info(info) {}
     220                 : 
     221                0:   APValue VisitStmt(Stmt *S) {
     222                0:     return APValue();
     223                 :   }
     224                 : 
     225                4:   APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
     226                 :   APValue VisitDeclRefExpr(DeclRefExpr *E);
     227                6:   APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E); }
     228                 :   APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
     229                 :   APValue VisitMemberExpr(MemberExpr *E);
     230               51:   APValue VisitStringLiteral(StringLiteral *E) { return APValue(E); }
     231               14:   APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E); }
     232                 :   APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E);
     233                 :   APValue VisitUnaryDeref(UnaryOperator *E);
     234                0:   APValue VisitUnaryExtension(const UnaryOperator *E)
     235                0:     { return Visit(E->getSubExpr()); }
     236                0:   APValue VisitChooseExpr(const ChooseExpr *E)
     237                0:     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
     238                 : 
     239                3:   APValue VisitCastExpr(CastExpr *E) {
                        1: branch 1 taken
                        2: branch 2 taken
     240                3:     switch (E->getCastKind()) {
     241                 :     default:
     242                1:       return APValue();
     243                 : 
     244                 :     case CastExpr::CK_NoOp:
     245                2:       return Visit(E->getSubExpr());
     246                 :     }
     247                 :   }
     248                 :   // FIXME: Missing: __real__, __imag__
     249                 : };
     250                 : } // end anonymous namespace
     251                 : 
     252              748: static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) {
     253              748:   Result = LValueExprEvaluator(Info).Visit(const_cast<Expr*>(E));
     254              748:   return Result.isLValue();
     255                 : }
     256                 : 
     257              352: APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) {
                       73: branch 2 taken
                      279: branch 3 taken
     258              352:   if (isa<FunctionDecl>(E->getDecl())) {
     259               73:     return APValue(E);
                      279: branch 2 taken
                        0: branch 3 not taken
     260              279:   } else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) {
                      248: branch 0 taken
                       31: branch 1 taken
                       20: branch 3 taken
                      228: branch 4 taken
                       20: branch 5 taken
                      259: branch 6 taken
     261              279:     if (!Info.AnyLValue && !VD->hasGlobalStorage())
     262               20:       return APValue();
                      258: branch 3 taken
                        1: branch 4 taken
     263              259:     if (!VD->getType()->isReferenceType())
     264              258:       return APValue(E);
     265                 :     // FIXME: Check whether VD might be overridden!
                        1: branch 1 taken
                        0: branch 2 not taken
     266                1:     if (const Expr *Init = VD->getAnyInitializer())
     267                1:       return Visit(const_cast<Expr *>(Init));
     268                 :   }
     269                 : 
     270                0:   return APValue();
     271                 : }
     272                 : 
     273               12: APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
                       12: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                       12: branch 4 taken
                        0: branch 5 not taken
                       12: branch 6 taken
     274               12:   if (!Info.AnyLValue && !E->isFileScope())
     275                0:     return APValue();
     276               12:   return APValue(E);
     277                 : }
     278                 : 
     279              306: APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
     280              306:   APValue result;
     281              306:   QualType Ty;
                       10: branch 1 taken
                      296: branch 2 taken
     282              306:   if (E->isArrow()) {
                        0: branch 2 not taken
                       10: branch 3 taken
     283               10:     if (!EvaluatePointer(E->getBase(), result, Info))
     284                0:       return APValue();
     285               10:     Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType();
     286                 :   } else {
     287              296:     result = Visit(E->getBase());
                        5: branch 1 taken
                      291: branch 2 taken
     288              296:     if (result.isUninit())
     289                5:       return APValue();
     290              291:     Ty = E->getBase()->getType();
     291                 :   }
     292                 : 
     293              301:   RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
     294              301:   const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
     295                 : 
     296              301:   FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
                        0: branch 0 not taken
                      301: branch 1 taken
     297              301:   if (!FD) // FIXME: deal with other kinds of member expressions
     298                0:     return APValue();
     299                 : 
                        2: branch 3 taken
                      299: branch 4 taken
     300              301:   if (FD->getType()->isReferenceType())
     301                2:     return APValue();
     302                 : 
     303                 :   // FIXME: This is linear time.
     304              299:   unsigned i = 0;
                      439: branch 3 taken
                        0: branch 4 not taken
     305              738:   for (RecordDecl::field_iterator Field = RD->field_begin(),
     306              299:                                FieldEnd = RD->field_end();
     307                 :        Field != FieldEnd; (void)++Field, ++i) {
                      299: branch 1 taken
                      140: branch 2 taken
     308              439:     if (*Field == FD)
     309              299:       break;
     310                 :   }
     311                 : 
     312                 :   result.setLValue(result.getLValueBase(),
     313                 :                    result.getLValueOffset() + 
     314              299:                        CharUnits::fromQuantity(RL.getFieldOffset(i) / 8));
     315                 : 
     316              299:   return result;
     317                 : }
     318                 : 
     319               50: APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
     320               50:   APValue Result;
     321                 : 
                        6: branch 2 taken
                       44: branch 3 taken
     322               50:   if (!EvaluatePointer(E->getBase(), Result, Info))
     323                6:     return APValue();
     324                 : 
     325               44:   APSInt Index;
                        2: branch 2 taken
                       42: branch 3 taken
     326               44:   if (!EvaluateInteger(E->getIdx(), Index, Info))
     327                2:     return APValue();
     328                 : 
     329               42:   CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType());
     330                 : 
     331               42:   CharUnits Offset = Index.getSExtValue() * ElementSize;
     332                 :   Result.setLValue(Result.getLValueBase(),
     333               42:                    Result.getLValueOffset() + Offset);
     334               42:   return Result;
     335                 : }
     336                 : 
     337              253: APValue LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) {
     338              253:   APValue Result;
                        2: branch 2 taken
                      251: branch 3 taken
     339              253:   if (!EvaluatePointer(E->getSubExpr(), Result, Info))
     340                2:     return APValue();
     341              251:   return Result;
     342                 : }
     343                 : 
     344                 : //===----------------------------------------------------------------------===//
     345                 : // Pointer Evaluation
     346                 : //===----------------------------------------------------------------------===//
     347                 : 
     348                 : namespace {
     349                 : class PointerExprEvaluator
     350                 :   : public StmtVisitor<PointerExprEvaluator, APValue> {
     351                 :   EvalInfo &Info;
     352                 : public:
     353                 : 
     354             2845:   PointerExprEvaluator(EvalInfo &info) : Info(info) {}
     355                 : 
     356             1642:   APValue VisitStmt(Stmt *S) {
     357             1642:     return APValue();
     358                 :   }
     359                 : 
     360              190:   APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
     361                 : 
     362                 :   APValue VisitBinaryOperator(const BinaryOperator *E);
     363                 :   APValue VisitCastExpr(CastExpr* E);
     364                1:   APValue VisitUnaryExtension(const UnaryOperator *E)
     365                1:       { return Visit(E->getSubExpr()); }
     366                 :   APValue VisitUnaryAddrOf(const UnaryOperator *E);
     367               10:   APValue VisitObjCStringLiteral(ObjCStringLiteral *E)
     368               10:       { return APValue(E); }
     369               30:   APValue VisitAddrLabelExpr(AddrLabelExpr *E)
     370               30:       { return APValue(E); }
     371                 :   APValue VisitCallExpr(CallExpr *E);
     372               16:   APValue VisitBlockExpr(BlockExpr *E) {
                       15: branch 1 taken
                        1: branch 2 taken
     373               16:     if (!E->hasBlockDeclRefExprs())
     374               15:       return APValue(E);
     375                1:     return APValue();
     376                 :   }
     377              250:   APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E)
     378              250:       { return APValue((Expr*)0); }
     379                 :   APValue VisitConditionalOperator(ConditionalOperator *E);
     380                1:   APValue VisitChooseExpr(ChooseExpr *E)
     381                1:       { return Visit(E->getChosenSubExpr(Info.Ctx)); }
     382                1:   APValue VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E)
     383                1:       { return APValue((Expr*)0); }
     384                 :   // FIXME: Missing: @protocol, @selector
     385                 : };
     386                 : } // end anonymous namespace
     387                 : 
     388             2845: static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
                        0: branch 3 not taken
                     2845: branch 4 taken
     389             2845:   if (!E->getType()->hasPointerRepresentation())
     390                0:     return false;
     391             2845:   Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
     392             2845:   return Result.isLValue();
     393                 : }
     394                 : 
     395               96: APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
                       53: branch 1 taken
                       43: branch 2 taken
                       47: branch 4 taken
                        6: branch 5 taken
                       47: branch 6 taken
                       49: branch 7 taken
     396               96:   if (E->getOpcode() != BinaryOperator::Add &&
     397                 :       E->getOpcode() != BinaryOperator::Sub)
     398               47:     return APValue();
     399                 : 
     400               49:   const Expr *PExp = E->getLHS();
     401               49:   const Expr *IExp = E->getRHS();
                        1: branch 3 taken
                       48: branch 4 taken
     402               49:   if (IExp->getType()->isPointerType())
     403                1:     std::swap(PExp, IExp);
     404                 : 
     405               49:   APValue ResultLValue;
                        5: branch 1 taken
                       44: branch 2 taken
     406               49:   if (!EvaluatePointer(PExp, ResultLValue, Info))
     407                5:     return APValue();
     408                 : 
     409               44:   llvm::APSInt AdditionalOffset(32);
                        0: branch 1 not taken
                       44: branch 2 taken
     410               44:   if (!EvaluateInteger(IExp, AdditionalOffset, Info))
     411                0:     return APValue();
     412                 : 
     413               44:   QualType PointeeType = PExp->getType()->getAs<PointerType>()->getPointeeType();
     414               44:   CharUnits SizeOfPointee;
     415                 : 
     416                 :   // Explicitly handle GNU void* and function pointer arithmetic extensions.
                       41: branch 2 taken
                        3: branch 3 taken
                        0: branch 6 not taken
                       41: branch 7 taken
                        3: branch 8 taken
                       41: branch 9 taken
     417               44:   if (PointeeType->isVoidType() || PointeeType->isFunctionType())
     418                3:     SizeOfPointee = CharUnits::One();
     419                 :   else
     420               41:     SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType);
     421                 : 
     422               44:   CharUnits Offset = ResultLValue.getLValueOffset();
     423                 : 
                       38: branch 1 taken
                        6: branch 2 taken
     424               44:   if (E->getOpcode() == BinaryOperator::Add)
     425               38:     Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee;
     426                 :   else
     427                6:     Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee;
     428                 : 
     429               44:   return APValue(ResultLValue.getLValueBase(), Offset);
     430                 : }
     431                 : 
     432              271: APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
     433              271:   APValue result;
                      249: branch 2 taken
                       22: branch 3 taken
     434              271:   if (EvaluateLValue(E->getSubExpr(), result, Info))
     435              249:     return result;
     436               22:   return APValue();
     437                 : }
     438                 : 
     439                 : 
     440              739: APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
     441              739:   Expr* SubExpr = E->getSubExpr();
     442                 : 
                       22: branch 1 taken
                      266: branch 2 taken
                       91: branch 3 taken
                      142: branch 4 taken
                      218: branch 5 taken
     443              739:   switch (E->getCastKind()) {
     444                 :   default:
     445               22:     break;
     446                 : 
     447                 :   case CastExpr::CK_Unknown: {
     448                 :     // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary!
     449                 : 
     450                 :     // Check for pointer->pointer cast
                       88: branch 3 taken
                      178: branch 4 taken
                       68: branch 8 taken
                       20: branch 9 taken
                       67: branch 13 taken
                        1: branch 14 taken
                        8: branch 18 taken
                       59: branch 19 taken
                      207: branch 20 taken
                       59: branch 21 taken
     451              266:     if (SubExpr->getType()->isPointerType() ||
     452                 :         SubExpr->getType()->isObjCObjectPointerType() ||
     453                 :         SubExpr->getType()->isNullPtrType() ||
     454                 :         SubExpr->getType()->isBlockPointerType())
     455              207:       return Visit(SubExpr);
     456                 : 
                       59: branch 3 taken
                        0: branch 4 not taken
     457               59:     if (SubExpr->getType()->isIntegralType()) {
     458               59:       APValue Result;
                        0: branch 1 not taken
                       59: branch 2 taken
     459               59:       if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
     460                0:         break;
     461                 : 
                       59: branch 1 taken
                        0: branch 2 not taken
     462               59:       if (Result.isInt()) {
     463               59:         Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
     464                 :         return APValue(0, 
     465              118:                        CharUnits::fromQuantity(Result.getInt().getZExtValue()));
     466                 :       }
     467                 : 
     468                 :       // Cast is of an lvalue, no need to change value.
                        0: branch 2 not taken
                       59: branch 3 taken
     469                0:       return Result;
     470                 :     }
     471                0:     break;
     472                 :   }
     473                 : 
     474                 :   case CastExpr::CK_NoOp:
     475                 :   case CastExpr::CK_BitCast:
     476                 :   case CastExpr::CK_AnyPointerToObjCPointerCast:
     477                 :   case CastExpr::CK_AnyPointerToBlockPointerCast:
     478               91:     return Visit(SubExpr);
     479                 : 
     480                 :   case CastExpr::CK_IntegralToPointer: {
     481              142:     APValue Result;
                        2: branch 1 taken
                      140: branch 2 taken
     482              142:     if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
     483                2:       break;
     484                 : 
                      137: branch 1 taken
                        3: branch 2 taken
     485              140:     if (Result.isInt()) {
     486              137:       Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
     487                 :       return APValue(0, 
     488              277:                      CharUnits::fromQuantity(Result.getInt().getZExtValue()));
     489                 :     }
     490                 : 
     491                 :     // Cast is of an lvalue, no need to change value.
                        2: branch 2 taken
                      140: branch 3 taken
     492                3:     return Result;
     493                 :   }
     494                 :   case CastExpr::CK_ArrayToPointerDecay:
     495                 :   case CastExpr::CK_FunctionToPointerDecay: {
     496              218:     APValue Result;
                      212: branch 1 taken
                        6: branch 2 taken
     497              218:     if (EvaluateLValue(SubExpr, Result, Info))
     498              424:       return Result;
                      212: branch 1 taken
                        6: branch 2 taken
     499              224:     break;
     500                 :   }
     501                 :   }
     502                 : 
     503               30:   return APValue();
     504                 : }
     505                 : 
     506               72: APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) {
                       50: branch 1 taken
                       22: branch 2 taken
                        0: branch 4 not taken
                       50: branch 5 taken
                       22: branch 6 taken
                       50: branch 7 taken
     507               72:   if (E->isBuiltinCall(Info.Ctx) ==
     508                 :         Builtin::BI__builtin___CFStringMakeConstantString ||
     509                 :       E->isBuiltinCall(Info.Ctx) ==
     510                 :         Builtin::BI__builtin___NSStringMakeConstantString)
     511               22:     return APValue(E);
     512               50:   return APValue();
     513                 : }
     514                 : 
     515               16: APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
     516                 :   bool BoolResult;
                        0: branch 2 not taken
                       16: branch 3 taken
     517               16:   if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
     518                0:     return APValue();
     519                 : 
                        6: branch 0 taken
                       10: branch 1 taken
     520               16:   Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
     521                 : 
     522               16:   APValue Result;
                       16: branch 1 taken
                        0: branch 2 not taken
     523               16:   if (EvaluatePointer(EvalExpr, Result, Info))
     524               16:     return Result;
     525                0:   return APValue();
     526                 : }
     527                 : 
     528                 : //===----------------------------------------------------------------------===//
     529                 : // Vector Evaluation
     530                 : //===----------------------------------------------------------------------===//
     531                 : 
     532                 : namespace {
     533                 :   class VectorExprEvaluator
     534                 :   : public StmtVisitor<VectorExprEvaluator, APValue> {
     535                 :     EvalInfo &Info;
     536                 :     APValue GetZeroVector(QualType VecType);
     537                 :   public:
     538                 : 
     539              744:     VectorExprEvaluator(EvalInfo &info) : Info(info) {}
     540                 : 
     541              732:     APValue VisitStmt(Stmt *S) {
     542              732:       return APValue();
     543                 :     }
     544                 : 
     545                0:     APValue VisitParenExpr(ParenExpr *E)
     546                0:         { return Visit(E->getSubExpr()); }
     547                0:     APValue VisitUnaryExtension(const UnaryOperator *E)
     548                0:       { return Visit(E->getSubExpr()); }
     549                0:     APValue VisitUnaryPlus(const UnaryOperator *E)
     550                0:       { return Visit(E->getSubExpr()); }
     551                1:     APValue VisitUnaryReal(const UnaryOperator *E)
     552                1:       { return Visit(E->getSubExpr()); }
     553                0:     APValue VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
     554                0:       { return GetZeroVector(E->getType()); }
     555                 :     APValue VisitCastExpr(const CastExpr* E);
     556                 :     APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
     557                 :     APValue VisitInitListExpr(const InitListExpr *E);
     558                 :     APValue VisitConditionalOperator(const ConditionalOperator *E);
     559                1:     APValue VisitChooseExpr(const ChooseExpr *E)
     560                1:       { return Visit(E->getChosenSubExpr(Info.Ctx)); }
     561                 :     APValue VisitUnaryImag(const UnaryOperator *E);
     562                 :     // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div,
     563                 :     //                 binary comparisons, binary and/or/xor,
     564                 :     //                 shufflevector, ExtVectorElementExpr
     565                 :     //        (Note that these require implementing conversions
     566                 :     //         between vector types.)
     567                 :   };
     568                 : } // end anonymous namespace
     569                 : 
     570              744: static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
                        0: branch 3 not taken
                      744: branch 4 taken
     571              744:   if (!E->getType()->isVectorType())
     572                0:     return false;
     573              744:   Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E));
     574              744:   return !Result.isUninit();
     575                 : }
     576                 : 
     577                3: APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
     578                3:   const VectorType *VTy = E->getType()->getAs<VectorType>();
     579                3:   QualType EltTy = VTy->getElementType();
     580                3:   unsigned NElts = VTy->getNumElements();
     581                3:   unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
     582                 : 
     583                3:   const Expr* SE = E->getSubExpr();
     584                3:   QualType SETy = SE->getType();
     585                3:   APValue Result = APValue();
     586                 : 
     587                 :   // Check for vector->vector bitcast and scalar->vector splat.
                        2: branch 2 taken
                        1: branch 3 taken
     588                3:   if (SETy->isVectorType()) {
     589                2:     return this->Visit(const_cast<Expr*>(SE));
                        0: branch 2 not taken
                        1: branch 3 taken
     590                1:   } else if (SETy->isIntegerType()) {
     591                0:     APSInt IntResult;
                        0: branch 1 not taken
                        0: branch 2 not taken
     592                0:     if (!EvaluateInteger(SE, IntResult, Info))
     593                0:       return APValue();
                        0: branch 4 not taken
                        0: branch 5 not taken
     594                0:     Result = APValue(IntResult);
                        1: branch 2 taken
                        0: branch 3 not taken
     595                1:   } else if (SETy->isRealFloatingType()) {
     596                1:     APFloat F(0.0);
                        0: branch 1 not taken
                        1: branch 2 taken
     597                1:     if (!EvaluateFloat(SE, F, Info))
     598                0:       return APValue();
                        1: branch 4 taken
                        0: branch 5 not taken
     599                1:     Result = APValue(F);
     600                 :   } else
     601                0:     return APValue();
     602                 : 
     603                 :   // For casts of a scalar to ExtVector, convert the scalar to the element type
     604                 :   // and splat it to all elements.
                        1: branch 3 taken
                        0: branch 4 not taken
     605                1:   if (E->getType()->isExtVectorType()) {
                        0: branch 2 not taken
                        1: branch 3 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        1: branch 8 taken
     606                1:     if (EltTy->isIntegerType() && Result.isInt())
     607                 :       Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(),
     608                0:                                           Info.Ctx));
                        0: branch 2 not taken
                        1: branch 3 taken
     609                1:     else if (EltTy->isIntegerType())
     610                 :       Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(),
     611                0:                                             Info.Ctx));
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
     612                1:     else if (EltTy->isRealFloatingType() && Result.isInt())
     613                 :       Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(),
     614                0:                                             Info.Ctx));
                        1: branch 2 taken
                        0: branch 3 not taken
     615                1:     else if (EltTy->isRealFloatingType())
     616                 :       Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(),
     617                1:                                               Info.Ctx));
     618                 :     else
     619                0:       return APValue();
     620                 : 
     621                 :     // Splat and create vector APValue.
     622                1:     llvm::SmallVector<APValue, 4> Elts(NElts, Result);
     623                1:     return APValue(&Elts[0], Elts.size());
     624                 :   }
     625                 : 
     626                 :   // For casts of a scalar to regular gcc-style vector type, bitcast the scalar
     627                 :   // to the vector. To construct the APValue vector initializer, bitcast the
     628                 :   // initializing value to an APInt, and shift out the bits pertaining to each
     629                 :   // element.
     630                0:   APSInt Init;
                        0: branch 1 not taken
                        0: branch 2 not taken
     631                0:   Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt();
     632                 : 
     633                0:   llvm::SmallVector<APValue, 4> Elts;
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
     634                0:   for (unsigned i = 0; i != NElts; ++i) {
     635                0:     APSInt Tmp = Init;
     636                0:     Tmp.extOrTrunc(EltWidth);
     637                 : 
                        0: branch 2 not taken
                        0: branch 3 not taken
     638                0:     if (EltTy->isIntegerType())
     639                0:       Elts.push_back(APValue(Tmp));
                        0: branch 2 not taken
                        0: branch 3 not taken
     640                0:     else if (EltTy->isRealFloatingType())
     641                0:       Elts.push_back(APValue(APFloat(Tmp)));
     642                 :     else
     643                0:       return APValue();
     644                 : 
     645                0:     Init >>= EltWidth;
     646                 :   }
     647                0:   return APValue(&Elts[0], Elts.size());
     648                 : }
     649                 : 
     650                 : APValue
     651                7: VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
     652                7:   return this->Visit(const_cast<Expr*>(E->getInitializer()));
     653                 : }
     654                 : 
     655                 : APValue
     656                9: VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
     657                9:   const VectorType *VT = E->getType()->getAs<VectorType>();
     658                9:   unsigned NumInits = E->getNumInits();
     659                9:   unsigned NumElements = VT->getNumElements();
     660                 : 
     661                9:   QualType EltTy = VT->getElementType();
     662                9:   llvm::SmallVector<APValue, 4> Elements;
     663                 : 
                       36: branch 0 taken
                        9: branch 1 taken
     664               45:   for (unsigned i = 0; i < NumElements; i++) {
                       24: branch 2 taken
                       12: branch 3 taken
     665               36:     if (EltTy->isIntegerType()) {
     666               24:       llvm::APSInt sInt(32);
                       11: branch 0 taken
                       13: branch 1 taken
     667               24:       if (i < NumInits) {
                        0: branch 2 not taken
                       11: branch 3 taken
     668               11:         if (!EvaluateInteger(E->getInit(i), sInt, Info))
     669                0:           return APValue();
     670                 :       } else {
     671               13:         sInt = Info.Ctx.MakeIntValue(0, EltTy);
     672                 :       }
                       24: branch 4 taken
                        0: branch 5 not taken
     673               24:       Elements.push_back(APValue(sInt));
     674                 :     } else {
     675               12:       llvm::APFloat f(0.0);
                       12: branch 0 taken
                        0: branch 1 not taken
     676               12:       if (i < NumInits) {
                        0: branch 2 not taken
                       12: branch 3 taken
     677               12:         if (!EvaluateFloat(E->getInit(i), f, Info))
     678                0:           return APValue();
     679                 :       } else {
     680                0:         f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
     681                 :       }
                       12: branch 4 taken
                        0: branch 5 not taken
     682               12:       Elements.push_back(APValue(f));
     683                 :     }
     684                 :   }
     685                9:   return APValue(&Elements[0], Elements.size());
     686                 : }
     687                 : 
     688                 : APValue
     689                1: VectorExprEvaluator::GetZeroVector(QualType T) {
     690                1:   const VectorType *VT = T->getAs<VectorType>();
     691                1:   QualType EltTy = VT->getElementType();
     692                1:   APValue ZeroElement;
                        1: branch 2 taken
                        0: branch 3 not taken
     693                1:   if (EltTy->isIntegerType())
     694                1:     ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy));
     695                 :   else
     696                 :     ZeroElement =
     697                0:         APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
     698                 : 
     699                1:   llvm::SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement);
     700                1:   return APValue(&Elements[0], Elements.size());
     701                 : }
     702                 : 
     703                1: APValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
     704                 :   bool BoolResult;
                        0: branch 2 not taken
                        1: branch 3 taken
     705                1:   if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
     706                0:     return APValue();
     707                 : 
                        1: branch 0 taken
                        0: branch 1 not taken
     708                1:   Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();
     709                 : 
     710                1:   APValue Result;
                        1: branch 1 taken
                        0: branch 2 not taken
     711                1:   if (EvaluateVector(EvalExpr, Result, Info))
     712                1:     return Result;
     713                0:   return APValue();
     714                 : }
     715                 : 
     716                1: APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
                        0: branch 2 not taken
                        1: branch 3 taken
     717                1:   if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
     718                0:     Info.EvalResult.HasSideEffects = true;
     719                1:   return GetZeroVector(E->getType());
     720                 : }
     721                 : 
     722                 : //===----------------------------------------------------------------------===//
     723                 : // Integer Evaluation
     724                 : //===----------------------------------------------------------------------===//
     725                 : 
     726                 : namespace {
     727                 : class IntExprEvaluator
     728                 :   : public StmtVisitor<IntExprEvaluator, bool> {
     729                 :   EvalInfo &Info;
     730                 :   APValue &Result;
     731                 : public:
     732            26549:   IntExprEvaluator(EvalInfo &info, APValue &result)
     733            26549:     : Info(info), Result(result) {}
     734                 : 
     735             5887:   bool Success(const llvm::APSInt &SI, const Expr *E) {
                     5887: branch 3 taken
                        0: branch 4 not taken
     736             5887:     assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
     737                 :     assert(SI.isSigned() == E->getType()->isSignedIntegerType() &&
                     5887: branch 4 taken
                        0: branch 5 not taken
     738             5887:            "Invalid evaluation result.");
     739                 :     assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
                     5887: branch 3 taken
                        0: branch 4 not taken
     740             5887:            "Invalid evaluation result.");
     741             5887:     Result = APValue(SI);
     742             5887:     return true;
     743                 :   }
     744                 : 
     745            16527:   bool Success(const llvm::APInt &I, const Expr *E) {
                    16527: branch 3 taken
                        0: branch 4 not taken
     746            16527:     assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
     747                 :     assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
                    16527: branch 3 taken
                        0: branch 4 not taken
     748            16527:            "Invalid evaluation result.");
     749            16527:     Result = APValue(APSInt(I));
     750            16527:     Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerType());
     751            16527:     return true;
     752                 :   }
     753                 : 
     754             2734:   bool Success(uint64_t Value, const Expr *E) {
                     2734: branch 3 taken
                        0: branch 4 not taken
     755             2734:     assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
     756             2734:     Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
     757             2734:     return true;
     758                 :   }
     759                 : 
     760             5029:   bool Error(SourceLocation L, diag::kind D, const Expr *E) {
     761                 :     // Take the first error.
                     4998: branch 0 taken
                       31: branch 1 taken
     762             5029:     if (Info.EvalResult.Diag == 0) {
     763             4998:       Info.EvalResult.DiagLoc = L;
     764             4998:       Info.EvalResult.Diag = D;
     765             4998:       Info.EvalResult.DiagExpr = E;
     766                 :     }
     767             5029:     return false;
     768                 :   }
     769                 : 
     770                 :   //===--------------------------------------------------------------------===//
     771                 :   //                            Visitor Methods
     772                 :   //===--------------------------------------------------------------------===//
     773                 : 
     774                0:   bool VisitStmt(Stmt *) {
     775                0:     assert(0 && "This should be called on integers, stmts are not integers");
     776                 :     return false;
     777                 :   }
     778                 : 
     779              410:   bool VisitExpr(Expr *E) {
     780              410:     return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
     781                 :   }
     782                 : 
     783             1375:   bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
     784                 : 
     785            16527:   bool VisitIntegerLiteral(const IntegerLiteral *E) {
     786            16527:     return Success(E->getValue(), E);
     787                 :   }
     788              195:   bool VisitCharacterLiteral(const CharacterLiteral *E) {
     789              195:     return Success(E->getValue(), E);
     790                 :   }
     791               12:   bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
     792                 :     // Per gcc docs "this built-in function ignores top level
     793                 :     // qualifiers".  We need to use the canonical version to properly
     794                 :     // be able to strip CRV qualifiers from the type.
     795               12:     QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
     796               12:     QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
     797                 :     return Success(Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(),
     798                 :                                                T1.getUnqualifiedType()),
     799               12:                    E);
     800                 :   }
     801                 : 
     802                 :   bool CheckReferencedDecl(const Expr *E, const Decl *D);
     803             5113:   bool VisitDeclRefExpr(const DeclRefExpr *E) {
     804             5113:     return CheckReferencedDecl(E, E->getDecl());
     805                 :   }
     806              457:   bool VisitMemberExpr(const MemberExpr *E) {
                        5: branch 2 taken
                      452: branch 3 taken
     807              457:     if (CheckReferencedDecl(E, E->getMemberDecl())) {
     808                 :       // Conservatively assume a MemberExpr will have side-effects
     809                5:       Info.EvalResult.HasSideEffects = true;
     810                5:       return true;
     811                 :     }
     812              452:     return false;
     813                 :   }
     814                 : 
     815                 :   bool VisitCallExpr(const CallExpr *E);
     816                 :   bool VisitBinaryOperator(const BinaryOperator *E);
     817                 :   bool VisitUnaryOperator(const UnaryOperator *E);
     818                 :   bool VisitConditionalOperator(const ConditionalOperator *E);
     819                 : 
     820                 :   bool VisitCastExpr(CastExpr* E);
     821                 :   bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
     822                 : 
     823              302:   bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
     824              302:     return Success(E->getValue(), E);
     825                 :   }
     826                 : 
     827                7:   bool VisitGNUNullExpr(const GNUNullExpr *E) {
     828                7:     return Success(0, E);
     829                 :   }
     830                 : 
     831                4:   bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
     832                4:     return Success(0, E);
     833                 :   }
     834                 : 
     835                6:   bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
     836                6:     return Success(0, E);
     837                 :   }
     838                 : 
     839              334:   bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
     840              334:     return Success(E->EvaluateTrait(Info.Ctx), E);
     841                 :   }
     842                 : 
     843                1:   bool VisitChooseExpr(const ChooseExpr *E) {
     844                1:     return Visit(E->getChosenSubExpr(Info.Ctx));
     845                 :   }
     846                 : 
     847                 :   bool VisitUnaryReal(const UnaryOperator *E);
     848                 :   bool VisitUnaryImag(const UnaryOperator *E);
     849                 : 
     850                 : private:
     851                 :   CharUnits GetAlignOfExpr(const Expr *E);
     852                 :   CharUnits GetAlignOfType(QualType T);
     853                 :   // FIXME: Missing: array subscript of vector, member of vector
     854                 : };
     855                 : } // end anonymous namespace
     856                 : 
     857             4141: static bool EvaluateIntegerOrLValue(const Expr* E, APValue &Result, EvalInfo &Info) {
                        0: branch 3 not taken
                     4141: branch 4 taken
     858             4141:   if (!E->getType()->isIntegralType())
     859                0:     return false;
     860                 : 
     861             4141:   return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
     862                 : }
     863                 : 
     864             1700: static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
     865             1700:   APValue Val;
                     1260: branch 1 taken
                      440: branch 2 taken
                        1: branch 4 taken
                     1259: branch 5 taken
                      441: branch 6 taken
                     1259: branch 7 taken
     866             1700:   if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt())
     867              441:     return false;
     868             1259:   Result = Val.getInt();
     869             1259:   return true;
     870                 : }
     871                 : 
     872             5570: bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
     873                 :   // Enums are integer constant exprs.
                     1196: branch 1 taken
                     4374: branch 2 taken
     874             5570:   if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
     875             1196:     return Success(ECD->getInitVal(), E);
     876                 : 
     877                 :   // In C++, const, non-volatile integers initialized with ICEs are ICEs.
     878                 :   // In C, they can also be folded, although they are not ICEs.
                      637: branch 3 taken
                     3737: branch 4 taken
     879             4374:   if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers() 
     880                 :                                                         == Qualifiers::Const) {
     881                 : 
                       15: branch 1 taken
                      622: branch 2 taken
     882              637:     if (isa<ParmVarDecl>(D))
     883               15:       return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
     884                 : 
                      509: branch 1 taken
                      113: branch 2 taken
     885              622:     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
                      496: branch 1 taken
                       13: branch 2 taken
     886              509:       if (const Expr *Init = VD->getAnyInitializer()) {
                      290: branch 1 taken
                      206: branch 2 taken
     887              496:         if (APValue *V = VD->getEvaluatedValue()) {
                      271: branch 1 taken
                       19: branch 2 taken
     888              290:           if (V->isInt())
     889              271:             return Success(V->getInt(), E);
     890               19:           return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
     891                 :         }
     892                 : 
                        2: branch 1 taken
                      204: branch 2 taken
     893              206:         if (VD->isEvaluatingValue())
     894                2:           return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
     895                 : 
     896              204:         VD->setEvaluatingValue();
     897                 : 
                      199: branch 1 taken
                        5: branch 2 taken
     898              204:         if (Visit(const_cast<Expr*>(Init))) {
     899                 :           // Cache the evaluated value in the variable declaration.
     900              199:           VD->setEvaluatedValue(Result);
     901              199:           return true;
     902                 :         }
     903                 : 
     904                5:         VD->setEvaluatedValue(APValue());
     905                5:         return false;
     906                 :       }
     907                 :     }
     908                 :   }
     909                 : 
     910                 :   // Otherwise, random variable references are not constants.
     911             3863:   return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
     912                 : }
     913                 : 
     914                 : /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
     915                 : /// as GCC.
     916               25: static int EvaluateBuiltinClassifyType(const CallExpr *E) {
     917                 :   // The following enum mimics the values returned by GCC.
     918                 :   // FIXME: Does GCC differ between lvalue and rvalue references here?
     919                 :   enum gcc_type_class {
     920                 :     no_type_class = -1,
     921                 :     void_type_class, integer_type_class, char_type_class,
     922                 :     enumeral_type_class, boolean_type_class,
     923                 :     pointer_type_class, reference_type_class, offset_type_class,
     924                 :     real_type_class, complex_type_class,
     925                 :     function_type_class, method_type_class,
     926                 :     record_type_class, union_type_class,
     927                 :     array_type_class, string_type_class,
     928                 :     lang_type_class
     929                 :   };
     930                 : 
     931                 :   // If no argument was supplied, default to "no_type_class". This isn't
     932                 :   // ideal, however it is what gcc does.
                        0: branch 1 not taken
                       25: branch 2 taken
     933               25:   if (E->getNumArgs() == 0)
     934                0:     return no_type_class;
     935                 : 
     936               25:   QualType ArgTy = E->getArg(0)->getType();
                        0: branch 2 not taken
                       25: branch 3 taken
     937               25:   if (ArgTy->isVoidType())
     938                0:     return void_type_class;
                        0: branch 2 not taken
                       25: branch 3 taken
     939               25:   else if (ArgTy->isEnumeralType())
     940                0:     return enumeral_type_class;
                        0: branch 2 not taken
                       25: branch 3 taken
     941               25:   else if (ArgTy->isBooleanType())
     942                0:     return boolean_type_class;
                        0: branch 2 not taken
                       25: branch 3 taken
     943               25:   else if (ArgTy->isCharType())
     944                0:     return string_type_class; // gcc doesn't appear to use char_type_class
                        7: branch 2 taken
                       18: branch 3 taken
     945               25:   else if (ArgTy->isIntegerType())
     946                7:     return integer_type_class;
                        0: branch 2 not taken
                       18: branch 3 taken
     947               18:   else if (ArgTy->isPointerType())
     948                0:     return pointer_type_class;
                        0: branch 2 not taken
                       18: branch 3 taken
     949               18:   else if (ArgTy->isReferenceType())
     950                0:     return reference_type_class;
                        5: branch 2 taken
                       13: branch 3 taken
     951               18:   else if (ArgTy->isRealType())
     952                5:     return real_type_class;
                        8: branch 2 taken
                        5: branch 3 taken
     953               13:   else if (ArgTy->isComplexType())
     954                8:     return complex_type_class;
                        0: branch 2 not taken
                        5: branch 3 taken
     955                5:   else if (ArgTy->isFunctionType())
     956                0:     return function_type_class;
                        5: branch 2 taken
                        0: branch 3 not taken
     957                5:   else if (ArgTy->isStructureType())
     958                5:     return record_type_class;
                        0: branch 2 not taken
                        0: branch 3 not taken
     959                0:   else if (ArgTy->isUnionType())
     960                0:     return union_type_class;
                        0: branch 2 not taken
                        0: branch 3 not taken
     961                0:   else if (ArgTy->isArrayType())
     962                0:     return array_type_class;
                        0: branch 2 not taken
                        0: branch 3 not taken
     963                0:   else if (ArgTy->isUnionType())
     964                0:     return union_type_class;
     965                 :   else  // FIXME: offset_type_class, method_type_class, & lang_type_class?
     966                0:     assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
     967                 :   return -1;
     968                 : }
     969                 : 
     970              817: bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
                      701: branch 1 taken
                       64: branch 2 taken
                       25: branch 3 taken
                       24: branch 4 taken
                        3: branch 5 taken
     971              817:   switch (E->isBuiltinCall(Info.Ctx)) {
     972                 :   default:
     973              701:     return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
     974                 : 
     975                 :   case Builtin::BI__builtin_object_size: {
     976               64:     const Expr *Arg = E->getArg(0)->IgnoreParens();
     977               64:     Expr::EvalResult Base;
     978                 :     
     979                 :     // TODO: Perhaps we should let LLVM lower this?
                       31: branch 1 taken
                       33: branch 2 taken
                       31: branch 4 taken
                        0: branch 5 not taken
                       31: branch 6 taken
                        0: branch 7 not taken
                       31: branch 8 taken
                       33: branch 9 taken
     980               64:     if (Arg->EvaluateAsAny(Base, Info.Ctx)
     981                 :         && Base.Val.getKind() == APValue::LValue
     982                 :         && !Base.HasSideEffects)
                       31: branch 1 taken
                        0: branch 2 not taken
     983               31:       if (const Expr *LVBase = Base.Val.getLValueBase())
                       31: branch 1 taken
                        0: branch 2 not taken
     984               31:         if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LVBase)) {
                       31: branch 2 taken
                        0: branch 3 not taken
     985               31:           if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
                       31: branch 3 taken
                        0: branch 4 not taken
                       31: branch 8 taken
                        0: branch 9 not taken
                       31: branch 13 taken
                        0: branch 14 not taken
                       31: branch 18 taken
                        0: branch 19 not taken
                       31: branch 20 taken
                        0: branch 21 not taken
     986               31:             if (!VD->getType()->isIncompleteType()
     987                 :                 && VD->getType()->isObjectType()
     988                 :                 && !VD->getType()->isVariablyModifiedType()
     989                 :                 && !VD->getType()->isDependentType()) {
     990               31:               CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType());
     991               31:               CharUnits Offset = Base.Val.getLValueOffset();
                       28: branch 1 taken
                        3: branch 2 taken
                       25: branch 4 taken
                        3: branch 5 taken
                       25: branch 6 taken
                        6: branch 7 taken
     992               31:               if (!Offset.isNegative() && Offset <= Size)
     993               25:                 Size -= Offset;
     994                 :               else
     995                6:                 Size = CharUnits::Zero();
     996               31:               return Success(Size.getQuantity(), E);
     997                 :             }
     998                 :           }
     999                 :         }
    1000                 : 
    1001                 :     // If evaluating the argument has side-effects we can't determine
    1002                 :     // the size of the object and lower it to unknown now.
                       28: branch 2 taken
                        5: branch 3 taken
    1003               33:     if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
                       24: branch 4 taken
                        4: branch 5 taken
    1004               28:       if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1)
    1005               24:         return Success(-1ULL, E);
    1006                4:       return Success(0, E);
    1007                 :     }
    1008                 : 
    1009                5:     return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
    1010                 :   }
    1011                 : 
    1012                 :   case Builtin::BI__builtin_classify_type:
    1013               25:     return Success(EvaluateBuiltinClassifyType(E), E);
    1014                 : 
    1015                 :   case Builtin::BI__builtin_constant_p:
    1016                 :     // __builtin_constant_p always has one operand: it returns true if that
    1017                 :     // operand can be folded, false otherwise.
    1018               24:     return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E);
    1019                 :       
    1020                 :   case Builtin::BI__builtin_eh_return_data_regno: {
    1021                3:     int Operand = E->getArg(0)->EvaluateAsInt(Info.Ctx).getZExtValue();
    1022                3:     Operand = Info.Ctx.Target.getEHDataRegisterNumber(Operand);
    1023                3:     return Success(Operand, E);
    1024                 :   }
    1025                 :   }
    1026                 : }
    1027                 : 
    1028             3751: bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
                        6: branch 1 taken
                     3745: branch 2 taken
    1029             3751:   if (E->getOpcode() == BinaryOperator::Comma) {
                        2: branch 2 taken
                        4: branch 3 taken
    1030                6:     if (!Visit(E->getRHS()))
    1031                2:       return false;
    1032                 : 
    1033                 :     // If we can't evaluate the LHS, it might have side effects;
    1034                 :     // conservatively mark it.
                        3: branch 2 taken
                        1: branch 3 taken
    1035                4:     if (!E->getLHS()->isEvaluatable(Info.Ctx))
    1036                3:       Info.EvalResult.HasSideEffects = true;
    1037                 : 
    1038                4:     return true;
    1039                 :   }
    1040                 : 
                       81: branch 1 taken
                     3664: branch 2 taken
    1041             3745:   if (E->isLogicalOp()) {
    1042                 :     // These need to be handled specially because the operands aren't
    1043                 :     // necessarily integral
    1044                 :     bool lhsResult, rhsResult;
    1045                 : 
                       11: branch 2 taken
                       70: branch 3 taken
    1046               81:     if (HandleConversionToBool(E->getLHS(), lhsResult, Info)) {
    1047                 :       // We were able to evaluate the LHS, see if we can get away with not
    1048                 :       // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
                       10: branch 1 taken
                        1: branch 2 taken
    1049               11:       if (lhsResult == (E->getOpcode() == BinaryOperator::LOr))
    1050               10:         return Success(lhsResult, E);
    1051                 : 
                        1: branch 2 taken
                        0: branch 3 not taken
    1052                1:       if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
                        0: branch 1 not taken
                        1: branch 2 taken
    1053                1:         if (E->getOpcode() == BinaryOperator::LOr)
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
    1054                0:           return Success(lhsResult || rhsResult, E);
    1055                 :         else
                        1: branch 0 taken
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 3 not taken
    1056                1:           return Success(lhsResult && rhsResult, E);
    1057                 :       }
    1058                 :     } else {
                       11: branch 2 taken
                       59: branch 3 taken
    1059               70:       if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
    1060                 :         // We can't evaluate the LHS; however, sometimes the result
    1061                 :         // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
                        2: branch 1 taken
                        9: branch 2 taken
                        0: branch 4 not taken
                        2: branch 5 taken
                        9: branch 6 taken
                        2: branch 7 taken
    1062               11:         if (rhsResult == (E->getOpcode() == BinaryOperator::LOr) ||
    1063                 :             !rhsResult == (E->getOpcode() == BinaryOperator::LAnd)) {
    1064                 :           // Since we weren't able to evaluate the left hand side, it
    1065                 :           // must have had side effects.
    1066                9:           Info.EvalResult.HasSideEffects = true;
    1067                 : 
    1068                9:           return Success(rhsResult, E);
    1069                 :         }
    1070                 :       }
    1071                 :     }
    1072                 : 
    1073               61:     return false;
    1074                 :   }
    1075                 : 
    1076             3664:   QualType LHSTy = E->getLHS()->getType();
    1077             3664:   QualType RHSTy = E->getRHS()->getType();
    1078                 : 
                       10: branch 2 taken
                     3654: branch 3 taken
    1079             3664:   if (LHSTy->isAnyComplexType()) {
                       10: branch 2 taken
                        0: branch 3 not taken
    1080               10:     assert(RHSTy->isAnyComplexType() && "Invalid comparison");
    1081               10:     APValue LHS, RHS;
    1082                 : 
                        0: branch 2 not taken
                       10: branch 3 taken
    1083               10:     if (!EvaluateComplex(E->getLHS(), LHS, Info))
    1084                0:       return false;
    1085                 : 
                        0: branch 2 not taken
                       10: branch 3 taken
    1086               10:     if (!EvaluateComplex(E->getRHS(), RHS, Info))
    1087                0:       return false;
    1088                 : 
                        4: branch 1 taken
                        6: branch 2 taken
    1089               10:     if (LHS.isComplexFloat()) {
    1090                 :       APFloat::cmpResult CR_r =
    1091                4:         LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
    1092                 :       APFloat::cmpResult CR_i =
    1093                4:         LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
    1094                 : 
                        2: branch 1 taken
                        2: branch 2 taken
    1095                4:       if (E->getOpcode() == BinaryOperator::EQ)
    1096                 :         return Success((CR_r == APFloat::cmpEqual &&
                        2: branch 0 taken
                        0: branch 1 not taken
                        2: branch 2 taken
                        0: branch 3 not taken
    1097                2:                         CR_i == APFloat::cmpEqual), E);
    1098                 :       else {
    1099                 :         assert(E->getOpcode() == BinaryOperator::NE &&
                        2: branch 1 taken
                        0: branch 2 not taken
    1100                2:                "Invalid complex comparison.");
    1101                 :         return Success(((CR_r == APFloat::cmpGreaterThan ||
    1102                 :                          CR_r == APFloat::cmpLessThan) &&
    1103                 :                         (CR_i == APFloat::cmpGreaterThan ||
                        2: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        2: branch 3 taken
                        2: branch 4 taken
                        2: branch 5 taken
                        2: branch 6 taken
                        2: branch 7 taken
    1104                4:                          CR_i == APFloat::cmpLessThan)), E);
    1105                 :       }
    1106                 :     } else {
                        4: branch 1 taken
                        2: branch 2 taken
    1107                6:       if (E->getOpcode() == BinaryOperator::EQ)
    1108                 :         return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
                        2: branch 3 taken
                        2: branch 4 taken
                        2: branch 8 taken
                        0: branch 9 not taken
    1109                4:                         LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
    1110                 :       else {
    1111                 :         assert(E->getOpcode() == BinaryOperator::NE &&
                        2: branch 1 taken
                        0: branch 2 not taken
    1112                2:                "Invalid compex comparison.");
    1113                 :         return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
                        2: branch 3 taken
                        0: branch 4 not taken
                        0: branch 8 not taken
                        2: branch 9 taken
    1114                4:                         LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
    1115                 :       }
    1116               10:     }
    1117                 :   }
    1118                 : 
                        6: branch 2 taken
                     3648: branch 3 taken
                        6: branch 6 taken
                        0: branch 7 not taken
                        6: branch 8 taken
                     3648: branch 9 taken
    1119             3654:   if (LHSTy->isRealFloatingType() &&
    1120                 :       RHSTy->isRealFloatingType()) {
    1121                6:     APFloat RHS(0.0), LHS(0.0);
    1122                 : 
                        0: branch 2 not taken
                        6: branch 3 taken
    1123                6:     if (!EvaluateFloat(E->getRHS(), RHS, Info))
    1124                0:       return false;
    1125                 : 
                        0: branch 2 not taken
                        6: branch 3 taken
    1126                6:     if (!EvaluateFloat(E->getLHS(), LHS, Info))
    1127                0:       return false;
    1128                 : 
    1129                6:     APFloat::cmpResult CR = LHS.compare(RHS);
    1130                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
                        0: branch 3 not taken
                        4: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
    1131                6:     switch (E->getOpcode()) {
    1132                 :     default:
    1133                0:       assert(0 && "Invalid binary operator!");
    1134                 :     case BinaryOperator::LT:
    1135                1:       return Success(CR == APFloat::cmpLessThan, E);
    1136                 :     case BinaryOperator::GT:
    1137                0:       return Success(CR == APFloat::cmpGreaterThan, E);
    1138                 :     case BinaryOperator::LE:
                        0: branch 0 not taken
                        4: branch 1 taken
                        4: branch 2 taken
                        4: branch 3 taken
    1139                4:       return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
    1140                 :     case BinaryOperator::GE:
    1141                 :       return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
    1142                0:                      E);
    1143                 :     case BinaryOperator::EQ:
    1144                1:       return Success(CR == APFloat::cmpEqual, E);
    1145                 :     case BinaryOperator::NE:
    1146                 :       return Success(CR == APFloat::cmpGreaterThan
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
    1147                0:                      || CR == APFloat::cmpLessThan, E);
    1148                6:     }
    1149                 :   }
    1150                 : 
                      284: branch 2 taken
                     3364: branch 3 taken
                      284: branch 6 taken
                        0: branch 7 not taken
                      284: branch 8 taken
                     3364: branch 9 taken
    1151             3648:   if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
                      260: branch 1 taken
                       24: branch 2 taken
                      251: branch 4 taken
                        9: branch 5 taken
                      275: branch 6 taken
                        9: branch 7 taken
    1152              284:     if (E->getOpcode() == BinaryOperator::Sub || E->isEqualityOp()) {
    1153              275:       APValue LHSValue;
                      171: branch 2 taken
                      104: branch 3 taken
    1154              275:       if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
    1155              171:         return false;
    1156                 : 
    1157              104:       APValue RHSValue;
                       96: branch 2 taken
                        8: branch 3 taken
    1158              104:       if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
    1159               96:         return false;
    1160                 : 
    1161                 :       // Reject any bases from the normal codepath; we special-case comparisons
    1162                 :       // to null.
                        3: branch 1 taken
                        5: branch 2 taken
    1163                8:       if (LHSValue.getLValueBase()) {
                        2: branch 1 taken
                        1: branch 2 taken
    1164                3:         if (!E->isEqualityOp())
    1165                2:           return false;
                        1: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
    1166                1:         if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero())
    1167                0:           return false;
    1168                 :         bool bres;
                        0: branch 1 not taken
                        1: branch 2 taken
    1169                1:         if (!EvalPointerValueAsBool(LHSValue, bres))
    1170                0:           return false;
    1171                1:         return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
                        0: branch 1 not taken
                        5: branch 2 taken
    1172                5:       } else if (RHSValue.getLValueBase()) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1173                0:         if (!E->isEqualityOp())
    1174                0:           return false;
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
    1175                0:         if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero())
    1176                0:           return false;
    1177                 :         bool bres;
                        0: branch 1 not taken
                        0: branch 2 not taken
    1178                0:         if (!EvalPointerValueAsBool(RHSValue, bres))
    1179                0:           return false;
    1180                0:         return Success(bres ^ (E->getOpcode() == BinaryOperator::EQ), E);
    1181                 :       }
    1182                 : 
                        3: branch 1 taken
                        2: branch 2 taken
    1183                5:       if (E->getOpcode() == BinaryOperator::Sub) {
    1184                3:         const QualType Type = E->getLHS()->getType();
    1185                3:         const QualType ElementType = Type->getAs<PointerType>()->getPointeeType();
    1186                 : 
    1187                3:         CharUnits ElementSize = CharUnits::One();
                        2: branch 2 taken
                        1: branch 3 taken
                        2: branch 6 taken
                        0: branch 7 not taken
                        2: branch 8 taken
                        1: branch 9 taken
    1188                3:         if (!ElementType->isVoidType() && !ElementType->isFunctionType())
    1189                2:           ElementSize = Info.Ctx.getTypeSizeInChars(ElementType);
    1190                 : 
    1191                 :         CharUnits Diff = LHSValue.getLValueOffset() - 
    1192                3:                              RHSValue.getLValueOffset();
    1193                3:         return Success(Diff / ElementSize, E);
    1194                 :       }
    1195                 :       bool Result;
                        1: branch 1 taken
                        1: branch 2 taken
    1196                2:       if (E->getOpcode() == BinaryOperator::EQ) {
    1197                1:         Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset();
    1198                 :       } else {
    1199                1:         Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset();
    1200                 :       }
    1201                2:       return Success(Result, E);
    1202                 :     }
    1203                 :   }
                     3257: branch 2 taken
                      116: branch 3 taken
                        0: branch 6 not taken
                     3257: branch 7 taken
                      116: branch 8 taken
                     3257: branch 9 taken
    1204             3373:   if (!LHSTy->isIntegralType() ||
    1205                 :       !RHSTy->isIntegralType()) {
    1206                 :     // We can't continue from here for non-integral types, and they
    1207                 :     // could potentially confuse the following operations.
    1208              116:     return false;
    1209                 :   }
    1210                 : 
    1211                 :   // The LHS of a constant expr is always evaluated and needed.
                     1017: branch 2 taken
                     2240: branch 3 taken
    1212             3257:   if (!Visit(E->getLHS()))
    1213             1017:     return false; // error in subexpression.
    1214                 : 
    1215             2240:   APValue RHSVal;
                      104: branch 2 taken
                     2136: branch 3 taken
    1216             2240:   if (!EvaluateIntegerOrLValue(E->getRHS(), RHSVal, Info))
    1217              104:     return false;
    1218                 : 
    1219                 :   // Handle cases like (unsigned long)&a + 4.
                      936: branch 1 taken
                     1200: branch 2 taken
                        2: branch 4 taken
                      934: branch 5 taken
                        2: branch 7 taken
                        0: branch 8 not taken
                        2: branch 9 taken
                     2134: branch 10 taken
    1220             2136:   if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) {
    1221                2:     CharUnits Offset = Result.getLValueOffset();
    1222                 :     CharUnits AdditionalOffset = CharUnits::fromQuantity(
    1223                2:                                      RHSVal.getInt().getZExtValue());
                        1: branch 1 taken
                        1: branch 2 taken
    1224                2:     if (E->getOpcode() == BinaryOperator::Add)
    1225                1:       Offset += AdditionalOffset;
    1226                 :     else
    1227                1:       Offset -= AdditionalOffset;
    1228                2:     Result = APValue(Result.getLValueBase(), Offset);
    1229                2:     return true;
    1230                 :   }
    1231                 : 
    1232                 :   // Handle cases like 4 + (unsigned long)&a
                      435: branch 1 taken
                     1699: branch 2 taken
                        1: branch 4 taken
                      434: branch 5 taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
                     2133: branch 10 taken
    1233             2134:   if (E->getOpcode() == BinaryOperator::Add &&
    1234                 :         RHSVal.isLValue() && Result.isInt()) {
    1235                1:     CharUnits Offset = RHSVal.getLValueOffset();
    1236                1:     Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue());
    1237                1:     Result = APValue(RHSVal.getLValueBase(), Offset);
    1238                1:     return true;
    1239                 :   }
    1240                 : 
    1241                 :   // All the following cases expect both operands to be an integer
                     2133: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                     2133: branch 5 taken
                        0: branch 6 not taken
                     2133: branch 7 taken
    1242             2133:   if (!Result.isInt() || !RHSVal.isInt())
    1243                0:     return false;
    1244                 : 
    1245             2133:   APSInt& RHS = RHSVal.getInt();
    1246                 : 
                        0: branch 1 not taken
                      104: branch 2 taken
                      434: branch 3 taken
                      499: branch 4 taken
                      147: branch 5 taken
                        7: branch 6 taken
                      170: branch 7 taken
                       59: branch 8 taken
                        4: branch 9 taken
                      245: branch 10 taken
                        8: branch 11 taken
                       18: branch 12 taken
                       13: branch 13 taken
                       11: branch 14 taken
                        7: branch 15 taken
                      382: branch 16 taken
                       25: branch 17 taken
    1247             2133:   switch (E->getOpcode()) {
    1248                 :   default:
    1249                0:     return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
    1250              104:   case BinaryOperator::Mul: return Success(Result.getInt() * RHS, E);
    1251              434:   case BinaryOperator::Add: return Success(Result.getInt() + RHS, E);
    1252              499:   case BinaryOperator::Sub: return Success(Result.getInt() - RHS, E);
    1253              147:   case BinaryOperator::And: return Success(Result.getInt() & RHS, E);
    1254                7:   case BinaryOperator::Xor: return Success(Result.getInt() ^ RHS, E);
    1255              170:   case BinaryOperator::Or:  return Success(Result.getInt() | RHS, E);
    1256                 :   case BinaryOperator::Div:
                        2: branch 1 taken
                       57: branch 2 taken
    1257               59:     if (RHS == 0)
    1258                2:       return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
    1259               57:     return Success(Result.getInt() / RHS, E);
    1260                 :   case BinaryOperator::Rem:
                        0: branch 1 not taken
                        4: branch 2 taken
    1261                4:     if (RHS == 0)
    1262                0:       return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
    1263                4:     return Success(Result.getInt() % RHS, E);
    1264                 :   case BinaryOperator::Shl: {
    1265                 :     // FIXME: Warn about out of range shift amounts!
    1266                 :     unsigned SA =
    1267              245:       (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
    1268              245:     return Success(Result.getInt() << SA, E);
    1269                 :   }
    1270                 :   case BinaryOperator::Shr: {
    1271                 :     unsigned SA =
    1272                8:       (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
    1273                8:     return Success(Result.getInt() >> SA, E);
    1274                 :   }
    1275                 : 
    1276               18:   case BinaryOperator::LT: return Success(Result.getInt() < RHS, E);
    1277               13:   case BinaryOperator::GT: return Success(Result.getInt() > RHS, E);
    1278               11:   case BinaryOperator::LE: return Success(Result.getInt() <= RHS, E);
    1279                7:   case BinaryOperator::GE: return Success(Result.getInt() >= RHS, E);
    1280              382:   case BinaryOperator::EQ: return Success(Result.getInt() == RHS, E);
    1281               25:   case BinaryOperator::NE: return Success(Result.getInt() != RHS, E);
    1282             2240:   }
    1283                 : }
    1284                 : 
    1285              861: bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
    1286                 :   bool Cond;
                       11: branch 2 taken
                      850: branch 3 taken
    1287              861:   if (!HandleConversionToBool(E->getCond(), Cond, Info))
    1288               11:     return false;
    1289                 : 
                      638: branch 0 taken
                      212: branch 1 taken
    1290              850:   return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
    1291                 : }
    1292                 : 
    1293               63: CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
    1294                 :   // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
    1295                 :   //   the result is the size of the referenced type."
    1296                 :   // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
    1297                 :   //   result shall be the alignment of the referenced type."
                        0: branch 2 not taken
                       63: branch 3 taken
    1298               63:   if (const ReferenceType *Ref = T->getAs<ReferenceType>())
    1299                0:     T = Ref->getPointeeType();
    1300                 : 
    1301                 :   // Get information about the alignment.
    1302               63:   unsigned CharSize = Info.Ctx.Target.getCharWidth();
    1303                 : 
    1304                 :   // __alignof is defined to return the preferred alignment.
    1305                 :   return CharUnits::fromQuantity(
    1306               63:       Info.Ctx.getPreferredTypeAlign(T.getTypePtr()) / CharSize);
    1307                 : }
    1308                 : 
    1309               31: CharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
    1310               31:   E = E->IgnoreParens();
    1311                 : 
    1312                 :   // alignof decl is always accepted, even if it doesn't make sense: we default
    1313                 :   // to 1 in those cases.
                       28: branch 1 taken
                        3: branch 2 taken
    1314               31:   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
    1315                 :     return Info.Ctx.getDeclAlign(DRE->getDecl(), 
    1316               28:                                  /*RefAsPointee*/true);
    1317                 : 
                        1: branch 1 taken
                        2: branch 2 taken
    1318                3:   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
    1319                 :     return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
    1320                1:                                  /*RefAsPointee*/true);
    1321                 : 
    1322                2:   return GetAlignOfType(E->getType());
    1323                 : }
    1324                 : 
    1325                 : 
    1326                 : /// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
    1327                 : /// expression's type.
    1328              881: bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
    1329                 :   // Handle alignof separately.
                       92: branch 1 taken
                      789: branch 2 taken
    1330              881:   if (!E->isSizeOf()) {
                       61: branch 1 taken
                       31: branch 2 taken
    1331               92:     if (E->isArgumentType())
    1332               61:       return Success(GetAlignOfType(E->getArgumentType()).getQuantity(), E);
    1333                 :     else
    1334               31:       return Success(GetAlignOfExpr(E->getArgumentExpr()).getQuantity(), E);
    1335                 :   }
    1336                 : 
    1337              789:   QualType SrcTy = E->getTypeOfArgument();
    1338                 :   // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
    1339                 :   //   the result is the size of the referenced type."
    1340                 :   // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
    1341                 :   //   result shall be the alignment of the referenced type."
                        0: branch 2 not taken
                      789: branch 3 taken
    1342              789:   if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
    1343                0:     SrcTy = Ref->getPointeeType();
    1344                 : 
    1345                 :   // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
    1346                 :   // extension.
                      750: branch 2 taken
                       39: branch 3 taken
                       12: branch 6 taken
                      738: branch 7 taken
                       51: branch 8 taken
                      738: branch 9 taken
    1347              789:   if (SrcTy->isVoidType() || SrcTy->isFunctionType())
    1348               51:     return Success(1, E);
    1349                 : 
    1350                 :   // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
                       30: branch 2 taken
                      708: branch 3 taken
    1351              738:   if (!SrcTy->isConstantSizeType())
    1352               30:     return false;
    1353                 : 
    1354                 :   // Get information about the size.
    1355              708:   return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E);
    1356                 : }
    1357                 : 
    1358             1055: bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
    1359                 :   // Special case unary operators that do not need their subexpression
    1360                 :   // evaluated.  offsetof/sizeof/alignof are all special.
                      250: branch 1 taken
                      805: branch 2 taken
    1361             1055:   if (E->isOffsetOfOp()) {
    1362                 :     // The AST for offsetof is defined in such a way that we can just
    1363                 :     // directly Evaluate it as an l-value.
    1364              250:     APValue LV;
                        3: branch 2 taken
                      247: branch 3 taken
    1365              250:     if (!EvaluateLValue(E->getSubExpr(), LV, Info))
    1366                3:       return false;
                        0: branch 1 not taken
                      247: branch 2 taken
    1367              247:     if (LV.getLValueBase())
    1368                0:       return false;
    1369              247:     return Success(LV.getLValueOffset().getQuantity(), E);
    1370                 :   }
    1371                 : 
                      455: branch 1 taken
                      350: branch 2 taken
    1372              805:   if (E->getOpcode() == UnaryOperator::LNot) {
    1373                 :     // LNot's operand isn't necessarily an integer, so we handle it specially.
    1374                 :     bool bres;
                      430: branch 2 taken
                       25: branch 3 taken
    1375              455:     if (!HandleConversionToBool(E->getSubExpr(), bres, Info))
    1376              430:       return false;
    1377               25:     return Success(!bres, E);
    1378                 :   }
    1379                 : 
    1380                 :   // Only handle integral operations...
                      123: branch 4 taken
                      227: branch 5 taken
    1381              350:   if (!E->getSubExpr()->getType()->isIntegralType())
    1382              123:     return false;
    1383                 : 
    1384                 :   // Get the operand value into 'Result'.
                       17: branch 2 taken
                      210: branch 3 taken
    1385              227:   if (!Visit(E->getSubExpr()))
    1386               17:     return false;
    1387                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
                        4: branch 3 taken
                      190: branch 4 taken
                       16: branch 5 taken
    1388              210:   switch (E->getOpcode()) {
    1389                 :   default:
    1390                 :     // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
    1391                 :     // See C99 6.6p3.
    1392                0:     return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
    1393                 :   case UnaryOperator::Extension:
    1394                 :     // FIXME: Should extension allow i-c-e extension expressions in its scope?
    1395                 :     // If so, we could clear the diagnostic ID.
    1396                0:     return true;
    1397                 :   case UnaryOperator::Plus:
    1398                 :     // The result is always just the subexpr.
    1399                4:     return true;
    1400                 :   case UnaryOperator::Minus:
                        0: branch 1 not taken
                      190: branch 2 taken
    1401              190:     if (!Result.isInt()) return false;
    1402              190:     return Success(-Result.getInt(), E);
    1403                 :   case UnaryOperator::Not:
                        0: branch 1 not taken
                       16: branch 2 taken
    1404               16:     if (!Result.isInt()) return false;
    1405               16:     return Success(~Result.getInt(), E);
    1406                 :   }
    1407                 : }
    1408                 : 
    1409                 : /// HandleCast - This is used to evaluate implicit or explicit casts where the
    1410                 : /// result type is integer.
    1411             4035: bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
    1412             4035:   Expr *SubExpr = E->getSubExpr();
    1413             4035:   QualType DestType = E->getType();
    1414             4035:   QualType SrcType = SubExpr->getType();
    1415                 : 
                      196: branch 2 taken
                     3839: branch 3 taken
    1416             4035:   if (DestType->isBooleanType()) {
    1417                 :     bool BoolResult;
                       59: branch 1 taken
                      137: branch 2 taken
    1418              196:     if (!HandleConversionToBool(SubExpr, BoolResult, Info))
    1419               59:       return false;
    1420              137:     return Success(BoolResult, E);
    1421                 :   }
    1422                 : 
    1423                 :   // Handle simple integer->integer casts.
                     3681: branch 2 taken
                      158: branch 3 taken
    1424             3839:   if (SrcType->isIntegralType()) {
                     1230: branch 1 taken
                     2451: branch 2 taken
    1425             3681:     if (!Visit(SubExpr))
    1426             1230:       return false;
    1427                 : 
                        1: branch 1 taken
                     2450: branch 2 taken
    1428             2451:     if (!Result.isInt()) {
    1429                 :       // Only allow casts of lvalues if they are lossless.
    1430                1:       return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
    1431                 :     }
    1432                 : 
    1433                 :     return Success(HandleIntToIntCast(DestType, SrcType,
    1434             2450:                                       Result.getInt(), Info.Ctx), E);
    1435                 :   }
    1436                 : 
    1437                 :   // FIXME: Clean this up!
                       90: branch 2 taken
                       68: branch 3 taken
    1438              158:   if (SrcType->isPointerType()) {
    1439               90:     APValue LV;
                       18: branch 1 taken
                       72: branch 2 taken
    1440               90:     if (!EvaluatePointer(SubExpr, LV, Info))
    1441               18:       return false;
    1442                 : 
                       41: branch 1 taken
                       31: branch 2 taken
    1443               72:     if (LV.getLValueBase()) {
    1444                 :       // Only allow based lvalue casts if they are lossless.
                        4: branch 2 taken
                       37: branch 3 taken
    1445               41:       if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
    1446                4:         return false;
    1447                 : 
    1448               37:       Result = LV;
    1449               37:       return true;
    1450                 :     }
    1451                 : 
    1452                 :     APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), 
    1453               31:                                          SrcType);
    1454               31:     return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E);
    1455                 :   }
    1456                 : 
                       68: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                       68: branch 7 taken
                        0: branch 8 not taken
                       68: branch 9 taken
    1457               68:   if (SrcType->isArrayType() || SrcType->isFunctionType()) {
    1458                 :     // This handles double-conversion cases, where there's both
    1459                 :     // an l-value promotion and an implicit conversion to int.
    1460                0:     APValue LV;
                        0: branch 1 not taken
                        0: branch 2 not taken
    1461                0:     if (!EvaluateLValue(SubExpr, LV, Info))
    1462                0:       return false;
    1463                 : 
                        0: branch 3 not taken
                        0: branch 4 not taken
    1464                0:     if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy))
    1465                0:       return false;
    1466                 : 
    1467                0:     Result = LV;
    1468                0:     return true;
    1469                 :   }
    1470                 : 
                        1: branch 2 taken
                       67: branch 3 taken
    1471               68:   if (SrcType->isAnyComplexType()) {
    1472                1:     APValue C;
                        0: branch 1 not taken
                        1: branch 2 taken
    1473                1:     if (!EvaluateComplex(SubExpr, C, Info))
    1474                0:       return false;
                        1: branch 1 taken
                        0: branch 2 not taken
    1475                1:     if (C.isComplexFloat())
    1476                 :       return Success(HandleFloatToIntCast(DestType, SrcType,
    1477                 :                                           C.getComplexFloatReal(), Info.Ctx),
    1478                1:                      E);
    1479                 :     else
    1480                 :       return Success(HandleIntToIntCast(DestType, SrcType,
    1481                0:                                         C.getComplexIntReal(), Info.Ctx), E);
    1482                 :   }
    1483                 :   // FIXME: Handle vectors
    1484                 : 
                        9: branch 2 taken
                       58: branch 3 taken
    1485               67:   if (!SrcType->isRealFloatingType())
    1486                9:     return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
    1487                 : 
    1488               58:   APFloat F(0.0);
                        3: branch 1 taken
                       55: branch 2 taken
    1489               58:   if (!EvaluateFloat(SubExpr, F, Info))
    1490                3:     return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
    1491                 : 
    1492               55:   return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E);
    1493                 : }
    1494                 : 
    1495                6: bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
                        1: branch 4 taken
                        5: branch 5 taken
    1496                6:   if (E->getSubExpr()->getType()->isAnyComplexType()) {
    1497                1:     APValue LV;
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
    1498                1:     if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
    1499                0:       return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
    1500                1:     return Success(LV.getComplexIntReal(), E);
    1501                 :   }
    1502                 : 
    1503                5:   return Visit(E->getSubExpr());
    1504                 : }
    1505                 : 
    1506                6: bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
                        1: branch 4 taken
                        5: branch 5 taken
    1507                6:   if (E->getSubExpr()->getType()->isComplexIntegerType()) {
    1508                1:     APValue LV;
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
    1509                1:     if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
    1510                0:       return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
    1511                1:     return Success(LV.getComplexIntImag(), E);
    1512                 :   }
    1513                 : 
                        4: branch 2 taken
                        1: branch 3 taken
    1514                5:   if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
    1515                4:     Info.EvalResult.HasSideEffects = true;
    1516                5:   return Success(0, E);
    1517                 : }
    1518                 : 
    1519                 : //===----------------------------------------------------------------------===//
    1520                 : // Float Evaluation
    1521                 : //===----------------------------------------------------------------------===//
    1522                 : 
    1523                 : namespace {
    1524                 : class FloatExprEvaluator
    1525                 :   : public StmtVisitor<FloatExprEvaluator, bool> {
    1526                 :   EvalInfo &Info;
    1527                 :   APFloat &Result;
    1528                 : public:
    1529              872:   FloatExprEvaluator(EvalInfo &info, APFloat &result)
    1530              872:     : Info(info), Result(result) {}
    1531                 : 
    1532              207:   bool VisitStmt(Stmt *S) {
    1533              207:     return false;
    1534                 :   }
    1535                 : 
    1536               28:   bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
    1537                 :   bool VisitCallExpr(const CallExpr *E);
    1538                 : 
    1539                 :   bool VisitUnaryOperator(const UnaryOperator *E);
    1540                 :   bool VisitBinaryOperator(const BinaryOperator *E);
    1541                 :   bool VisitFloatingLiteral(const FloatingLiteral *E);
    1542                 :   bool VisitCastExpr(CastExpr *E);
    1543                 :   bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
    1544                 :   bool VisitConditionalOperator(ConditionalOperator *E);
    1545                 : 
    1546                0:   bool VisitChooseExpr(const ChooseExpr *E)
    1547                0:     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
    1548                0:   bool VisitUnaryExtension(const UnaryOperator *E)
    1549                0:     { return Visit(E->getSubExpr()); }
    1550                 : 
    1551                 :   // FIXME: Missing: __real__/__imag__, array subscript of vector,
    1552                 :   //                 member of vector, ImplicitValueInitExpr
    1553                 : };
    1554                 : } // end anonymous namespace
    1555                 : 
    1556              872: static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
    1557              872:   return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
    1558                 : }
    1559                 : 
    1560               84: bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
                       19: branch 1 taken
                       26: branch 2 taken
                       31: branch 3 taken
                        4: branch 4 taken
                        4: branch 5 taken
    1561               84:   switch (E->isBuiltinCall(Info.Ctx)) {
    1562               19:   default: return false;
    1563                 :   case Builtin::BI__builtin_huge_val:
    1564                 :   case Builtin::BI__builtin_huge_valf:
    1565                 :   case Builtin::BI__builtin_huge_vall:
    1566                 :   case Builtin::BI__builtin_inf:
    1567                 :   case Builtin::BI__builtin_inff:
    1568                 :   case Builtin::BI__builtin_infl: {
    1569                 :     const llvm::fltSemantics &Sem =
    1570               26:       Info.Ctx.getFloatTypeSemantics(E->getType());
    1571               26:     Result = llvm::APFloat::getInf(Sem);
    1572               26:     return true;
    1573                 :   }
    1574                 : 
    1575                 :   case Builtin::BI__builtin_nan:
    1576                 :   case Builtin::BI__builtin_nanf:
    1577                 :   case Builtin::BI__builtin_nanl:
    1578                 :     // If this is __builtin_nan() turn this into a nan, otherwise we
    1579                 :     // can't constant fold it.
                       31: branch 0 taken
                        0: branch 1 not taken
    1580               31:     if (const StringLiteral *S =
    1581               31:         dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
                       31: branch 1 taken
                        0: branch 2 not taken
    1582               31:       if (!S->isWide()) {
    1583                 :         const llvm::fltSemantics &Sem =
    1584               31:           Info.Ctx.getFloatTypeSemantics(E->getType());
    1585               31:         unsigned Type = 0;
                       22: branch 2 taken
                        9: branch 3 taken
                        0: branch 6 not taken
                       22: branch 7 taken
                        0: branch 8 not taken
                       31: branch 9 taken
    1586               31:         if (!S->getString().empty() && S->getString().getAsInteger(0, Type))
    1587                0:           return false;
    1588               31:         Result = llvm::APFloat::getNaN(Sem, false, Type);
    1589               31:         return true;
    1590                 :       }
    1591                 :     }
    1592                0:     return false;
    1593                 : 
    1594                 :   case Builtin::BI__builtin_fabs:
    1595                 :   case Builtin::BI__builtin_fabsf:
    1596                 :   case Builtin::BI__builtin_fabsl:
                        0: branch 2 not taken
                        4: branch 3 taken
    1597                4:     if (!EvaluateFloat(E->getArg(0), Result, Info))
    1598                0:       return false;
    1599                 : 
                        4: branch 1 taken
                        0: branch 2 not taken
    1600                4:     if (Result.isNegative())
    1601                4:       Result.changeSign();
    1602                4:     return true;
    1603                 : 
    1604                 :   case Builtin::BI__builtin_copysign:
    1605                 :   case Builtin::BI__builtin_copysignf:
    1606                 :   case Builtin::BI__builtin_copysignl: {
    1607                4:     APFloat RHS(0.);
                        4: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        4: branch 7 taken
                        0: branch 8 not taken
                        4: branch 9 taken
    1608                4:     if (!EvaluateFloat(E->getArg(0), Result, Info) ||
    1609                 :         !EvaluateFloat(E->getArg(1), RHS, Info))
    1610                0:       return false;
    1611                4:     Result.copySign(RHS);
    1612                4:     return true;
    1613                 :   }
    1614                 :   }
    1615                 : }
    1616                 : 
    1617               23: bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
                        1: branch 1 taken
                       22: branch 2 taken
    1618               23:   if (E->getOpcode() == UnaryOperator::Deref)
    1619                1:     return false;
    1620                 : 
                        0: branch 2 not taken
                       22: branch 3 taken
    1621               22:   if (!EvaluateFloat(E->getSubExpr(), Result, Info))
    1622                0:     return false;
    1623                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
                       22: branch 3 taken
    1624               22:   switch (E->getOpcode()) {
    1625                0:   default: return false;
    1626                 :   case UnaryOperator::Plus:
    1627                0:     return true;
    1628                 :   case UnaryOperator::Minus:
    1629               22:     Result.changeSign();
    1630               22:     return true;
    1631                 :   }
    1632                 : }
    1633                 : 
    1634               34: bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
                        1: branch 1 taken
                       33: branch 2 taken
    1635               34:   if (E->getOpcode() == BinaryOperator::Comma) {
                        0: branch 2 not taken
                        1: branch 3 taken
    1636                1:     if (!EvaluateFloat(E->getRHS(), Result, Info))
    1637                0:       return false;
    1638                 : 
    1639                 :     // If we can't evaluate the LHS, it might have side effects;
    1640                 :     // conservatively mark it.
                        0: branch 2 not taken
                        1: branch 3 taken
    1641                1:     if (!E->getLHS()->isEvaluatable(Info.Ctx))
    1642                0:       Info.EvalResult.HasSideEffects = true;
    1643                 : 
    1644                1:     return true;
    1645                 :   }
    1646                 : 
    1647                 :   // FIXME: Diagnostics?  I really don't understand how the warnings
    1648                 :   // and errors are supposed to work.
    1649               33:   APFloat RHS(0.0);
                        8: branch 2 taken
                       25: branch 3 taken
    1650               33:   if (!EvaluateFloat(E->getLHS(), Result, Info))
    1651                8:     return false;
                        3: branch 2 taken
                       22: branch 3 taken
    1652               25:   if (!EvaluateFloat(E->getRHS(), RHS, Info))
    1653                3:     return false;
    1654                 : 
                        0: branch 1 not taken
                        3: branch 2 taken
                       15: branch 3 taken
                        1: branch 4 taken
                        3: branch 5 taken
    1655               22:   switch (E->getOpcode()) {
    1656                0:   default: return false;
    1657                 :   case BinaryOperator::Mul:
    1658                3:     Result.multiply(RHS, APFloat::rmNearestTiesToEven);
    1659                3:     return true;
    1660                 :   case BinaryOperator::Add:
    1661               15:     Result.add(RHS, APFloat::rmNearestTiesToEven);
    1662               15:     return true;
    1663                 :   case BinaryOperator::Sub:
    1664                1:     Result.subtract(RHS, APFloat::rmNearestTiesToEven);
    1665                1:     return true;
    1666                 :   case BinaryOperator::Div:
    1667                3:     Result.divide(RHS, APFloat::rmNearestTiesToEven);
    1668                3:     return true;
    1669               33:   }
    1670                 : }
    1671                 : 
    1672              447: bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
    1673              447:   Result = E->getValue();
    1674              447:   return true;
    1675                 : }
    1676                 : 
    1677              197: bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
    1678              197:   Expr* SubExpr = E->getSubExpr();
    1679                 : 
                       76: branch 3 taken
                      121: branch 4 taken
    1680              197:   if (SubExpr->getType()->isIntegralType()) {
    1681               76:     APSInt IntResult;
                        3: branch 1 taken
                       73: branch 2 taken
    1682               76:     if (!EvaluateInteger(SubExpr, IntResult, Info))
    1683                3:       return false;
    1684                 :     Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(),
    1685               73:                                   IntResult, Info.Ctx);
    1686               73:     return true;
    1687                 :   }
                      121: branch 3 taken
                        0: branch 4 not taken
    1688              121:   if (SubExpr->getType()->isRealFloatingType()) {
                        9: branch 1 taken
                      112: branch 2 taken
    1689              121:     if (!Visit(SubExpr))
    1690                9:       return false;
    1691                 :     Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(),
    1692              112:                                     Result, Info.Ctx);
    1693              112:     return true;
    1694                 :   }
    1695                 :   // FIXME: Handle complex types
    1696                 : 
    1697                0:   return false;
    1698                 : }
    1699                 : 
    1700                1: bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
    1701                1:   Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
    1702                1:   return true;
    1703                 : }
    1704                 : 
    1705                1: bool FloatExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
    1706                 :   bool Cond;
                        0: branch 2 not taken
                        1: branch 3 taken
    1707                1:   if (!HandleConversionToBool(E->getCond(), Cond, Info))
    1708                0:     return false;
    1709                 : 
                        0: branch 0 not taken
                        1: branch 1 taken
    1710                1:   return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
    1711                 : }
    1712                 : 
    1713                 : //===----------------------------------------------------------------------===//
    1714                 : // Complex Evaluation (for float and integer)
    1715                 : //===----------------------------------------------------------------------===//
    1716                 : 
    1717                 : namespace {
    1718                 : class ComplexExprEvaluator
    1719                 :   : public StmtVisitor<ComplexExprEvaluator, APValue> {
    1720                 :   EvalInfo &Info;
    1721                 : 
    1722                 : public:
    1723              255:   ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
    1724                 : 
    1725                 :   //===--------------------------------------------------------------------===//
    1726                 :   //                            Visitor Methods
    1727                 :   //===--------------------------------------------------------------------===//
    1728                 : 
    1729               52:   APValue VisitStmt(Stmt *S) {
    1730               52:     return APValue();
    1731                 :   }
    1732                 : 
    1733               33:   APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
    1734                 : 
    1735               50:   APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
    1736               50:     Expr* SubExpr = E->getSubExpr();
    1737                 : 
                       27: branch 3 taken
                       23: branch 4 taken
    1738               50:     if (SubExpr->getType()->isRealFloatingType()) {
    1739               27:       APFloat Result(0.0);
    1740                 : 
                        0: branch 1 not taken
                       27: branch 2 taken
    1741               27:       if (!EvaluateFloat(SubExpr, Result, Info))
    1742                0:         return APValue();
    1743                 : 
    1744                 :       return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false),
    1745               27:                      Result);
    1746                 :     } else {
    1747                 :       assert(SubExpr->getType()->isIntegerType() &&
                       23: branch 3 taken
                        0: branch 4 not taken
    1748               23:              "Unexpected imaginary literal.");
    1749                 : 
    1750               23:       llvm::APSInt Result;
                        0: branch 1 not taken
                       23: branch 2 taken
    1751               23:       if (!EvaluateInteger(SubExpr, Result, Info))
    1752                0:         return APValue();
    1753                 : 
    1754               23:       llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
    1755               23:       Zero = 0;
    1756               23:       return APValue(Zero, Result);
    1757                 :     }
    1758                 :   }
    1759                 : 
    1760               83:   APValue VisitCastExpr(CastExpr *E) {
    1761               83:     Expr* SubExpr = E->getSubExpr();
    1762               83:     QualType EltType = E->getType()->getAs<ComplexType>()->getElementType();
    1763               83:     QualType SubType = SubExpr->getType();
    1764                 : 
                       26: branch 2 taken
                       57: branch 3 taken
    1765               83:     if (SubType->isRealFloatingType()) {
    1766               26:       APFloat Result(0.0);
    1767                 : 
                        0: branch 1 not taken
                       26: branch 2 taken
    1768               26:       if (!EvaluateFloat(SubExpr, Result, Info))
    1769                0:         return APValue();
    1770                 : 
                       26: branch 2 taken
                        0: branch 3 not taken
    1771               26:       if (EltType->isRealFloatingType()) {
    1772               26:         Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
    1773                 :         return APValue(Result,
    1774               26:                        APFloat(Result.getSemantics(), APFloat::fcZero, false));
    1775                 :       } else {
    1776                0:         llvm::APSInt IResult;
    1777                0:         IResult = HandleFloatToIntCast(EltType, SubType, Result, Info.Ctx);
    1778                0:         llvm::APSInt Zero(IResult.getBitWidth(), !IResult.isSigned());
    1779                0:         Zero = 0;
    1780                0:         return APValue(IResult, Zero);
    1781               26:       }
                       34: branch 2 taken
                       23: branch 3 taken
    1782               57:     } else if (SubType->isIntegerType()) {
    1783               34:       APSInt Result;
    1784                 : 
                        2: branch 1 taken
                       32: branch 2 taken
    1785               34:       if (!EvaluateInteger(SubExpr, Result, Info))
    1786                2:         return APValue();
    1787                 : 
                        3: branch 2 taken
                       29: branch 3 taken
    1788               32:       if (EltType->isRealFloatingType()) {
    1789                 :         APFloat FResult =
    1790                3:             HandleIntToFloatCast(EltType, SubType, Result, Info.Ctx);
    1791                 :         return APValue(FResult,
    1792                3:                        APFloat(FResult.getSemantics(), APFloat::fcZero, false));
    1793                 :       } else {
    1794               29:         Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
    1795               29:         llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
    1796               29:         Zero = 0;
    1797               29:         return APValue(Result, Zero);
    1798               34:       }
                       23: branch 2 taken
                        0: branch 3 not taken
    1799               23:     } else if (const ComplexType *CT = SubType->getAs<ComplexType>()) {
    1800               23:       APValue Src;
    1801                 : 
                       17: branch 1 taken
                        6: branch 2 taken
    1802               23:       if (!EvaluateComplex(SubExpr, Src, Info))
    1803               17:         return APValue();
    1804                 : 
    1805                6:       QualType SrcType = CT->getElementType();
    1806                 : 
                        4: branch 1 taken
                        2: branch 2 taken
    1807                6:       if (Src.isComplexFloat()) {
                        4: branch 2 taken
                        0: branch 3 not taken
    1808                4:         if (EltType->isRealFloatingType()) {
    1809                 :           return APValue(HandleFloatToFloatCast(EltType, SrcType,
    1810                 :                                                 Src.getComplexFloatReal(),
    1811                 :                                                 Info.Ctx),
    1812                 :                          HandleFloatToFloatCast(EltType, SrcType,
    1813                 :                                                 Src.getComplexFloatImag(),
    1814                4:                                                 Info.Ctx));
    1815                 :         } else {
    1816                 :           return APValue(HandleFloatToIntCast(EltType, SrcType,
    1817                 :                                               Src.getComplexFloatReal(),
    1818                 :                                               Info.Ctx),
    1819                 :                          HandleFloatToIntCast(EltType, SrcType,
    1820                 :                                               Src.getComplexFloatImag(),
    1821                0:                                               Info.Ctx));
    1822                 :         }
    1823                 :       } else {
                        2: branch 1 taken
                        0: branch 2 not taken
    1824                2:         assert(Src.isComplexInt() && "Invalid evaluate result.");
                        0: branch 2 not taken
                        2: branch 3 taken
    1825                2:         if (EltType->isRealFloatingType()) {
    1826                 :           return APValue(HandleIntToFloatCast(EltType, SrcType,
    1827                 :                                               Src.getComplexIntReal(),
    1828                 :                                               Info.Ctx),
    1829                 :                          HandleIntToFloatCast(EltType, SrcType,
    1830                 :                                               Src.getComplexIntImag(),
    1831                0:                                               Info.Ctx));
    1832                 :         } else {
    1833                 :           return APValue(HandleIntToIntCast(EltType, SrcType,
    1834                 :                                             Src.getComplexIntReal(),
    1835                 :                                             Info.Ctx),
    1836                 :                          HandleIntToIntCast(EltType, SrcType,
    1837                 :                                             Src.getComplexIntImag(),
    1838                2:                                             Info.Ctx));
    1839                 :         }
    1840               23:       }
    1841                 :     }
    1842                 : 
    1843                 :     // FIXME: Handle more casts.
    1844                0:     return APValue();
    1845                 :   }
    1846                 : 
    1847                 :   APValue VisitBinaryOperator(const BinaryOperator *E);
    1848                0:   APValue VisitChooseExpr(const ChooseExpr *E)
    1849                0:     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
    1850                0:   APValue VisitUnaryExtension(const UnaryOperator *E)
    1851                0:     { return Visit(E->getSubExpr()); }
    1852                 :   // FIXME Missing: unary +/-/~, binary div, ImplicitValueInitExpr,
    1853                 :   //                conditional ?:, comma
    1854                 : };
    1855                 : } // end anonymous namespace
    1856                 : 
    1857              255: static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info) {
    1858              255:   Result = ComplexExprEvaluator(Info).Visit(const_cast<Expr*>(E));
    1859                 :   assert((!Result.isComplexFloat() ||
    1860                 :           (&Result.getComplexFloatReal().getSemantics() ==
    1861                 :            &Result.getComplexFloatImag().getSemantics())) &&
                       90: branch 1 taken
                      165: branch 2 taken
                       90: branch 7 taken
                        0: branch 8 not taken
    1862              255:          "Invalid complex evaluation.");
                      165: branch 1 taken
                       90: branch 2 taken
                       83: branch 4 taken
                       82: branch 5 taken
    1863              420:   return Result.isComplexFloat() || Result.isComplexInt();
    1864                 : }
    1865                 : 
    1866               70: APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
    1867               70:   APValue Result, RHS;
    1868                 : 
                       11: branch 2 taken
                       59: branch 3 taken
    1869               70:   if (!EvaluateComplex(E->getLHS(), Result, Info))
    1870               11:     return APValue();
    1871                 : 
                        0: branch 2 not taken
                       59: branch 3 taken
    1872               59:   if (!EvaluateComplex(E->getRHS(), RHS, Info))
    1873                0:     return APValue();
    1874                 : 
    1875                 :   assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
                       59: branch 2 taken
                        0: branch 3 not taken
    1876               59:          "Invalid operands to binary operator.");
                        0: branch 1 not taken
                       46: branch 2 taken
                        0: branch 3 not taken
                       13: branch 4 taken
    1877               59:   switch (E->getOpcode()) {
    1878                0:   default: return APValue();
    1879                 :   case BinaryOperator::Add:
                       24: branch 1 taken
                       22: branch 2 taken
    1880               46:     if (Result.isComplexFloat()) {
    1881                 :       Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
    1882               24:                                        APFloat::rmNearestTiesToEven);
    1883                 :       Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
    1884               24:                                        APFloat::rmNearestTiesToEven);
    1885                 :     } else {
    1886               22:       Result.getComplexIntReal() += RHS.getComplexIntReal();
    1887               22:       Result.getComplexIntImag() += RHS.getComplexIntImag();
    1888                 :     }
    1889               46:     break;
    1890                 :   case BinaryOperator::Sub:
                        0: branch 1 not taken
                        0: branch 2 not taken
    1891                0:     if (Result.isComplexFloat()) {
    1892                 :       Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
    1893                0:                                             APFloat::rmNearestTiesToEven);
    1894                 :       Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
    1895                0:                                             APFloat::rmNearestTiesToEven);
    1896                 :     } else {
    1897                0:       Result.getComplexIntReal() -= RHS.getComplexIntReal();
    1898                0:       Result.getComplexIntImag() -= RHS.getComplexIntImag();
    1899                 :     }
    1900                0:     break;
    1901                 :   case BinaryOperator::Mul:
                        6: branch 1 taken
                        7: branch 2 taken
    1902               13:     if (Result.isComplexFloat()) {
    1903                6:       APValue LHS = Result;
    1904                6:       APFloat &LHS_r = LHS.getComplexFloatReal();
    1905                6:       APFloat &LHS_i = LHS.getComplexFloatImag();
    1906                6:       APFloat &RHS_r = RHS.getComplexFloatReal();
    1907                6:       APFloat &RHS_i = RHS.getComplexFloatImag();
    1908                 : 
    1909                6:       APFloat Tmp = LHS_r;
    1910                6:       Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
    1911                6:       Result.getComplexFloatReal() = Tmp;
    1912                6:       Tmp = LHS_i;
    1913                6:       Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
    1914                6:       Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven);
    1915                 : 
    1916                6:       Tmp = LHS_r;
    1917                6:       Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
    1918                6:       Result.getComplexFloatImag() = Tmp;
    1919                6:       Tmp = LHS_i;
    1920                6:       Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
    1921                6:       Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
    1922                 :     } else {
    1923                7:       APValue LHS = Result;
    1924                 :       Result.getComplexIntReal() =
    1925                 :         (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
    1926                7:          LHS.getComplexIntImag() * RHS.getComplexIntImag());
    1927                 :       Result.getComplexIntImag() =
    1928                 :         (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
    1929                7:          LHS.getComplexIntImag() * RHS.getComplexIntReal());
    1930                 :     }
    1931                 :     break;
    1932                 :   }
    1933                 : 
    1934               59:   return Result;
    1935                 : }
    1936                 : 
    1937                 : //===----------------------------------------------------------------------===//
    1938                 : // Top level Expr::Evaluate method.
    1939                 : //===----------------------------------------------------------------------===//
    1940                 : 
    1941                 : /// Evaluate - Return true if this is a constant which we can fold using
    1942                 : /// any crazy technique (that has nothing to do with language standards) that
    1943                 : /// we want to.  If this function returns true, it returns the folded constant
    1944                 : /// in Result.
    1945            26037: bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
    1946            26037:   EvalInfo Info(Ctx, Result);
    1947                 : 
                      743: branch 3 taken
                    25294: branch 4 taken
    1948            26037:   if (getType()->isVectorType()) {
                      732: branch 1 taken
                       11: branch 2 taken
    1949              743:     if (!EvaluateVector(this, Result.Val, Info))
    1950              732:       return false;
                    22408: branch 3 taken
                     2886: branch 4 taken
    1951            25294:   } else if (getType()->isIntegerType()) {
                     5711: branch 2 taken
                    16697: branch 3 taken
    1952            22408:     if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
    1953             5711:       return false;
                     1742: branch 3 taken
                     1144: branch 4 taken
    1954             2886:   } else if (getType()->hasPointerRepresentation()) {
                     1283: branch 1 taken
                      459: branch 2 taken
    1955             1742:     if (!EvaluatePointer(this, Result.Val, Info))
    1956             1283:       return false;
                      621: branch 3 taken
                      523: branch 4 taken
    1957             1144:   } else if (getType()->isRealFloatingType()) {
    1958              621:     llvm::APFloat f(0.0);
                      211: branch 1 taken
                      410: branch 2 taken
    1959              621:     if (!EvaluateFloat(this, f, Info))
    1960              422:       return false;
    1961                 : 
                      410: branch 4 taken
                      211: branch 5 taken
    1962              410:     Result.Val = APValue(f);
                       76: branch 3 taken
                      447: branch 4 taken
    1963              523:   } else if (getType()->isAnyComplexType()) {
                       54: branch 1 taken
                       22: branch 2 taken
    1964               76:     if (!EvaluateComplex(this, Result.Val, Info))
    1965               54:       return false;
    1966                 :   } else
    1967              447:     return false;
    1968                 : 
    1969            17599:   return true;
    1970                 : }
    1971                 : 
    1972               64: bool Expr::EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const {
    1973               64:   EvalInfo Info(Ctx, Result, true);
    1974                 : 
                        0: branch 3 not taken
                       64: branch 4 taken
    1975               64:   if (getType()->isVectorType()) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1976                0:     if (!EvaluateVector(this, Result.Val, Info))
    1977                0:       return false;
                        0: branch 3 not taken
                       64: branch 4 taken
    1978               64:   } else if (getType()->isIntegerType()) {
                        0: branch 2 not taken
                        0: branch 3 not taken
    1979                0:     if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
    1980                0:       return false;
                       64: branch 3 taken
                        0: branch 4 not taken
    1981               64:   } else if (getType()->hasPointerRepresentation()) {
                       33: branch 1 taken
                       31: branch 2 taken
    1982               64:     if (!EvaluatePointer(this, Result.Val, Info))
    1983               33:       return false;
                        0: branch 3 not taken
                        0: branch 4 not taken
    1984                0:   } else if (getType()->isRealFloatingType()) {
    1985                0:     llvm::APFloat f(0.0);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1986                0:     if (!EvaluateFloat(this, f, Info))
    1987                0:       return false;
    1988                 : 
                        0: branch 4 not taken
                        0: branch 5 not taken
    1989                0:     Result.Val = APValue(f);
                        0: branch 3 not taken
                        0: branch 4 not taken
    1990                0:   } else if (getType()->isAnyComplexType()) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1991                0:     if (!EvaluateComplex(this, Result.Val, Info))
    1992                0:       return false;
    1993                 :   } else
    1994                0:     return false;
    1995                 : 
    1996               31:   return true;
    1997                 : }
    1998                 : 
    1999                9: bool Expr::EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const {
    2000                9:   EvalResult Scratch;
    2001                9:   EvalInfo Info(Ctx, Scratch);
    2002                 : 
    2003                9:   return HandleConversionToBool(this, Result, Info);
    2004                 : }
    2005                 : 
    2006                9: bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
    2007                9:   EvalInfo Info(Ctx, Result);
    2008                 : 
                        7: branch 1 taken
                        2: branch 2 taken
                        7: branch 3 taken
                        0: branch 4 not taken
    2009                9:   return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
    2010                 : }
    2011                 : 
    2012                0: bool Expr::EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const {
    2013                0:   EvalInfo Info(Ctx, Result, true);
    2014                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
    2015                0:   return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
    2016                 : }
    2017                 : 
    2018                 : /// isEvaluatable - Call Evaluate to see if this expression can be constant
    2019                 : /// folded, but discard the result.
    2020             1264: bool Expr::isEvaluatable(ASTContext &Ctx) const {
    2021             1264:   EvalResult Result;
                     1153: branch 1 taken
                      111: branch 2 taken
                     1153: branch 3 taken
                        0: branch 4 not taken
    2022             1264:   return Evaluate(Result, Ctx) && !Result.HasSideEffects;
    2023                 : }
    2024                 : 
    2025               65: bool Expr::HasSideEffects(ASTContext &Ctx) const {
    2026               65:   Expr::EvalResult Result;
    2027               65:   EvalInfo Info(Ctx, Result);
    2028               65:   return HasSideEffect(Info).Visit(const_cast<Expr*>(this));
    2029                 : }
    2030                 : 
    2031             1204: APSInt Expr::EvaluateAsInt(ASTContext &Ctx) const {
    2032             1204:   EvalResult EvalResult;
    2033             1204:   bool Result = Evaluate(EvalResult, Ctx);
    2034             1204:   Result = Result;
                        0: branch 0 not taken
                     1204: branch 1 taken
    2035             1204:   assert(Result && "Could not evaluate expression");
                     1204: branch 1 taken
                        0: branch 2 not taken
    2036             1204:   assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");
    2037                 : 
    2038             1204:   return EvalResult.Val.getInt();
    2039                 : }

Generated: 2010-02-10 01:31 by zcov