zcov: / lib/Lex/PPExpressions.cpp


Files: 1 Branches Taken: 78.1% 232 / 297
Generated: 2010-02-10 01:31 Branches Executed: 93.9% 279 / 297
Line Coverage: 85.1% 291 / 342


Programs: 2 Runs 3018


       1                 : //===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
       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 Preprocessor::EvaluateDirectiveExpression method,
      11                 : // which parses and evaluates integer constant expressions for #if directives.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : //
      15                 : // FIXME: implement testing for #assert's.
      16                 : //
      17                 : //===----------------------------------------------------------------------===//
      18                 : 
      19                 : #include "clang/Lex/Preprocessor.h"
      20                 : #include "clang/Lex/MacroInfo.h"
      21                 : #include "clang/Lex/LiteralSupport.h"
      22                 : #include "clang/Basic/TargetInfo.h"
      23                 : #include "clang/Lex/LexDiagnostic.h"
      24                 : #include "llvm/ADT/APSInt.h"
      25                 : using namespace clang;
      26                 : 
      27                 : /// PPValue - Represents the value of a subexpression of a preprocessor
      28                 : /// conditional and the source range covered by it.
      29             8459: class PPValue {
      30                 :   SourceRange Range;
      31                 : public:
      32                 :   llvm::APSInt Val;
      33                 : 
      34                 :   // Default ctor - Construct an 'invalid' PPValue.
      35             8459:   PPValue(unsigned BitWidth) : Val(BitWidth) {}
      36                 : 
      37            12197:   unsigned getBitWidth() const { return Val.getBitWidth(); }
      38             7630:   bool isUnsigned() const { return Val.isUnsigned(); }
      39                 : 
      40             6121:   const SourceRange &getRange() const { return Range; }
      41                 : 
      42             5367:   void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
      43             3283:   void setRange(SourceLocation B, SourceLocation E) {
      44             3283:     Range.setBegin(B); Range.setEnd(E);
      45             3283:   }
      46             4073:   void setBegin(SourceLocation L) { Range.setBegin(L); }
      47             9346:   void setEnd(SourceLocation L) { Range.setEnd(L); }
      48                 : };
      49                 : 
      50                 : static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
      51                 :                                      Token &PeekTok, bool ValueLive,
      52                 :                                      Preprocessor &PP);
      53                 : 
      54                 : /// DefinedTracker - This struct is used while parsing expressions to keep track
      55                 : /// of whether !defined(X) has been seen.
      56                 : ///
      57                 : /// With this simple scheme, we handle the basic forms:
      58                 : ///    !defined(X)   and !defined X
      59                 : /// but we also trivially handle (silly) stuff like:
      60                 : ///    !!!defined(X) and +!defined(X) and !+!+!defined(X) and !(defined(X)).
      61                 : struct DefinedTracker {
      62                 :   /// Each time a Value is evaluated, it returns information about whether the
      63                 :   /// parsed value is of the form defined(X), !defined(X) or is something else.
      64                 :   enum TrackerState {
      65                 :     DefinedMacro,        // defined(X)
      66                 :     NotDefinedMacro,     // !defined(X)
      67                 :     Unknown              // Something else.
      68                 :   } State;
      69                 :   /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this
      70                 :   /// indicates the macro that was checked.
      71                 :   IdentifierInfo *TheMacro;
      72                 : };
      73                 : 
      74                 : /// EvaluateDefined - Process a 'defined(sym)' expression.
      75                 : static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
      76             3088:                             bool ValueLive, Preprocessor &PP) {
      77                 :   IdentifierInfo *II;
      78             3088:   Result.setBegin(PeekTok.getLocation());
      79                 : 
      80                 :   // Get the next token, don't expand it.
      81             3088:   PP.LexUnexpandedToken(PeekTok);
      82                 : 
      83                 :   // Two options, it can either be a pp-identifier or a (.
      84             3088:   SourceLocation LParenLoc;
                      156: branch 1 taken
                     2932: branch 2 taken
      85             3088:   if (PeekTok.is(tok::l_paren)) {
      86                 :     // Found a paren, remember we saw it and skip it.
      87              156:     LParenLoc = PeekTok.getLocation();
      88              156:     PP.LexUnexpandedToken(PeekTok);
      89                 :   }
      90                 : 
      91                 :   // If we don't have a pp-identifier now, this is an error.
                        0: branch 1 not taken
                     3088: branch 2 taken
      92             3088:   if ((II = PeekTok.getIdentifierInfo()) == 0) {
      93                0:     PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
      94                0:     return true;
      95                 :   }
      96                 : 
      97                 :   // Otherwise, we got an identifier, is it defined to something?
      98             3088:   Result.Val = II->hasMacroDefinition();
      99             3088:   Result.Val.setIsUnsigned(false);  // Result is signed intmax_t.
     100                 : 
     101                 :   // If there is a macro, mark it used.
                     1227: branch 1 taken
                     1861: branch 2 taken
                      764: branch 3 taken
                      463: branch 4 taken
                      764: branch 5 taken
                     2324: branch 6 taken
     102             3088:   if (Result.Val != 0 && ValueLive) {
     103              764:     MacroInfo *Macro = PP.getMacroInfo(II);
     104              764:     Macro->setIsUsed(true);
     105                 :   }
     106                 : 
     107                 :   // Consume identifier.
     108             3088:   Result.setEnd(PeekTok.getLocation());
     109             3088:   PP.LexNonComment(PeekTok);
     110                 : 
     111                 :   // If we are in parens, ensure we have a trailing ).
                      156: branch 1 taken
                     2932: branch 2 taken
     112             3088:   if (LParenLoc.isValid()) {
                        0: branch 1 not taken
                      156: branch 2 taken
     113              156:     if (PeekTok.isNot(tok::r_paren)) {
     114                0:       PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
     115                0:       PP.Diag(LParenLoc, diag::note_matching) << "(";
     116                0:       return true;
     117                 :     }
     118                 :     // Consume the ).
     119              156:     Result.setEnd(PeekTok.getLocation());
     120              156:     PP.LexNonComment(PeekTok);
     121                 :   }
     122                 : 
     123                 :   // Success, remember that we saw defined(X).
     124             3088:   DT.State = DefinedTracker::DefinedMacro;
     125             3088:   DT.TheMacro = II;
     126             3088:   return false;
     127                 : }
     128                 : 
     129                 : /// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
     130                 : /// return the computed value in Result.  Return true if there was an error
     131                 : /// parsing.  This function also returns information about the form of the
     132                 : /// expression in DT.  See above for information on what DT means.
     133                 : ///
     134                 : /// If ValueLive is false, then this value is being evaluated in a context where
     135                 : /// the result is not used.  As such, avoid diagnostics that relate to
     136                 : /// evaluation.
     137                 : static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
     138            12727:                           bool ValueLive, Preprocessor &PP) {
     139            12727:   DT.State = DefinedTracker::Unknown;
     140                 : 
     141                 :   // If this token's spelling is a pp-identifier, check to see if it is
     142                 :   // 'defined' or if it is a macro.  Note that we check here because many
     143                 :   // keywords are pp-identifiers, so we can't check the kind.
                     3284: branch 1 taken
                     9443: branch 2 taken
     144            12727:   if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
     145                 :     // Handle "defined X" and "defined(X)".
                     3088: branch 1 taken
                      196: branch 2 taken
     146             3284:     if (II->isStr("defined"))
     147             3088:       return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
     148                 :     
     149                 :     // If this identifier isn't 'defined' or one of the special
     150                 :     // preprocessor keywords and it wasn't macro expanded, it turns
     151                 :     // into a simple 0, unless it is the C++ keyword "true", in which case it
     152                 :     // turns into "1".
                       37: branch 0 taken
                      159: branch 1 taken
     153              196:     if (ValueLive)
     154               37:       PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
     155              196:     Result.Val = II->getTokenID() == tok::kw_true;
     156              196:     Result.Val.setIsUnsigned(false);  // "0" is signed intmax_t 0.
     157              196:     Result.setRange(PeekTok.getLocation());
     158              196:     PP.LexNonComment(PeekTok);
     159              196:     return false;
     160                 :   }
     161                 : 
                        3: branch 1 taken
                        1: branch 2 taken
                     5169: branch 3 taken
                        2: branch 4 taken
                     3283: branch 5 taken
                        0: branch 6 not taken
                        5: branch 7 taken
                        6: branch 8 taken
                      974: branch 9 taken
     162             9443:   switch (PeekTok.getKind()) {
     163                 :   default:  // Non-value token.
     164                3:     PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
     165                3:     return true;
     166                 :   case tok::eom:
     167                 :   case tok::r_paren:
     168                 :     // If there is no expression, report and exit.
     169                1:     PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
     170                1:     return true;
     171                 :   case tok::numeric_constant: {
     172             5169:     llvm::SmallString<64> IntegerBuffer;
     173             5169:     IntegerBuffer.resize(PeekTok.getLength());
     174             5169:     const char *ThisTokBegin = &IntegerBuffer[0];
     175             5169:     unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
     176                 :     NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
     177             5169:                                  PeekTok.getLocation(), PP);
                        0: branch 0 not taken
                     5169: branch 1 taken
     178             5169:     if (Literal.hadError)
     179                0:       return true; // a diagnostic was already reported.
     180                 : 
                     5169: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                     5169: branch 4 taken
                        0: branch 5 not taken
                     5169: branch 6 taken
     181             5169:     if (Literal.isFloatingLiteral() || Literal.isImaginary) {
     182                0:       PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
     183                0:       return true;
     184                 :     }
                     5169: branch 1 taken
                        0: branch 2 not taken
     185             5169:     assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
     186                 : 
     187                 :     // long long is a C99 feature.
                     1051: branch 1 taken
                     4118: branch 2 taken
                      867: branch 4 taken
                      184: branch 5 taken
                        1: branch 6 taken
                      866: branch 7 taken
                        1: branch 8 taken
                     5168: branch 9 taken
     188             6220:     if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
     189                 :         && Literal.isLongLong)
     190                1:       PP.Diag(PeekTok, diag::ext_longlong);
     191                 : 
     192                 :     // Parse the integer literal into Result.
                        0: branch 1 not taken
                     5169: branch 2 taken
     193             5169:     if (Literal.GetIntegerValue(Result.Val)) {
     194                 :       // Overflow parsing integer literal.
                        0: branch 0 not taken
                        0: branch 1 not taken
     195                0:       if (ValueLive) PP.Diag(PeekTok, diag::warn_integer_too_large);
     196                0:       Result.Val.setIsUnsigned(true);
     197                 :     } else {
     198                 :       // Set the signedness of the result to match whether there was a U suffix
     199                 :       // or not.
     200             5169:       Result.Val.setIsUnsigned(Literal.isUnsigned);
     201                 : 
     202                 :       // Detect overflow based on whether the value is signed.  If signed
     203                 :       // and if the value is too large, emit a warning "integer constant is so
     204                 :       // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
     205                 :       // is 64-bits.
                     5167: branch 0 taken
                        2: branch 1 taken
                        4: branch 3 taken
                     5163: branch 4 taken
                        4: branch 5 taken
                     5165: branch 6 taken
     206             5169:       if (!Literal.isUnsigned && Result.Val.isNegative()) {
     207                 :         // Don't warn for a hex literal: 0x8000..0 shouldn't warn.
                        4: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        4: branch 4 taken
                        0: branch 5 not taken
                        4: branch 6 taken
     208                4:         if (ValueLive && Literal.getRadix() != 16)
     209                0:           PP.Diag(PeekTok, diag::warn_integer_too_large_for_signed);
     210                4:         Result.Val.setIsUnsigned(true);
     211                 :       }
     212                 :     }
     213                 : 
     214                 :     // Consume the token.
     215             5169:     Result.setRange(PeekTok.getLocation());
     216             5169:     PP.LexNonComment(PeekTok);
     217             5169:     return false;
     218                 :   }
     219                 :   case tok::char_constant: {   // 'x'
     220                2:     llvm::SmallString<32> CharBuffer;
     221                2:     CharBuffer.resize(PeekTok.getLength());
     222                2:     const char *ThisTokBegin = &CharBuffer[0];
     223                2:     unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
     224                 :     CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
     225                2:                               PeekTok.getLocation(), PP);
                        0: branch 1 not taken
                        2: branch 2 taken
     226                2:     if (Literal.hadError())
     227                0:       return true;  // A diagnostic was already emitted.
     228                 : 
     229                 :     // Character literals are always int or wchar_t, expand to intmax_t.
     230                2:     const TargetInfo &TI = PP.getTargetInfo();
     231                 :     unsigned NumBits;
                        1: branch 1 taken
                        1: branch 2 taken
     232                2:     if (Literal.isMultiChar())
     233                1:       NumBits = TI.getIntWidth();
                        0: branch 1 not taken
                        1: branch 2 taken
     234                1:     else if (Literal.isWide())
     235                0:       NumBits = TI.getWCharWidth();
     236                 :     else
     237                1:       NumBits = TI.getCharWidth();
     238                 : 
     239                 :     // Set the width.
     240                2:     llvm::APSInt Val(NumBits);
     241                 :     // Set the value.
     242                2:     Val = Literal.getValue();
     243                 :     // Set the signedness.
     244                2:     Val.setIsUnsigned(!PP.getLangOptions().CharIsSigned);
     245                 : 
                        2: branch 2 taken
                        0: branch 3 not taken
     246                2:     if (Result.Val.getBitWidth() > Val.getBitWidth()) {
     247                2:       Result.Val = Val.extend(Result.Val.getBitWidth());
     248                 :     } else {
     249                 :       assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
                        0: branch 2 not taken
                        0: branch 3 not taken
     250                0:              "intmax_t smaller than char/wchar_t?");
     251                0:       Result.Val = Val;
     252                 :     }
     253                 : 
     254                 :     // Consume the token.
     255                2:     Result.setRange(PeekTok.getLocation());
     256                2:     PP.LexNonComment(PeekTok);
     257                2:     return false;
     258                 :   }
     259                 :   case tok::l_paren: {
     260             3283:     SourceLocation Start = PeekTok.getLocation();
     261             3283:     PP.LexNonComment(PeekTok);  // Eat the (.
     262                 :     // Parse the value and if there are any binary operators involved, parse
     263                 :     // them.
                        0: branch 1 not taken
                     3283: branch 2 taken
     264             3283:     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     265                 : 
     266                 :     // If this is a silly value like (X), which doesn't need parens, check for
     267                 :     // !(defined X).
                     2227: branch 1 taken
                     1056: branch 2 taken
     268             3283:     if (PeekTok.is(tok::r_paren)) {
     269                 :       // Just use DT unmodified as our result.
     270                 :     } else {
     271                 :       // Otherwise, we have something like (x+y), and we consumed '(x'.
                        0: branch 1 not taken
                     2227: branch 2 taken
     272             2227:       if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP))
     273                0:         return true;
     274                 : 
                        0: branch 1 not taken
                     2227: branch 2 taken
     275             2227:       if (PeekTok.isNot(tok::r_paren)) {
     276                 :         PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
     277                0:           << Result.getRange();
     278                0:         PP.Diag(Start, diag::note_matching) << "(";
     279                0:         return true;
     280                 :       }
     281             2227:       DT.State = DefinedTracker::Unknown;
     282                 :     }
     283             3283:     Result.setRange(Start, PeekTok.getLocation());
     284             3283:     PP.LexNonComment(PeekTok);  // Eat the ).
     285             3283:     return false;
     286                 :   }
     287                 :   case tok::plus: {
     288                0:     SourceLocation Start = PeekTok.getLocation();
     289                 :     // Unary plus doesn't modify the value.
     290                0:     PP.LexNonComment(PeekTok);
                        0: branch 1 not taken
                        0: branch 2 not taken
     291                0:     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     292                0:     Result.setBegin(Start);
     293                0:     return false;
     294                 :   }
     295                 :   case tok::minus: {
     296                5:     SourceLocation Loc = PeekTok.getLocation();
     297                5:     PP.LexNonComment(PeekTok);
                        0: branch 1 not taken
                        5: branch 2 taken
     298                5:     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     299                5:     Result.setBegin(Loc);
     300                 : 
     301                 :     // C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
     302                5:     Result.Val = -Result.Val;
     303                 : 
     304                 :     // -MININT is the only thing that overflows.  Unsigned never overflows.
                        4: branch 1 taken
                        1: branch 2 taken
                        0: branch 4 not taken
                        4: branch 5 taken
     305                5:     bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
     306                 : 
     307                 :     // If this operator is live and overflowed, report the issue.
                        0: branch 0 not taken
                        5: branch 1 taken
                        5: branch 2 taken
                        5: branch 3 taken
     308                5:     if (Overflow && ValueLive)
     309                0:       PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
     310                 : 
     311                5:     DT.State = DefinedTracker::Unknown;
     312                5:     return false;
     313                 :   }
     314                 : 
     315                 :   case tok::tilde: {
     316                6:     SourceLocation Start = PeekTok.getLocation();
     317                6:     PP.LexNonComment(PeekTok);
                        0: branch 1 not taken
                        6: branch 2 taken
     318                6:     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     319                6:     Result.setBegin(Start);
     320                 : 
     321                 :     // C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
     322                6:     Result.Val = ~Result.Val;
     323                6:     DT.State = DefinedTracker::Unknown;
     324                6:     return false;
     325                 :   }
     326                 : 
     327                 :   case tok::exclaim: {
     328              974:     SourceLocation Start = PeekTok.getLocation();
     329              974:     PP.LexNonComment(PeekTok);
                        0: branch 1 not taken
                      974: branch 2 taken
     330              974:     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     331              974:     Result.setBegin(Start);
     332              974:     Result.Val = !Result.Val;
     333                 :     // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
     334              974:     Result.Val.setIsUnsigned(false);
     335                 : 
                      875: branch 0 taken
                       99: branch 1 taken
     336              974:     if (DT.State == DefinedTracker::DefinedMacro)
     337              875:       DT.State = DefinedTracker::NotDefinedMacro;
                        0: branch 0 not taken
                       99: branch 1 taken
     338               99:     else if (DT.State == DefinedTracker::NotDefinedMacro)
     339                0:       DT.State = DefinedTracker::DefinedMacro;
     340              974:     return false;
     341                 :   }
     342                 : 
     343                 :   // FIXME: Handle #assert
     344                 :   }
     345                 : }
     346                 : 
     347                 : 
     348                 : 
     349                 : /// getPrecedence - Return the precedence of the specified binary operator
     350                 : /// token.  This returns:
     351                 : ///   ~0 - Invalid token.
     352                 : ///   14 -> 3 - various operators.
     353                 : ///    0 - 'eom' or ')'
     354            13383: static unsigned getPrecedence(tok::TokenKind Kind) {
                        3: branch 0 taken
                       18: branch 1 taken
                     1744: branch 2 taken
                     1058: branch 3 taken
                     1353: branch 4 taken
                      407: branch 5 taken
                       12: branch 6 taken
                       10: branch 7 taken
                       10: branch 8 taken
                     1318: branch 9 taken
                     1124: branch 10 taken
                     1628: branch 11 taken
                       27: branch 12 taken
                       24: branch 13 taken
                     2861: branch 14 taken
                     1786: branch 15 taken
     355            13383:   switch (Kind) {
     356                3:   default: return ~0U;
     357                 :   case tok::percent:
     358                 :   case tok::slash:
     359               18:   case tok::star:                 return 14;
     360                 :   case tok::plus:
     361             1744:   case tok::minus:                return 13;
     362                 :   case tok::lessless:
     363             1058:   case tok::greatergreater:       return 12;
     364                 :   case tok::lessequal:
     365                 :   case tok::less:
     366                 :   case tok::greaterequal:
     367             1353:   case tok::greater:              return 11;
     368                 :   case tok::exclaimequal:
     369              407:   case tok::equalequal:           return 10;
     370               12:   case tok::amp:                  return 9;
     371               10:   case tok::caret:                return 8;
     372               10:   case tok::pipe:                 return 7;
     373             1318:   case tok::ampamp:               return 6;
     374             1124:   case tok::pipepipe:             return 5;
     375             1628:   case tok::question:             return 4;
     376               27:   case tok::comma:                return 3;
     377               24:   case tok::colon:                return 2;
     378             2861:   case tok::r_paren:              return 0;   // Lowest priority, end of expr.
     379             1786:   case tok::eom:                  return 0;   // Lowest priority, end of macro.
     380                 :   }
     381                 : }
     382                 : 
     383                 : 
     384                 : /// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
     385                 : /// PeekTok, and whose precedence is PeekPrec.  This returns the result in LHS.
     386                 : ///
     387                 : /// If ValueLive is false, then this value is being evaluated in a context where
     388                 : /// the result is not used.  As such, avoid diagnostics that relate to
     389                 : /// evaluation, such as division by zero warnings.
     390                 : static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
     391                 :                                      Token &PeekTok, bool ValueLive,
     392             4753:                                      Preprocessor &PP) {
     393             4753:   unsigned PeekPrec = getPrecedence(PeekTok.getKind());
     394                 :   // If this token isn't valid, report the error.
                        3: branch 0 taken
                     4750: branch 1 taken
     395             4753:   if (PeekPrec == ~0U) {
     396                 :     PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
     397                3:       << LHS.getRange();
     398                3:     return true;
     399                 :   }
     400                 : 
                     6086: branch 1 taken
                        2: branch 2 taken
                     6086: branch 4 taken
                        5: branch 5 taken
     401             6088:   while (1) {
     402                 :     // If this token has a lower precedence than we are allowed to parse, return
     403                 :     // it so that higher levels of the recursion can parse it.
                     4745: branch 0 taken
                     6091: branch 1 taken
     404            10836:     if (PeekPrec < MinPrec)
     405             4745:       return false;
     406                 : 
     407             6091:     tok::TokenKind Operator = PeekTok.getKind();
     408                 : 
     409                 :     // If this is a short-circuiting operator, see if the RHS of the operator is
     410                 :     // dead.  Note that this cannot just clobber ValueLive.  Consider
     411                 :     // "0 && 1 ? 4 : 1 / 0", which is parsed as "(0 && 1) ? 4 : (1 / 0)".  In
     412                 :     // this example, the RHS of the && being dead does not make the rest of the
     413                 :     // expr dead.
     414                 :     bool RHSIsLive;
                     1286: branch 0 taken
                     4805: branch 1 taken
                      624: branch 3 taken
                      662: branch 4 taken
                      624: branch 5 taken
                     5467: branch 6 taken
     415             6091:     if (Operator == tok::ampamp && LHS.Val == 0)
     416              624:       RHSIsLive = false;   // RHS of "0 && x" is dead.
                     1070: branch 0 taken
                     4397: branch 1 taken
                      585: branch 3 taken
                      485: branch 4 taken
                      585: branch 5 taken
                     4882: branch 6 taken
     417             5467:     else if (Operator == tok::pipepipe && LHS.Val != 0)
     418              585:       RHSIsLive = false;   // RHS of "1 || x" is dead.
                       17: branch 0 taken
                     4865: branch 1 taken
                        5: branch 3 taken
                       12: branch 4 taken
                        5: branch 5 taken
                     4877: branch 6 taken
     419             4882:     else if (Operator == tok::question && LHS.Val == 0)
     420                5:       RHSIsLive = false;   // RHS (x) of "0 ? x : y" is dead.
     421                 :     else
     422             4877:       RHSIsLive = ValueLive;
     423                 : 
     424                 :     // Consume the operator, remembering the operator's location for reporting.
     425             6091:     SourceLocation OpLoc = PeekTok.getLocation();
     426             6091:     PP.LexNonComment(PeekTok);
     427                 : 
     428             6091:     PPValue RHS(LHS.getBitWidth());
     429                 :     // Parse the RHS of the operator.
     430                 :     DefinedTracker DT;
                        3: branch 1 taken
                     6088: branch 2 taken
     431             6096:     if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
     432                 : 
     433                 :     // Remember the precedence of this operator and get the precedence of the
     434                 :     // operator immediately to the right of the RHS.
     435             6088:     unsigned ThisPrec = PeekPrec;
     436             6088:     PeekPrec = getPrecedence(PeekTok.getKind());
     437                 : 
     438                 :     // If this token isn't valid, report the error.
                        0: branch 0 not taken
                     6088: branch 1 taken
     439             6088:     if (PeekPrec == ~0U) {
     440                 :       PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
     441                0:         << RHS.getRange();
     442                0:       return true;
     443                 :     }
     444                 : 
     445                 :     // Decide whether to include the next binop in this subexpression.  For
     446                 :     // example, when parsing x+y*z and looking at '*', we want to recursively
     447                 :     // handle y*z as a single subexpression.  We do this because the precedence
     448                 :     // of * is higher than that of +.  The only strange case we have to handle
     449                 :     // here is for the ?: operator, where the precedence is actually lower than
     450                 :     // the LHS of the '?'.  The grammar rule is:
     451                 :     //
     452                 :     // conditional-expression ::=
     453                 :     //    logical-OR-expression ? expression : conditional-expression
     454                 :     // where 'expression' is actually comma-expression.
     455                 :     unsigned RHSPrec;
                       17: branch 0 taken
                     6071: branch 1 taken
     456             6088:     if (Operator == tok::question)
     457                 :       // The RHS of "?" should be maximally consumed as an expression.
     458               17:       RHSPrec = getPrecedence(tok::comma);
     459                 :     else  // All others should munch while higher precedence.
     460             6071:       RHSPrec = ThisPrec+1;
     461                 : 
                      899: branch 0 taken
                     5189: branch 1 taken
     462             6088:     if (PeekPrec >= RHSPrec) {
                        0: branch 1 not taken
                      899: branch 2 taken
     463              899:       if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP))
     464                0:         return true;
     465              899:       PeekPrec = getPrecedence(PeekTok.getKind());
     466                 :     }
                        0: branch 0 not taken
                     6088: branch 1 taken
     467             6088:     assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
     468                 : 
     469                 :     // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
     470                 :     // either operand is unsigned.
     471             6088:     llvm::APSInt Res(LHS.getBitWidth());
                     3433: branch 0 taken
                     2655: branch 1 taken
     472             6088:     switch (Operator) {
     473                 :     case tok::question:       // No UAC for x and y in "x ? y : z".
     474                 :     case tok::lessless:       // Shift amount doesn't UAC with shift value.
     475                 :     case tok::greatergreater: // Shift amount doesn't UAC with shift value.
     476                 :     case tok::comma:          // Comma operands are not subject to UACs.
     477                 :     case tok::pipepipe:       // Logical || does not do UACs.
     478                 :     case tok::ampamp:         // Logical && does not do UACs.
     479             3433:       break;                  // No UAC
     480                 :     default:
     481             2655:       Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
     482                 :       // If this just promoted something from signed to unsigned, and if the
     483                 :       // value was negative, warn about it.
                     2216: branch 0 taken
                      439: branch 1 taken
                        5: branch 3 taken
                     2211: branch 4 taken
                        5: branch 5 taken
                     2650: branch 6 taken
     484             2655:       if (ValueLive && Res.isUnsigned()) {
                        1: branch 1 taken
                        4: branch 2 taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 6 taken
                        4: branch 7 taken
     485                5:         if (!LHS.isUnsigned() && LHS.Val.isNegative())
     486                 :           PP.Diag(OpLoc, diag::warn_pp_convert_lhs_to_positive)
     487                 :             << LHS.Val.toString(10, true) + " to " +
     488                 :                LHS.Val.toString(10, false)
     489                1:             << LHS.getRange() << RHS.getRange();
                        4: branch 1 taken
                        1: branch 2 taken
                        2: branch 4 taken
                        2: branch 5 taken
                        2: branch 6 taken
                        3: branch 7 taken
     490                5:         if (!RHS.isUnsigned() && RHS.Val.isNegative())
     491                 :           PP.Diag(OpLoc, diag::warn_pp_convert_rhs_to_positive)
     492                 :             << RHS.Val.toString(10, true) + " to " +
     493                 :                RHS.Val.toString(10, false)
     494                2:             << LHS.getRange() << RHS.getRange();
     495                 :       }
     496             2655:       LHS.Val.setIsUnsigned(Res.isUnsigned());
     497             2655:       RHS.Val.setIsUnsigned(Res.isUnsigned());
     498                 :     }
     499                 : 
     500                 :     // FIXME: All of these should detect and report overflow??
     501             6088:     bool Overflow = false;
                        0: branch 0 not taken
                        0: branch 1 not taken
                        8: branch 2 taken
                        2: branch 3 taken
                     1057: branch 4 taken
                        1: branch 5 taken
                     1059: branch 6 taken
                      157: branch 7 taken
                        0: branch 8 not taken
                       74: branch 9 taken
                      856: branch 10 taken
                       89: branch 11 taken
                       12: branch 12 taken
                      366: branch 13 taken
                       12: branch 14 taken
                       10: branch 15 taken
                       10: branch 16 taken
                     1286: branch 17 taken
                     1070: branch 18 taken
                        2: branch 19 taken
                       17: branch 20 taken
                        0: branch 21 not taken
     502             6088:     switch (Operator) {
     503                0:     default: assert(0 && "Unknown operator token!");
     504                 :     case tok::percent:
                        0: branch 1 not taken
                        0: branch 2 not taken
     505                0:       if (RHS.Val != 0)
     506                0:         Res = LHS.Val % RHS.Val;
                        0: branch 0 not taken
                        0: branch 1 not taken
     507                0:       else if (ValueLive) {
     508                 :         PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
     509                0:           << LHS.getRange() << RHS.getRange();
     510                0:         return true;
     511                 :       }
     512                0:       break;
     513                 :     case tok::slash:
                        1: branch 1 taken
                        7: branch 2 taken
     514                8:       if (RHS.Val != 0) {
     515                1:         Res = LHS.Val / RHS.Val;
                        0: branch 1 not taken
                        1: branch 2 taken
     516                1:         if (LHS.Val.isSigned())   // MININT/-1  -->  overflow.
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
     517                0:           Overflow = LHS.Val.isMinSignedValue() && RHS.Val.isAllOnesValue();
                        1: branch 0 taken
                        6: branch 1 taken
     518                7:       } else if (ValueLive) {
     519                 :         PP.Diag(OpLoc, diag::err_pp_division_by_zero)
     520                1:           << LHS.getRange() << RHS.getRange();
     521                1:         return true;
     522                 :       }
     523                7:       break;
     524                 : 
     525                 :     case tok::star:
     526                2:       Res = LHS.Val * RHS.Val;
                        1: branch 1 taken
                        1: branch 2 taken
                        1: branch 4 taken
                        0: branch 5 not taken
                        1: branch 7 taken
                        0: branch 8 not taken
                        1: branch 9 taken
                        1: branch 10 taken
     527                2:       if (Res.isSigned() && LHS.Val != 0 && RHS.Val != 0)
                        0: branch 2 not taken
                        1: branch 3 taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        1: branch 9 taken
                        1: branch 11 taken
                        0: branch 12 not taken
     528                1:         Overflow = Res/RHS.Val != LHS.Val || Res/LHS.Val != RHS.Val;
     529                2:       break;
     530                 :     case tok::lessless: {
     531                 :       // Determine whether overflow is about to happen.
     532             1057:       unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
                        0: branch 1 not taken
                     1057: branch 2 taken
     533             1057:       if (ShAmt >= LHS.Val.getBitWidth())
     534                0:         Overflow = true, ShAmt = LHS.Val.getBitWidth()-1;
                        0: branch 1 not taken
                     1057: branch 2 taken
     535             1057:       else if (LHS.isUnsigned())
     536                0:         Overflow = false;
                     1057: branch 1 taken
                        0: branch 2 not taken
     537             1057:       else if (LHS.Val.isNonNegative()) // Don't allow sign change.
     538             1057:         Overflow = ShAmt >= LHS.Val.countLeadingZeros();
     539                 :       else
     540                0:         Overflow = ShAmt >= LHS.Val.countLeadingOnes();
     541                 : 
     542             1057:       Res = LHS.Val << ShAmt;
     543             1057:       break;
     544                 :     }
     545                 :     case tok::greatergreater: {
     546                 :       // Determine whether overflow is about to happen.
     547                1:       unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
                        0: branch 1 not taken
                        1: branch 2 taken
     548                1:       if (ShAmt >= LHS.getBitWidth())
     549                0:         Overflow = true, ShAmt = LHS.getBitWidth()-1;
     550                1:       Res = LHS.Val >> ShAmt;
     551                1:       break;
     552                 :     }
     553                 :     case tok::plus:
     554             1059:       Res = LHS.Val + RHS.Val;
                        2: branch 1 taken
                     1057: branch 2 taken
     555             1059:       if (LHS.isUnsigned())
     556                2:         Overflow = false;
                     1057: branch 2 taken
                        0: branch 3 not taken
                        1: branch 6 taken
                     1056: branch 7 taken
                        1: branch 8 taken
                     1056: branch 9 taken
     557             1057:       else if (LHS.Val.isNonNegative() == RHS.Val.isNonNegative() &&
     558                 :                Res.isNonNegative() != LHS.Val.isNonNegative())
     559                1:         Overflow = true;  // Overflow for signed addition.
     560             1059:       break;
     561                 :     case tok::minus:
     562              157:       Res = LHS.Val - RHS.Val;
                        1: branch 1 taken
                      156: branch 2 taken
     563              157:       if (LHS.isUnsigned())
     564                1:         Overflow = false;
                        1: branch 2 taken
                      155: branch 3 taken
                        1: branch 6 taken
                        0: branch 7 not taken
                        1: branch 8 taken
                      155: branch 9 taken
     565              156:       else if (LHS.Val.isNonNegative() != RHS.Val.isNonNegative() &&
     566                 :                Res.isNonNegative() != LHS.Val.isNonNegative())
     567                1:         Overflow = true;  // Overflow for signed subtraction.
     568              157:       break;
     569                 :     case tok::lessequal:
     570                0:       Res = LHS.Val <= RHS.Val;
     571                0:       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
     572                0:       break;
     573                 :     case tok::less:
     574               74:       Res = LHS.Val < RHS.Val;
     575               74:       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
     576               74:       break;
     577                 :     case tok::greaterequal:
     578              856:       Res = LHS.Val >= RHS.Val;
     579              856:       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
     580              856:       break;
     581                 :     case tok::greater:
     582               89:       Res = LHS.Val > RHS.Val;
     583               89:       Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
     584               89:       break;
     585                 :     case tok::exclaimequal:
     586               12:       Res = LHS.Val != RHS.Val;
     587               12:       Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
     588               12:       break;
     589                 :     case tok::equalequal:
     590              366:       Res = LHS.Val == RHS.Val;
     591              366:       Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
     592              366:       break;
     593                 :     case tok::amp:
     594               12:       Res = LHS.Val & RHS.Val;
     595               12:       break;
     596                 :     case tok::caret:
     597               10:       Res = LHS.Val ^ RHS.Val;
     598               10:       break;
     599                 :     case tok::pipe:
     600               10:       Res = LHS.Val | RHS.Val;
     601               10:       break;
     602                 :     case tok::ampamp:
                      662: branch 1 taken
                      624: branch 2 taken
                      548: branch 4 taken
                      114: branch 5 taken
     603             1286:       Res = (LHS.Val != 0 && RHS.Val != 0);
     604             1286:       Res.setIsUnsigned(false);  // C99 6.5.13p3, result is always int (signed)
     605             1286:       break;
     606                 :     case tok::pipepipe:
                      485: branch 1 taken
                      585: branch 2 taken
                      132: branch 4 taken
                      353: branch 5 taken
     607             1070:       Res = (LHS.Val != 0 || RHS.Val != 0);
     608             1070:       Res.setIsUnsigned(false);  // C99 6.5.14p3, result is always int (signed)
     609             1070:       break;
     610                 :     case tok::comma:
     611                 :       // Comma is invalid in pp expressions in c89/c++ mode, but is valid in C99
     612                 :       // if not being evaluated.
                        1: branch 1 taken
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 4 taken
                        1: branch 5 taken
                        1: branch 6 taken
     613                2:       if (!PP.getLangOptions().C99 || ValueLive)
     614                 :         PP.Diag(OpLoc, diag::ext_pp_comma_expr)
     615                1:           << LHS.getRange() << RHS.getRange();
     616                2:       Res = RHS.Val; // LHS = LHS,RHS -> RHS.
     617                2:       break;
     618                 :     case tok::question: {
     619                 :       // Parse the : part of the expression.
                        0: branch 1 not taken
                       17: branch 2 taken
     620               17:       if (PeekTok.isNot(tok::colon)) {
     621                 :         PP.Diag(PeekTok.getLocation(), diag::err_expected_colon)
     622                0:           << LHS.getRange(), RHS.getRange();
     623                0:         PP.Diag(OpLoc, diag::note_matching) << "?";
     624                0:         return true;
     625                 :       }
     626                 :       // Consume the :.
     627               17:       PP.LexNonComment(PeekTok);
     628                 : 
     629                 :       // Evaluate the value after the :.
                       16: branch 0 taken
                        1: branch 1 taken
                        5: branch 3 taken
                       11: branch 4 taken
     630               17:       bool AfterColonLive = ValueLive && LHS.Val == 0;
     631               17:       PPValue AfterColonVal(LHS.getBitWidth());
     632                 :       DefinedTracker DT;
                        0: branch 1 not taken
                       17: branch 2 taken
     633               17:       if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
     634                0:         return true;
     635                 : 
     636                 :       // Parse anything after the : with the same precedence as ?.  We allow
     637                 :       // things of equal precedence because ?: is right associative.
                        1: branch 1 taken
                       16: branch 2 taken
     638               17:       if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
     639                 :                                    PeekTok, AfterColonLive, PP))
     640                1:         return true;
     641                 : 
     642                 :       // Now that we have the condition, the LHS and the RHS of the :, evaluate.
                       12: branch 1 taken
                        4: branch 2 taken
     643               16:       Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
     644               16:       RHS.setEnd(AfterColonVal.getRange().getEnd());
     645                 : 
     646                 :       // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
     647                 :       // either operand is unsigned.
     648               16:       Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
     649                 : 
     650                 :       // Figure out the precedence of the token after the : part.
     651               16:       PeekPrec = getPrecedence(PeekTok.getKind());
                        1: branch 1 taken
                       16: branch 2 taken
     652               17:       break;
     653                 :     }
     654                 :     case tok::colon:
     655                 :       // Don't allow :'s to float around without being part of ?: exprs.
     656                 :       PP.Diag(OpLoc, diag::err_pp_colon_without_question)
     657                0:         << LHS.getRange() << RHS.getRange();
     658                0:       return true;
     659                 :     }
     660                 : 
     661                 :     // If this operator is live and overflowed, report the issue.
                        3: branch 0 taken
                     6083: branch 1 taken
                        3: branch 2 taken
                        0: branch 3 not taken
     662             6086:     if (Overflow && ValueLive)
     663                 :       PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
     664                3:         << LHS.getRange() << RHS.getRange();
     665                 : 
     666                 :     // Put the result back into 'LHS' for our next iteration.
     667             6086:     LHS.Val = Res;
     668             6086:     LHS.setEnd(RHS.getRange().getEnd());
     669                 :   }
     670                 : 
     671                 :   return false;
     672                 : }
     673                 : 
     674                 : /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
     675                 : /// may occur after a #if or #elif directive.  If the expression is equivalent
     676                 : /// to "!defined(X)" return X in IfNDefMacro.
     677                 : bool Preprocessor::
     678             2351: EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
     679                 :   // Save the current state of 'DisableMacroExpansion' and reset it to false. If
     680                 :   // 'DisableMacroExpansion' is true, then we must be in a macro argument list
     681                 :   // in which case a directive is undefined behavior.  We want macros to be able
     682                 :   // to recursively expand in order to get more gcc-list behavior, so we force
     683                 :   // DisableMacroExpansion to false and restore it when we're done parsing the
     684                 :   // expression.
     685             2351:   bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
     686             2351:   DisableMacroExpansion = false;
     687                 :   
     688                 :   // Peek ahead one token.
     689             2351:   Token Tok;
     690             2351:   Lex(Tok);
     691                 : 
     692                 :   // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
     693             2351:   unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
     694                 : 
     695             2351:   PPValue ResVal(BitWidth);
     696                 :   DefinedTracker DT;
                        1: branch 1 taken
                     2350: branch 2 taken
     697             2351:   if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
     698                 :     // Parse error, skip the rest of the macro line.
                        0: branch 1 not taken
                        1: branch 2 taken
     699                1:     if (Tok.isNot(tok::eom))
     700                0:       DiscardUntilEndOfDirective();
     701                 :     
     702                 :     // Restore 'DisableMacroExpansion'.
     703                1:     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
     704                1:     return false;
     705                 :   }
     706                 : 
     707                 :   // If we are at the end of the expression after just parsing a value, there
     708                 :   // must be no (unparenthesized) binary operators involved, so we can exit
     709                 :   // directly.
                      740: branch 1 taken
                     1610: branch 2 taken
     710             2350:   if (Tok.is(tok::eom)) {
     711                 :     // If the expression we parsed was of the form !defined(macro), return the
     712                 :     // macro in IfNDefMacro.
                        7: branch 0 taken
                      733: branch 1 taken
     713              740:     if (DT.State == DefinedTracker::NotDefinedMacro)
     714                7:       IfNDefMacro = DT.TheMacro;
     715                 : 
     716                 :     // Restore 'DisableMacroExpansion'.
     717              740:     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
     718              740:     return ResVal.Val != 0;
     719                 :   }
     720                 : 
     721                 :   // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
     722                 :   // operator and the stuff after it.
                        7: branch 2 taken
                     1603: branch 3 taken
     723             1610:   if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
     724                 :                                Tok, true, *this)) {
     725                 :     // Parse error, skip the rest of the macro line.
                        6: branch 1 taken
                        1: branch 2 taken
     726                7:     if (Tok.isNot(tok::eom))
     727                6:       DiscardUntilEndOfDirective();
     728                 :     
     729                 :     // Restore 'DisableMacroExpansion'.
     730                7:     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
     731                7:     return false;
     732                 :   }
     733                 : 
     734                 :   // If we aren't at the tok::eom token, something bad happened, like an extra
     735                 :   // ')' token.
                        3: branch 1 taken
                     1600: branch 2 taken
     736             1603:   if (Tok.isNot(tok::eom)) {
     737                3:     Diag(Tok, diag::err_pp_expected_eol);
     738                3:     DiscardUntilEndOfDirective();
     739                 :   }
     740                 : 
     741                 :   // Restore 'DisableMacroExpansion'.
     742             1603:   DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
     743             1603:   return ResVal.Val != 0;
     744                 : }
     745                 : 

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