zcov: / lib/Parse/ParseExpr.cpp


Files: 1 Branches Taken: 85.1% 370 / 435
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 435 / 435
Line Coverage: 90.2% 505 / 560


Programs: 2 Runs 3018


       1                 : //===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
       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 Expression parsing implementation.  Expressions in
      11                 : // C99 basically consist of a bunch of binary operators with unary operators and
      12                 : // other random stuff at the leaves.
      13                 : //
      14                 : // In the C99 grammar, these unary operators bind tightest and are represented
      15                 : // as the 'cast-expression' production.  Everything else is either a binary
      16                 : // operator (e.g. '/') or a ternary operator ("?:").  The unary leaves are
      17                 : // handled by ParseCastExpression, the higher level pieces are handled by
      18                 : // ParseBinaryExpression.
      19                 : //
      20                 : //===----------------------------------------------------------------------===//
      21                 : 
      22                 : #include "clang/Parse/Parser.h"
      23                 : #include "clang/Parse/DeclSpec.h"
      24                 : #include "clang/Parse/Scope.h"
      25                 : #include "clang/Parse/Template.h"
      26                 : #include "clang/Basic/PrettyStackTrace.h"
      27                 : #include "RAIIObjectsForParser.h"
      28                 : #include "llvm/ADT/SmallVector.h"
      29                 : #include "llvm/ADT/SmallString.h"
      30                 : using namespace clang;
      31                 : 
      32                 : /// PrecedenceLevels - These are precedences for the binary/ternary operators in
      33                 : /// the C99 grammar.  These have been named to relate with the C99 grammar
      34                 : /// productions.  Low precedences numbers bind more weakly than high numbers.
      35                 : namespace prec {
      36                 :   enum Level {
      37                 :     Unknown         = 0,    // Not binary operator.
      38                 :     Comma           = 1,    // ,
      39                 :     Assignment      = 2,    // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
      40                 :     Conditional     = 3,    // ?
      41                 :     LogicalOr       = 4,    // ||
      42                 :     LogicalAnd      = 5,    // &&
      43                 :     InclusiveOr     = 6,    // |
      44                 :     ExclusiveOr     = 7,    // ^
      45                 :     And             = 8,    // &
      46                 :     Equality        = 9,    // ==, !=
      47                 :     Relational      = 10,   //  >=, <=, >, <
      48                 :     Shift           = 11,   // <<, >>
      49                 :     Additive        = 12,   // -, +
      50                 :     Multiplicative  = 13,   // *, /, %
      51                 :     PointerToMember = 14    // .*, ->*
      52                 :   };
      53                 : }
      54                 : 
      55                 : 
      56                 : /// getBinOpPrecedence - Return the precedence of the specified binary operator
      57                 : /// token.  This returns:
      58                 : ///
      59                 : static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
      60                 :                                       bool GreaterThanIsOperator,
      61            78675:                                       bool CPlusPlus0x) {
                      610: branch 0 taken
                       23: branch 1 taken
                    60213: branch 2 taken
                     7778: branch 3 taken
                     3852: branch 4 taken
                     1054: branch 5 taken
                       47: branch 6 taken
                       70: branch 7 taken
                      200: branch 8 taken
                       37: branch 9 taken
                      247: branch 10 taken
                     1498: branch 11 taken
                      439: branch 12 taken
                      320: branch 13 taken
                     1642: branch 14 taken
                      565: branch 15 taken
                       80: branch 16 taken
      62            78675:   switch (Kind) {
      63                 :   case tok::greater:
      64                 :     // C++ [temp.names]p3:
      65                 :     //   [...] When parsing a template-argument-list, the first
      66                 :     //   non-nested > is taken as the ending delimiter rather than a
      67                 :     //   greater-than operator. [...]
                      159: branch 0 taken
                      451: branch 1 taken
      68              610:     if (GreaterThanIsOperator)
      69              159:       return prec::Relational;
      70              451:     return prec::Unknown;
      71                 : 
      72                 :   case tok::greatergreater:
      73                 :     // C++0x [temp.names]p3:
      74                 :     //
      75                 :     //   [...] Similarly, the first non-nested >> is treated as two
      76                 :     //   consecutive but distinct > tokens, the first of which is
      77                 :     //   taken as the end of the template-argument-list and completes
      78                 :     //   the template-id. [...]
                        4: branch 0 taken
                       19: branch 1 taken
                        3: branch 2 taken
                        1: branch 3 taken
      79               23:     if (GreaterThanIsOperator || !CPlusPlus0x)
      80               22:       return prec::Shift;
      81                1:     return prec::Unknown;
      82                 : 
      83            60213:   default:                        return prec::Unknown;
      84             7778:   case tok::comma:                return prec::Comma;
      85                 :   case tok::equal:
      86                 :   case tok::starequal:
      87                 :   case tok::slashequal:
      88                 :   case tok::percentequal:
      89                 :   case tok::plusequal:
      90                 :   case tok::minusequal:
      91                 :   case tok::lesslessequal:
      92                 :   case tok::greatergreaterequal:
      93                 :   case tok::ampequal:
      94                 :   case tok::caretequal:
      95             3852:   case tok::pipeequal:            return prec::Assignment;
      96             1054:   case tok::question:             return prec::Conditional;
      97               47:   case tok::pipepipe:             return prec::LogicalOr;
      98               70:   case tok::ampamp:               return prec::LogicalAnd;
      99              200:   case tok::pipe:                 return prec::InclusiveOr;
     100               37:   case tok::caret:                return prec::ExclusiveOr;
     101              247:   case tok::amp:                  return prec::And;
     102                 :   case tok::exclaimequal:
     103             1498:   case tok::equalequal:           return prec::Equality;
     104                 :   case tok::lessequal:
     105                 :   case tok::less:
     106              439:   case tok::greaterequal:         return prec::Relational;
     107              320:   case tok::lessless:             return prec::Shift;
     108                 :   case tok::plus:
     109             1642:   case tok::minus:                return prec::Additive;
     110                 :   case tok::percent:
     111                 :   case tok::slash:
     112              565:   case tok::star:                 return prec::Multiplicative;
     113                 :   case tok::periodstar:
     114               80:   case tok::arrowstar:            return prec::PointerToMember;
     115                 :   }
     116                 : }
     117                 : 
     118                 : 
     119                 : /// ParseExpression - Simple precedence-based parser for binary/ternary
     120                 : /// operators.
     121                 : ///
     122                 : /// Note: we diverge from the C99 grammar when parsing the assignment-expression
     123                 : /// production.  C99 specifies that the LHS of an assignment operator should be
     124                 : /// parsed as a unary-expression, but consistency dictates that it be a
     125                 : /// conditional-expession.  In practice, the important thing here is that the
     126                 : /// LHS of an assignment has to be an l-value, which productions between
     127                 : /// unary-expression and conditional-expression don't produce.  Because we want
     128                 : /// consistency, we parse the LHS as a conditional-expression, then check for
     129                 : /// l-value-ness in semantic analysis stages.
     130                 : ///
     131                 : ///       pm-expression: [C++ 5.5]
     132                 : ///         cast-expression
     133                 : ///         pm-expression '.*' cast-expression
     134                 : ///         pm-expression '->*' cast-expression
     135                 : ///
     136                 : ///       multiplicative-expression: [C99 6.5.5]
     137                 : ///     Note: in C++, apply pm-expression instead of cast-expression
     138                 : ///         cast-expression
     139                 : ///         multiplicative-expression '*' cast-expression
     140                 : ///         multiplicative-expression '/' cast-expression
     141                 : ///         multiplicative-expression '%' cast-expression
     142                 : ///
     143                 : ///       additive-expression: [C99 6.5.6]
     144                 : ///         multiplicative-expression
     145                 : ///         additive-expression '+' multiplicative-expression
     146                 : ///         additive-expression '-' multiplicative-expression
     147                 : ///
     148                 : ///       shift-expression: [C99 6.5.7]
     149                 : ///         additive-expression
     150                 : ///         shift-expression '<<' additive-expression
     151                 : ///         shift-expression '>>' additive-expression
     152                 : ///
     153                 : ///       relational-expression: [C99 6.5.8]
     154                 : ///         shift-expression
     155                 : ///         relational-expression '<' shift-expression
     156                 : ///         relational-expression '>' shift-expression
     157                 : ///         relational-expression '<=' shift-expression
     158                 : ///         relational-expression '>=' shift-expression
     159                 : ///
     160                 : ///       equality-expression: [C99 6.5.9]
     161                 : ///         relational-expression
     162                 : ///         equality-expression '==' relational-expression
     163                 : ///         equality-expression '!=' relational-expression
     164                 : ///
     165                 : ///       AND-expression: [C99 6.5.10]
     166                 : ///         equality-expression
     167                 : ///         AND-expression '&' equality-expression
     168                 : ///
     169                 : ///       exclusive-OR-expression: [C99 6.5.11]
     170                 : ///         AND-expression
     171                 : ///         exclusive-OR-expression '^' AND-expression
     172                 : ///
     173                 : ///       inclusive-OR-expression: [C99 6.5.12]
     174                 : ///         exclusive-OR-expression
     175                 : ///         inclusive-OR-expression '|' exclusive-OR-expression
     176                 : ///
     177                 : ///       logical-AND-expression: [C99 6.5.13]
     178                 : ///         inclusive-OR-expression
     179                 : ///         logical-AND-expression '&&' inclusive-OR-expression
     180                 : ///
     181                 : ///       logical-OR-expression: [C99 6.5.14]
     182                 : ///         logical-AND-expression
     183                 : ///         logical-OR-expression '||' logical-AND-expression
     184                 : ///
     185                 : ///       conditional-expression: [C99 6.5.15]
     186                 : ///         logical-OR-expression
     187                 : ///         logical-OR-expression '?' expression ':' conditional-expression
     188                 : /// [GNU]   logical-OR-expression '?' ':' conditional-expression
     189                 : /// [C++] the third operand is an assignment-expression
     190                 : ///
     191                 : ///       assignment-expression: [C99 6.5.16]
     192                 : ///         conditional-expression
     193                 : ///         unary-expression assignment-operator assignment-expression
     194                 : /// [C++]   throw-expression [C++ 15]
     195                 : ///
     196                 : ///       assignment-operator: one of
     197                 : ///         = *= /= %= += -= <<= >>= &= ^= |=
     198                 : ///
     199                 : ///       expression: [C99 6.5.17]
     200                 : ///         assignment-expression
     201                 : ///         expression ',' assignment-expression
     202                 : ///
     203            22537: Parser::OwningExprResult Parser::ParseExpression() {
     204            22537:   OwningExprResult LHS(ParseAssignmentExpression());
                      750: branch 1 taken
                    21787: branch 2 taken
     205            22537:   if (LHS.isInvalid()) return move(LHS);
     206                 : 
     207            21787:   return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
     208                 : }
     209                 : 
     210                 : /// This routine is called when the '@' is seen and consumed.
     211                 : /// Current token is an Identifier and is not a 'try'. This
     212                 : /// routine is necessary to disambiguate @try-statement from,
     213                 : /// for example, @encode-expression.
     214                 : ///
     215                 : Parser::OwningExprResult
     216                4: Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
     217                4:   OwningExprResult LHS(ParseObjCAtExpression(AtLoc));
                        0: branch 1 not taken
                        4: branch 2 taken
     218                4:   if (LHS.isInvalid()) return move(LHS);
     219                 : 
     220                4:   return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
     221                 : }
     222                 : 
     223                 : /// This routine is called when a leading '__extension__' is seen and
     224                 : /// consumed.  This is necessary because the token gets consumed in the
     225                 : /// process of disambiguating between an expression and a declaration.
     226                 : Parser::OwningExprResult
     227                6: Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
     228                6:   OwningExprResult LHS(Actions, true);
     229                 :   {
     230                 :     // Silence extension warnings in the sub-expression
     231                6:     ExtensionRAIIObject O(Diags);
     232                 : 
     233                6:     LHS = ParseCastExpression(false);
                        2: branch 1 taken
                        4: branch 2 taken
                        4: branch 8 taken
                        2: branch 9 taken
     234                6:     if (LHS.isInvalid()) return move(LHS);
     235                 :   }
     236                 : 
     237                 :   LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__,
     238                4:                              move(LHS));
                        0: branch 1 not taken
                        4: branch 2 taken
     239                4:   if (LHS.isInvalid()) return move(LHS);
     240                 : 
     241                4:   return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
     242                 : }
     243                 : 
     244                 : /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
     245                 : ///
     246            44284: Parser::OwningExprResult Parser::ParseAssignmentExpression() {
                        2: branch 1 taken
                    44282: branch 2 taken
     247            44284:   if (Tok.is(tok::code_completion)) {
     248                2:     Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Expression);
     249                2:     ConsumeToken();
     250                 :   }
     251                 : 
                       40: branch 1 taken
                    44244: branch 2 taken
     252            44284:   if (Tok.is(tok::kw_throw))
     253               40:     return ParseThrowExpression();
     254                 : 
     255            44244:   OwningExprResult LHS(ParseCastExpression(false));
                      720: branch 1 taken
                    43524: branch 2 taken
     256            44244:   if (LHS.isInvalid()) return move(LHS);
     257                 : 
     258            43524:   return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
     259                 : }
     260                 : 
     261                 : /// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
     262                 : /// where part of an objc message send has already been parsed.  In this case
     263                 : /// LBracLoc indicates the location of the '[' of the message send, and either
     264                 : /// ReceiverName or ReceiverExpr is non-null indicating the receiver of the
     265                 : /// message.
     266                 : ///
     267                 : /// Since this handles full assignment-expression's, it handles postfix
     268                 : /// expressions and other binary operators for these expressions as well.
     269                 : Parser::OwningExprResult
     270                 : Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
     271                 :                                                     SourceLocation NameLoc,
     272                 :                                                    IdentifierInfo *ReceiverName,
     273               26:                                                     ExprArg ReceiverExpr) {
     274                 :   OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
     275                 :                                                     ReceiverName,
     276               26:                                                     move(ReceiverExpr)));
                        0: branch 1 not taken
                       26: branch 2 taken
     277               26:   if (R.isInvalid()) return move(R);
     278               26:   R = ParsePostfixExpressionSuffix(move(R));
                        0: branch 1 not taken
                       26: branch 2 taken
     279               26:   if (R.isInvalid()) return move(R);
     280               26:   return ParseRHSOfBinaryExpression(move(R), prec::Assignment);
     281                 : }
     282                 : 
     283                 : 
     284             2620: Parser::OwningExprResult Parser::ParseConstantExpression() {
     285                 :   // C++ [basic.def.odr]p2:
     286                 :   //   An expression is potentially evaluated unless it appears where an
     287                 :   //   integral constant expression is required (see 5.19) [...].
     288                 :   EnterExpressionEvaluationContext Unevaluated(Actions,
     289             2620:                                                Action::Unevaluated);
     290                 : 
     291             2620:   OwningExprResult LHS(ParseCastExpression(false));
                       12: branch 1 taken
                     2608: branch 2 taken
     292             2620:   if (LHS.isInvalid()) return move(LHS);
     293                 : 
     294             2608:   return ParseRHSOfBinaryExpression(move(LHS), prec::Conditional);
     295                 : }
     296                 : 
     297                 : /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
     298                 : /// LHS and has a precedence of at least MinPrec.
     299                 : Parser::OwningExprResult
     300            68338: Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
     301                 :   unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind(),
     302                 :                                             GreaterThanIsOperator,
     303            68338:                                             getLang().CPlusPlus0x);
     304            68338:   SourceLocation ColonLoc;
     305                 : 
                     9952: branch 1 taken
                       37: branch 2 taken
                     9952: branch 4 taken
                       37: branch 5 taken
     306             9989:   while (1) {
     307                 :     // If this token has a lower precedence than we are allowed to parse (e.g.
     308                 :     // because we are called recursively, or because the token is not a binop),
     309                 :     // then we are done!
                    68301: branch 0 taken
                     9989: branch 1 taken
     310            78290:     if (NextTokPrec < MinPrec)
     311            68301:       return move(LHS);
     312                 : 
     313                 :     // Consume the operator, saving the operator token for error reporting.
     314             9989:     Token OpToken = Tok;
     315             9989:     ConsumeToken();
     316                 : 
     317                 :     // Special case handling for the ternary operator.
     318             9989:     OwningExprResult TernaryMiddle(Actions, true);
                     1011: branch 0 taken
                     8978: branch 1 taken
     319             9989:     if (NextTokPrec == prec::Conditional) {
                      985: branch 1 taken
                       26: branch 2 taken
     320             1011:       if (Tok.isNot(tok::colon)) {
     321                 :         // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
     322              985:         ColonProtectionRAIIObject X(*this);
     323                 : 
     324                 :         // Handle this production specially:
     325                 :         //   logical-OR-expression '?' expression ':' conditional-expression
     326                 :         // In particular, the RHS of the '?' is 'expression', not
     327                 :         // 'logical-OR-expression' as we might expect.
     328              985:         TernaryMiddle = ParseExpression();
                        0: branch 1 not taken
                      985: branch 2 taken
     329              985:         if (TernaryMiddle.isInvalid())
                      985: branch 5 taken
                        0: branch 6 not taken
     330                0:           return move(TernaryMiddle);
     331                 :       } else {
     332                 :         // Special case handling of "X ? Y : Z" where Y is empty:
     333                 :         //   logical-OR-expression '?' ':' conditional-expression   [GNU]
     334               26:         TernaryMiddle = 0;
     335               26:         Diag(Tok, diag::ext_gnu_conditional_expr);
     336                 :       }
     337                 : 
                        0: branch 1 not taken
                     1011: branch 2 taken
     338             1011:       if (Tok.isNot(tok::colon)) {
     339                0:         Diag(Tok, diag::err_expected_colon);
     340                0:         Diag(OpToken, diag::note_matching) << "?";
     341                0:         return ExprError();
     342                 :       }
     343                 : 
     344                 :       // Eat the colon.
     345             1011:       ColonLoc = ConsumeToken();
     346                 :     }
     347                 :     
     348                 :     // Parse another leaf here for the RHS of the operator.
     349                 :     // ParseCastExpression works here because all RHS expressions in C have it
     350                 :     // as a prefix, at least. However, in C++, an assignment-expression could
     351                 :     // be a throw-expression, which is not a valid cast-expression.
     352                 :     // Therefore we need some special-casing here.
     353                 :     // Also note that the third operand of the conditional operator is
     354                 :     // an assignment-expression in C++.
     355             9989:     OwningExprResult RHS(Actions);
                     2347: branch 1 taken
                     7642: branch 2 taken
                     1091: branch 3 taken
                     1256: branch 4 taken
                     1091: branch 5 taken
                     8898: branch 6 taken
     356             9989:     if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional)
     357             1091:       RHS = ParseAssignmentExpression();
     358                 :     else
     359             8898:       RHS = ParseCastExpression(false);
                       30: branch 1 taken
                     9959: branch 2 taken
     360             9989:     if (RHS.isInvalid())
     361               30:       return move(RHS);
     362                 : 
     363                 :     // Remember the precedence of this operator and get the precedence of the
     364                 :     // operator immediately to the right of the RHS.
     365             9959:     unsigned ThisPrec = NextTokPrec;
     366                 :     NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
     367             9959:                                      getLang().CPlusPlus0x);
     368                 : 
     369                 :     // Assignment and conditional expressions are right-associative.
     370                 :     bool isRightAssoc = ThisPrec == prec::Conditional ||
                     8948: branch 0 taken
                     1011: branch 1 taken
                     3808: branch 2 taken
                     5140: branch 3 taken
     371             9959:                         ThisPrec == prec::Assignment;
     372                 : 
     373                 :     // Get the precedence of the operator to the right of the RHS.  If it binds
     374                 :     // more tightly with RHS than we do, evaluate it completely first.
                     9591: branch 0 taken
                      368: branch 1 taken
                      529: branch 2 taken
                     9062: branch 3 taken
                       17: branch 4 taken
                      512: branch 5 taken
     375             9959:     if (ThisPrec < NextTokPrec ||
     376                 :         (ThisPrec == NextTokPrec && isRightAssoc)) {
     377                 :       // If this is left-associative, only parse things on the RHS that bind
     378                 :       // more tightly than the current operator.  If it is left-associative, it
     379                 :       // is okay, to bind exactly as tightly.  For example, compile A=B=C=D as
     380                 :       // A=(B=(C=D)), where each paren is a level of recursion here.
     381                 :       // The function takes ownership of the RHS.
     382              385:       RHS = ParseRHSOfBinaryExpression(move(RHS), ThisPrec + !isRightAssoc);
                        7: branch 1 taken
                      378: branch 2 taken
     383              385:       if (RHS.isInvalid())
     384                7:         return move(RHS);
     385                 : 
     386                 :       NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
     387              378:                                        getLang().CPlusPlus0x);
     388                 :     }
                        0: branch 0 not taken
                     9952: branch 1 taken
     389             9952:     assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
     390                 : 
                     9949: branch 1 taken
                        3: branch 2 taken
     391             9952:     if (!LHS.isInvalid()) {
     392                 :       // Combine the LHS and RHS into the LHS (e.g. build AST).
                     8939: branch 1 taken
                     1010: branch 2 taken
     393             9949:       if (TernaryMiddle.isInvalid()) {
     394                 :         // If we're using '>>' as an operator within a template
     395                 :         // argument list (in C++98), suggest the addition of
     396                 :         // parentheses so that the code remains well-formed in C++0x.
                       24: branch 0 taken
                     8915: branch 1 taken
                        3: branch 3 taken
                       21: branch 4 taken
                        3: branch 5 taken
                     8936: branch 6 taken
     397             8939:         if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater))
     398                 :           SuggestParentheses(OpToken.getLocation(),
     399                 :                              diag::warn_cxx0x_right_shift_in_template_arg,
     400                 :                          SourceRange(Actions.getExprRange(LHS.get()).getBegin(),
     401                3:                                      Actions.getExprRange(RHS.get()).getEnd()));
     402                 : 
     403                 :         LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
     404             8939:                                  OpToken.getKind(), move(LHS), move(RHS));
     405                 :       } else
     406                 :         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
     407                 :                                          move(LHS), move(TernaryMiddle),
     408             1010:                                          move(RHS));
     409                 :     }
     410                 :   }
     411                 : }
     412                 : 
     413                 : /// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
     414                 : /// true, parse a unary-expression. isAddressOfOperand exists because an
     415                 : /// id-expression that is the operand of address-of gets special treatment
     416                 : /// due to member pointers.
     417                 : ///
     418                 : Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
     419                 :                                                      bool isAddressOfOperand,
     420            65481:                                                      TypeTy *TypeOfCast) {
     421                 :   bool NotCastExpr;
     422                 :   OwningExprResult Res = ParseCastExpression(isUnaryExpression,
     423                 :                                              isAddressOfOperand,
     424                 :                                              NotCastExpr,
     425            65481:                                              TypeOfCast);
                       26: branch 0 taken
                    65455: branch 1 taken
     426            65481:   if (NotCastExpr)
     427               26:     Diag(Tok, diag::err_expected_expression);
     428            65481:   return move(Res);
     429                 : }
     430                 : 
     431                 : /// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
     432                 : /// true, parse a unary-expression. isAddressOfOperand exists because an
     433                 : /// id-expression that is the operand of address-of gets special treatment
     434                 : /// due to member pointers. NotCastExpr is set to true if the token is not the
     435                 : /// start of a cast-expression, and no diagnostic is emitted in this case.
     436                 : ///
     437                 : ///       cast-expression: [C99 6.5.4]
     438                 : ///         unary-expression
     439                 : ///         '(' type-name ')' cast-expression
     440                 : ///
     441                 : ///       unary-expression:  [C99 6.5.3]
     442                 : ///         postfix-expression
     443                 : ///         '++' unary-expression
     444                 : ///         '--' unary-expression
     445                 : ///         unary-operator cast-expression
     446                 : ///         'sizeof' unary-expression
     447                 : ///         'sizeof' '(' type-name ')'
     448                 : /// [GNU]   '__alignof' unary-expression
     449                 : /// [GNU]   '__alignof' '(' type-name ')'
     450                 : /// [C++0x] 'alignof' '(' type-id ')'
     451                 : /// [GNU]   '&&' identifier
     452                 : /// [C++]   new-expression
     453                 : /// [C++]   delete-expression
     454                 : ///
     455                 : ///       unary-operator: one of
     456                 : ///         '&'  '*'  '+'  '-'  '~'  '!'
     457                 : /// [GNU]   '__extension__'  '__real'  '__imag'
     458                 : ///
     459                 : ///       primary-expression: [C99 6.5.1]
     460                 : /// [C99]   identifier
     461                 : /// [C++]   id-expression
     462                 : ///         constant
     463                 : ///         string-literal
     464                 : /// [C++]   boolean-literal  [C++ 2.13.5]
     465                 : /// [C++0x] 'nullptr'        [C++0x 2.14.7]
     466                 : ///         '(' expression ')'
     467                 : ///         '__func__'        [C99 6.4.2.2]
     468                 : /// [GNU]   '__FUNCTION__'
     469                 : /// [GNU]   '__PRETTY_FUNCTION__'
     470                 : /// [GNU]   '(' compound-statement ')'
     471                 : /// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
     472                 : /// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
     473                 : /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
     474                 : ///                                     assign-expr ')'
     475                 : /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
     476                 : /// [GNU]   '__null'
     477                 : /// [OBJC]  '[' objc-message-expr ']'
     478                 : /// [OBJC]  '@selector' '(' objc-selector-arg ')'
     479                 : /// [OBJC]  '@protocol' '(' identifier ')'
     480                 : /// [OBJC]  '@encode' '(' type-name ')'
     481                 : /// [OBJC]  objc-string-literal
     482                 : /// [C++]   simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
     483                 : /// [C++]   typename-specifier '(' expression-list[opt] ')'         [TODO]
     484                 : /// [C++]   'const_cast' '<' type-name '>' '(' expression ')'       [C++ 5.2p1]
     485                 : /// [C++]   'dynamic_cast' '<' type-name '>' '(' expression ')'     [C++ 5.2p1]
     486                 : /// [C++]   'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
     487                 : /// [C++]   'static_cast' '<' type-name '>' '(' expression ')'      [C++ 5.2p1]
     488                 : /// [C++]   'typeid' '(' expression ')'                             [C++ 5.2p1]
     489                 : /// [C++]   'typeid' '(' type-id ')'                                [C++ 5.2p1]
     490                 : /// [C++]   'this'          [C++ 9.3.2]
     491                 : /// [G++]   unary-type-trait '(' type-id ')'
     492                 : /// [G++]   binary-type-trait '(' type-id ',' type-id ')'           [TODO]
     493                 : /// [clang] '^' block-literal
     494                 : ///
     495                 : ///       constant: [C99 6.4.4]
     496                 : ///         integer-constant
     497                 : ///         floating-constant
     498                 : ///         enumeration-constant -> identifier
     499                 : ///         character-constant
     500                 : ///
     501                 : ///       id-expression: [C++ 5.1]
     502                 : ///                   unqualified-id
     503                 : ///                   qualified-id           [TODO]
     504                 : ///
     505                 : ///       unqualified-id: [C++ 5.1]
     506                 : ///                   identifier
     507                 : ///                   operator-function-id
     508                 : ///                   conversion-function-id [TODO]
     509                 : ///                   '~' class-name         [TODO]
     510                 : ///                   template-id            [TODO]
     511                 : ///
     512                 : ///       new-expression: [C++ 5.3.4]
     513                 : ///                   '::'[opt] 'new' new-placement[opt] new-type-id
     514                 : ///                                     new-initializer[opt]
     515                 : ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
     516                 : ///                                     new-initializer[opt]
     517                 : ///
     518                 : ///       delete-expression: [C++ 5.3.5]
     519                 : ///                   '::'[opt] 'delete' cast-expression
     520                 : ///                   '::'[opt] 'delete' '[' ']' cast-expression
     521                 : ///
     522                 : /// [GNU] unary-type-trait:
     523                 : ///                   '__has_nothrow_assign'                  [TODO]
     524                 : ///                   '__has_nothrow_copy'                    [TODO]
     525                 : ///                   '__has_nothrow_constructor'             [TODO]
     526                 : ///                   '__has_trivial_assign'                  [TODO]
     527                 : ///                   '__has_trivial_copy'                    [TODO]
     528                 : ///                   '__has_trivial_constructor'
     529                 : ///                   '__has_trivial_destructor'
     530                 : ///                   '__has_virtual_destructor'              [TODO]
     531                 : ///                   '__is_abstract'                         [TODO]
     532                 : ///                   '__is_class'
     533                 : ///                   '__is_empty'                            [TODO]
     534                 : ///                   '__is_enum'
     535                 : ///                   '__is_pod'
     536                 : ///                   '__is_polymorphic'
     537                 : ///                   '__is_union'
     538                 : ///
     539                 : /// [GNU] binary-type-trait:
     540                 : ///                   '__is_base_of'                          [TODO]
     541                 : ///
     542                 : Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
     543                 :                                                      bool isAddressOfOperand,
     544                 :                                                      bool &NotCastExpr,
     545            65517:                                                      TypeTy *TypeOfCast) {
     546            65517:   OwningExprResult Res(Actions);
     547            65517:   tok::TokenKind SavedKind = Tok.getKind();
     548            65517:   NotCastExpr = false;
     549                 : 
     550                 :   // This handles all of cast-expression, unary-expression, postfix-expression,
     551                 :   // and primary-expression.  We handle them together like this for efficiency
     552                 :   // and to simplify handling of an expression starting with a '(' token: which
     553                 :   // may be one of a parenthesized expression, cast-expression, compound literal
     554                 :   // expression, or statement expression.
     555                 :   //
     556                 :   // If the parsed tokens consist of a primary-expression, the cases below
     557                 :   // call ParsePostfixExpressionSuffix to handle the postfix expression
     558                 :   // suffixes.  Cases that cannot be followed by postfix exprs should
     559                 :   // return without invoking ParsePostfixExpressionSuffix.
                     8637: branch 0 taken
                    16337: branch 1 taken
                      141: branch 2 taken
                       36: branch 3 taken
                    29546: branch 4 taken
                      192: branch 5 taken
                      242: branch 6 taken
                     1211: branch 7 taken
                      234: branch 8 taken
                       18: branch 9 taken
                      487: branch 10 taken
                     1223: branch 11 taken
                     2275: branch 12 taken
                       37: branch 13 taken
                      623: branch 14 taken
                       39: branch 15 taken
                      252: branch 16 taken
                       83: branch 17 taken
                       80: branch 18 taken
                      518: branch 19 taken
                      532: branch 20 taken
                      120: branch 21 taken
                       11: branch 22 taken
                       10: branch 23 taken
                      113: branch 24 taken
                       48: branch 25 taken
                      180: branch 26 taken
                      318: branch 27 taken
                      264: branch 28 taken
                     1677: branch 29 taken
                       33: branch 30 taken
     560            65517:   switch (SavedKind) {
     561                 :   case tok::l_paren: {
     562                 :     // If this expression is limited to being a unary-expression, the parent can
     563                 :     // not start a cast expression.
     564                 :     ParenParseOption ParenExprType =
                        3: branch 0 taken
                     8634: branch 1 taken
     565             8637:       isUnaryExpression ? CompoundLiteral : CastExpr;
     566                 :     TypeTy *CastTy;
     567             8637:     SourceLocation LParenLoc = Tok.getLocation();
     568             8637:     SourceLocation RParenLoc;
     569                 :     
     570                 :     {
     571                 :       // The inside of the parens don't need to be a colon protected scope.
     572             8637:       ColonProtectionRAIIObject X(*this, false);
     573                 :     
     574                 :       Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
     575             8637:                                  TypeOfCast, CastTy, RParenLoc);
                      240: branch 1 taken
                     8397: branch 2 taken
                     8397: branch 8 taken
                      240: branch 9 taken
     576             8637:       if (Res.isInvalid()) return move(Res);
     577                 :     }
     578                 : 
                     3394: branch 0 taken
                       64: branch 1 taken
                      285: branch 2 taken
                     4654: branch 3 taken
                        0: branch 4 not taken
     579             8397:     switch (ParenExprType) {
     580             3394:     case SimpleExpr:   break;    // Nothing else to do.
     581               64:     case CompoundStmt: break;  // Nothing else to do.
     582                 :     case CompoundLiteral:
     583                 :       // We parsed '(' type-name ')' '{' ... '}'.  If any suffixes of
     584                 :       // postfix-expression exist, parse them now.
     585              285:       break;
     586                 :     case CastExpr:
     587                 :       // We have parsed the cast-expression and no postfix-expr pieces are
     588                 :       // following.
     589             4654:       return move(Res);
     590                 :     }
     591                 : 
     592                 :     // These can be followed by postfix-expr pieces.
     593             3743:     return ParsePostfixExpressionSuffix(move(Res));
     594                 :   }
     595                 : 
     596                 :     // primary-expression
     597                 :   case tok::numeric_constant:
     598                 :     // constant: integer-constant
     599                 :     // constant: floating-constant
     600                 : 
     601            16337:     Res = Actions.ActOnNumericConstant(Tok);
     602            16337:     ConsumeToken();
     603                 : 
     604                 :     // These can be followed by postfix-expr pieces.
     605            16337:     return ParsePostfixExpressionSuffix(move(Res));
     606                 : 
     607                 :   case tok::kw_true:
     608                 :   case tok::kw_false:
     609              141:     return ParseCXXBoolLiteral();
     610                 : 
     611                 :   case tok::kw_nullptr:
     612               36:     return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
     613                 : 
     614                 :   case tok::identifier: {      // primary-expression: identifier
     615                 :                                // unqualified-id: identifier
     616                 :                                // constant: enumeration-constant
     617                 :     // Turn a potentially qualified name into a annot_typename or
     618                 :     // annot_cxxscope if it would be valid.  This handles things like x::y, etc.
                     8510: branch 1 taken
                    21036: branch 2 taken
     619            29546:     if (getLang().CPlusPlus) {
     620                 :       // Avoid the unnecessary parse-time lookup in the common case
     621                 :       // where the syntax forbids a type.
     622             8510:       const Token &Next = NextToken();
                     8307: branch 1 taken
                      203: branch 2 taken
                     8077: branch 3 taken
                      230: branch 4 taken
                     8073: branch 6 taken
                        4: branch 7 taken
                     7930: branch 9 taken
                      373: branch 10 taken
                     1864: branch 12 taken
                     6066: branch 13 taken
                     2444: branch 14 taken
                     6066: branch 15 taken
     623             8510:       if (Next.is(tok::coloncolon) ||
     624                 :           (!ColonIsSacred && Next.is(tok::colon)) ||
     625                 :           Next.is(tok::less) ||
     626                 :           Next.is(tok::l_paren)) {
     627                 :         // If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
                      803: branch 1 taken
                     1641: branch 2 taken
     628             2444:         if (TryAnnotateTypeOrScopeToken())
     629              803:           return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
     630                 :       }
     631                 :     }
     632                 : 
     633                 :     // Consume the identifier so that we can see if it is followed by a '(' or
     634                 :     // '.'.
     635            28743:     IdentifierInfo &II = *Tok.getIdentifierInfo();
     636            28743:     SourceLocation ILoc = ConsumeToken();
     637                 :     
     638                 :     // Support 'Class.property' notation.  We don't use
     639                 :     // isTokObjCMessageIdentifierReceiver(), since it allows 'super' (which is
     640                 :     // inappropriate here).
                     8314: branch 1 taken
                    20429: branch 2 taken
                      399: branch 4 taken
                     7915: branch 5 taken
                       17: branch 7 taken
                      382: branch 8 taken
                       17: branch 9 taken
                    28726: branch 10 taken
     641            28743:     if (getLang().ObjC1 && Tok.is(tok::period) &&
     642                 :         Actions.getTypeName(II, ILoc, CurScope)) {
     643               17:       SourceLocation DotLoc = ConsumeToken();
     644                 :       
                        0: branch 1 not taken
                       17: branch 2 taken
     645               17:       if (Tok.isNot(tok::identifier)) {
     646                0:         Diag(Tok, diag::err_expected_property_name);
     647                0:         return ExprError();
     648                 :       }
     649               17:       IdentifierInfo &PropertyName = *Tok.getIdentifierInfo();
     650               17:       SourceLocation PropertyLoc = ConsumeToken();
     651                 :       
     652                 :       Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName,
     653               17:                                               ILoc, PropertyLoc);
     654                 :       // These can be followed by postfix-expr pieces.
     655               17:       return ParsePostfixExpressionSuffix(move(Res));
     656                 :     }
     657                 :    
     658                 :     // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
     659                 :     // need to know whether or not this identifier is a function designator or
     660                 :     // not.
     661            28726:     UnqualifiedId Name;
     662            28726:     CXXScopeSpec ScopeSpec;
     663            28726:     Name.setIdentifier(&II, ILoc);
     664                 :     Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name, 
     665            28726:                                     Tok.is(tok::l_paren), false);
     666                 :     // These can be followed by postfix-expr pieces.
     667            28726:     return ParsePostfixExpressionSuffix(move(Res));
     668                 :   }
     669                 :   case tok::char_constant:     // constant: character-constant
     670              192:     Res = Actions.ActOnCharacterConstant(Tok);
     671              192:     ConsumeToken();
     672                 :     // These can be followed by postfix-expr pieces.
     673              192:     return ParsePostfixExpressionSuffix(move(Res));
     674                 :   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
     675                 :   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
     676                 :   case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
     677              242:     Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
     678              242:     ConsumeToken();
     679                 :     // These can be followed by postfix-expr pieces.
     680              242:     return ParsePostfixExpressionSuffix(move(Res));
     681                 :   case tok::string_literal:    // primary-expression: string-literal
     682                 :   case tok::wide_string_literal:
     683             1211:     Res = ParseStringLiteralExpression();
                        4: branch 1 taken
                     1207: branch 2 taken
     684             1211:     if (Res.isInvalid()) return move(Res);
     685                 :     // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
     686             1207:     return ParsePostfixExpressionSuffix(move(Res));
     687                 :   case tok::kw___builtin_va_arg:
     688                 :   case tok::kw___builtin_offsetof:
     689                 :   case tok::kw___builtin_choose_expr:
     690                 :   case tok::kw___builtin_types_compatible_p:
     691              234:     return ParseBuiltinPrimaryExpression();
     692                 :   case tok::kw___null:
     693               18:     return Actions.ActOnGNUNullExpr(ConsumeToken());
     694                 :     break;
     695                 :   case tok::plusplus:      // unary-expression: '++' unary-expression
     696                 :   case tok::minusminus: {  // unary-expression: '--' unary-expression
     697              487:     SourceLocation SavedLoc = ConsumeToken();
     698              487:     Res = ParseCastExpression(true);
                      486: branch 1 taken
                        1: branch 2 taken
     699              487:     if (!Res.isInvalid())
     700              486:       Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
     701              487:     return move(Res);
     702                 :   }
     703                 :   case tok::amp: {         // unary-expression: '&' cast-expression
     704                 :     // Special treatment because of member pointers
     705             1223:     SourceLocation SavedLoc = ConsumeToken();
     706             1223:     Res = ParseCastExpression(false, true);
                     1217: branch 1 taken
                        6: branch 2 taken
     707             1223:     if (!Res.isInvalid())
     708             1217:       Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
     709             1223:     return move(Res);
     710                 :   }
     711                 : 
     712                 :   case tok::star:          // unary-expression: '*' cast-expression
     713                 :   case tok::plus:          // unary-expression: '+' cast-expression
     714                 :   case tok::minus:         // unary-expression: '-' cast-expression
     715                 :   case tok::tilde:         // unary-expression: '~' cast-expression
     716                 :   case tok::exclaim:       // unary-expression: '!' cast-expression
     717                 :   case tok::kw___real:     // unary-expression: '__real' cast-expression [GNU]
     718                 :   case tok::kw___imag: {   // unary-expression: '__imag' cast-expression [GNU]
     719             2275:     SourceLocation SavedLoc = ConsumeToken();
     720             2275:     Res = ParseCastExpression(false);
                     2272: branch 1 taken
                        3: branch 2 taken
     721             2275:     if (!Res.isInvalid())
     722             2272:       Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
     723             2275:     return move(Res);
     724                 :   }
     725                 : 
     726                 :   case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
     727                 :     // __extension__ silences extension warnings in the subexpression.
     728               37:     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     729               37:     SourceLocation SavedLoc = ConsumeToken();
     730               37:     Res = ParseCastExpression(false);
                       37: branch 1 taken
                        0: branch 2 not taken
     731               37:     if (!Res.isInvalid())
     732               37:       Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move(Res));
     733               37:     return move(Res);
     734                 :   }
     735                 :   case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
     736                 :                            // unary-expression: 'sizeof' '(' type-name ')'
     737                 :   case tok::kw_alignof:
     738                 :   case tok::kw___alignof:  // unary-expression: '__alignof' unary-expression
     739                 :                            // unary-expression: '__alignof' '(' type-name ')'
     740                 :                            // unary-expression: 'alignof' '(' type-id ')'
     741              623:     return ParseSizeofAlignofExpression();
     742                 :   case tok::ampamp: {      // unary-expression: '&&' identifier
     743               39:     SourceLocation AmpAmpLoc = ConsumeToken();
                        0: branch 1 not taken
                       39: branch 2 taken
     744               39:     if (Tok.isNot(tok::identifier))
     745                0:       return ExprError(Diag(Tok, diag::err_expected_ident));
     746                 : 
     747               39:     Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
     748                 :     Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
     749               39:                                  Tok.getIdentifierInfo());
     750               39:     ConsumeToken();
     751               39:     return move(Res);
     752                 :   }
     753                 :   case tok::kw_const_cast:
     754                 :   case tok::kw_dynamic_cast:
     755                 :   case tok::kw_reinterpret_cast:
     756                 :   case tok::kw_static_cast:
     757              252:     Res = ParseCXXCasts();
     758                 :     // These can be followed by postfix-expr pieces.
     759              252:     return ParsePostfixExpressionSuffix(move(Res));
     760                 :   case tok::kw_typeid:
     761               83:     Res = ParseCXXTypeid();
     762                 :     // This can be followed by postfix-expr pieces.
     763               83:     return ParsePostfixExpressionSuffix(move(Res));
     764                 :   case tok::kw_this:
     765               80:     Res = ParseCXXThis();
     766                 :     // This can be followed by postfix-expr pieces.
     767               80:     return ParsePostfixExpressionSuffix(move(Res));
     768                 : 
     769                 :   case tok::kw_char:
     770                 :   case tok::kw_wchar_t:
     771                 :   case tok::kw_char16_t:
     772                 :   case tok::kw_char32_t:
     773                 :   case tok::kw_bool:
     774                 :   case tok::kw_short:
     775                 :   case tok::kw_int:
     776                 :   case tok::kw_long:
     777                 :   case tok::kw_signed:
     778                 :   case tok::kw_unsigned:
     779                 :   case tok::kw_float:
     780                 :   case tok::kw_double:
     781                 :   case tok::kw_void:
     782                 :   case tok::kw_typename:
     783                 :   case tok::kw_typeof:
     784                 :   case tok::kw___vector:
     785                 :   case tok::annot_typename: {
                        0: branch 1 not taken
                      518: branch 2 taken
     786              518:     if (!getLang().CPlusPlus) {
     787                0:       Diag(Tok, diag::err_expected_expression);
     788                0:       return ExprError();
     789                 :     }
     790                 : 
                        3: branch 0 taken
                      515: branch 1 taken
     791              518:     if (SavedKind == tok::kw_typename) {
     792                 :       // postfix-expression: typename-specifier '(' expression-list[opt] ')'
                        1: branch 1 taken
                        2: branch 2 taken
     793                3:       if (!TryAnnotateTypeOrScopeToken())
     794                1:         return ExprError();
     795                 :     }
     796                 : 
     797                 :     // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
     798                 :     //
     799              517:     DeclSpec DS;
     800              517:     ParseCXXSimpleTypeSpecifier(DS);
                        2: branch 1 taken
                      515: branch 2 taken
     801              517:     if (Tok.isNot(tok::l_paren))
     802                 :       return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
     803                2:                          << DS.getSourceRange());
     804                 : 
     805              515:     Res = ParseCXXTypeConstructExpression(DS);
     806                 :     // This can be followed by postfix-expr pieces.
     807              515:     return ParsePostfixExpressionSuffix(move(Res));
     808                 :   }
     809                 : 
     810                 :   case tok::annot_cxxscope: { // [C++] id-expression: qualified-id
     811              532:     Token Next = NextToken();
                       11: branch 1 taken
                      521: branch 2 taken
     812              532:     if (Next.is(tok::annot_template_id)) {
     813                 :       TemplateIdAnnotation *TemplateId
     814               11:         = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
                        1: branch 0 taken
                       10: branch 1 taken
     815               11:       if (TemplateId->Kind == TNK_Type_template) {
     816                 :         // We have a qualified template-id that we know refers to a
     817                 :         // type, translate it into a type and continue parsing as a
     818                 :         // cast expression.
     819                1:         CXXScopeSpec SS;
     820                1:         ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
     821                1:         AnnotateTemplateIdTokenAsType(&SS);
     822                 :         return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
     823                1:                                    NotCastExpr, TypeOfCast);
     824                 :       }
     825                 :     }
     826                 : 
     827                 :     // Parse as an id-expression.
     828              531:     Res = ParseCXXIdExpression(isAddressOfOperand);
     829              531:     return ParsePostfixExpressionSuffix(move(Res));
     830                 :   }
     831                 : 
     832                 :   case tok::annot_template_id: { // [C++]          template-id
     833                 :     TemplateIdAnnotation *TemplateId
     834              120:       = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
                        1: branch 0 taken
                      119: branch 1 taken
     835              120:     if (TemplateId->Kind == TNK_Type_template) {
     836                 :       // We have a template-id that we know refers to a type,
     837                 :       // translate it into a type and continue parsing as a cast
     838                 :       // expression.
     839                1:       AnnotateTemplateIdTokenAsType();
     840                 :       return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
     841                1:                                  NotCastExpr, TypeOfCast);
     842                 :     }
     843                 : 
     844                 :     // Fall through to treat the template-id as an id-expression.
     845                 :   }
     846                 : 
     847                 :   case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
     848              130:     Res = ParseCXXIdExpression(isAddressOfOperand);
     849              130:     return ParsePostfixExpressionSuffix(move(Res));
     850                 : 
     851                 :   case tok::coloncolon: {
     852                 :     // ::foo::bar -> global qualified name etc.   If TryAnnotateTypeOrScopeToken
     853                 :     // annotates the token, tail recurse.
                        6: branch 1 taken
                        4: branch 2 taken
     854               10:     if (TryAnnotateTypeOrScopeToken())
     855                6:       return ParseCastExpression(isUnaryExpression, isAddressOfOperand);
     856                 : 
     857                 :     // ::new -> [C++] new-expression
     858                 :     // ::delete -> [C++] delete-expression
     859                4:     SourceLocation CCLoc = ConsumeToken();
                        2: branch 1 taken
                        2: branch 2 taken
     860                4:     if (Tok.is(tok::kw_new))
     861                2:       return ParseCXXNewExpression(true, CCLoc);
                        2: branch 1 taken
                        0: branch 2 not taken
     862                2:     if (Tok.is(tok::kw_delete))
     863                2:       return ParseCXXDeleteExpression(true, CCLoc);
     864                 : 
     865                 :     // This is not a type name or scope specifier, it is an invalid expression.
     866                0:     Diag(CCLoc, diag::err_expected_expression);
     867                0:     return ExprError();
     868                 :   }
     869                 : 
     870                 :   case tok::kw_new: // [C++] new-expression
     871              113:     return ParseCXXNewExpression(false, Tok.getLocation());
     872                 : 
     873                 :   case tok::kw_delete: // [C++] delete-expression
     874               48:     return ParseCXXDeleteExpression(false, Tok.getLocation());
     875                 : 
     876                 :   case tok::kw___is_pod: // [GNU] unary-type-trait
     877                 :   case tok::kw___is_class:
     878                 :   case tok::kw___is_enum:
     879                 :   case tok::kw___is_union:
     880                 :   case tok::kw___is_empty:
     881                 :   case tok::kw___is_polymorphic:
     882                 :   case tok::kw___is_abstract:
     883                 :   case tok::kw___is_literal:
     884                 :   case tok::kw___has_trivial_constructor:
     885                 :   case tok::kw___has_trivial_copy:
     886                 :   case tok::kw___has_trivial_assign:
     887                 :   case tok::kw___has_trivial_destructor:
     888              180:     return ParseUnaryTypeTrait();
     889                 : 
     890                 :   case tok::at: {
     891              318:     SourceLocation AtLoc = ConsumeToken();
     892              318:     return ParseObjCAtExpression(AtLoc);
     893                 :   }
     894                 :   case tok::caret:
     895              264:     return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression());
     896                 :   case tok::l_square:
     897                 :     // These can be followed by postfix-expr pieces.
                     1675: branch 1 taken
                        2: branch 2 taken
     898             1677:     if (getLang().ObjC1)
     899             1675:       return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
     900                 :     // FALL THROUGH.
     901                 :   default:
     902               35:     NotCastExpr = true;
     903               35:     return ExprError();
     904                 :   }
     905                 : 
     906                 :   // unreachable.
     907            65517:   abort();
     908                 : }
     909                 : 
     910                 : /// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
     911                 : /// is parsed, this method parses any suffixes that apply.
     912                 : ///
     913                 : ///       postfix-expression: [C99 6.5.2]
     914                 : ///         primary-expression
     915                 : ///         postfix-expression '[' expression ']'
     916                 : ///         postfix-expression '(' argument-expression-list[opt] ')'
     917                 : ///         postfix-expression '.' identifier
     918                 : ///         postfix-expression '->' identifier
     919                 : ///         postfix-expression '++'
     920                 : ///         postfix-expression '--'
     921                 : ///         '(' type-name ')' '{' initializer-list '}'
     922                 : ///         '(' type-name ')' '{' initializer-list ',' '}'
     923                 : ///
     924                 : ///       argument-expression-list: [C99 6.5.2]
     925                 : ///         argument-expression
     926                 : ///         argument-expression-list ',' assignment-expression
     927                 : ///
     928                 : Parser::OwningExprResult
     929            55001: Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
     930                 :   // Now that the primary-expression piece of the postfix-expression has been
     931                 :   // parsed, see if there are any postfix-expression pieces here.
     932            55001:   SourceLocation Loc;
     933             9917:   while (1) {
                    54954: branch 1 taken
                      852: branch 2 taken
                     6549: branch 3 taken
                     2208: branch 4 taken
                      355: branch 5 taken
     934            64918:     switch (Tok.getKind()) {
     935                 :     default:  // Not a postfix-expression suffix.
     936            54954:       return move(LHS);
     937                 :     case tok::l_square: {  // postfix-expression: p-e '[' expression ']'
     938              852:       Loc = ConsumeBracket();
     939              852:       OwningExprResult Idx(ParseExpression());
     940                 : 
     941              852:       SourceLocation RLoc = Tok.getLocation();
     942                 : 
                      843: branch 1 taken
                        9: branch 2 taken
                      843: branch 4 taken
                        0: branch 5 not taken
                      843: branch 7 taken
                        0: branch 8 not taken
                      843: branch 9 taken
                        9: branch 10 taken
     943              852:       if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
     944                 :         LHS = Actions.ActOnArraySubscriptExpr(CurScope, move(LHS), Loc,
     945              843:                                               move(Idx), RLoc);
     946                 :       } else
     947                9:         LHS = ExprError();
     948                 : 
     949                 :       // Match the ']'.
     950              852:       MatchRHSPunctuation(tok::r_square, Loc);
     951              852:       break;
     952                 :     }
     953                 : 
     954                 :     case tok::l_paren: {   // p-e: p-e '(' argument-expression-list[opt] ')'
     955             6549:       ExprVector ArgExprs(Actions);
     956             6549:       CommaLocsTy CommaLocs;
     957                 : 
     958             6549:       Loc = ConsumeParen();
     959                 : 
                        2: branch 1 taken
                     6547: branch 2 taken
     960             6549:       if (Tok.is(tok::code_completion)) {
     961                2:         Actions.CodeCompleteCall(CurScope, LHS.get(), 0, 0);
     962                2:         ConsumeToken();
     963                 :       }
     964                 :       
                     4936: branch 1 taken
                     1613: branch 2 taken
     965             6549:       if (Tok.isNot(tok::r_paren)) {
                       24: branch 2 taken
                     4912: branch 3 taken
     966             4936:         if (ParseExpressionList(ArgExprs, CommaLocs, &Action::CodeCompleteCall,
     967                 :                                 LHS.get())) {
     968               24:           SkipUntil(tok::r_paren);
     969               24:           return ExprError();
     970                 :         }
     971                 :       }
     972                 : 
     973                 :       // Match the ')'.
                        1: branch 1 taken
                     6524: branch 2 taken
     974             6525:       if (Tok.isNot(tok::r_paren)) {
     975                1:         MatchRHSPunctuation(tok::r_paren, Loc);
     976                1:         return ExprError();
     977                 :       }
     978                 : 
                     6507: branch 1 taken
                       17: branch 2 taken
     979             6524:       if (!LHS.isInvalid()) {
     980                 :         assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
                     4908: branch 1 taken
                     1599: branch 2 taken
                     4908: branch 5 taken
                        0: branch 6 not taken
     981             6507:                "Unexpected number of commas!");
     982                 :         LHS = Actions.ActOnCallExpr(CurScope, move(LHS), Loc,
     983                 :                                     move_arg(ArgExprs), CommaLocs.data(),
     984             6507:                                     Tok.getLocation());
     985                 :       }
     986                 : 
     987             6524:       ConsumeParen();
                       25: branch 1 taken
                     6524: branch 2 taken
                       25: branch 4 taken
                     6524: branch 5 taken
     988             6549:       break;
     989                 :     }
     990                 :     case tok::arrow:
     991                 :     case tok::period: {
     992                 :       // postfix-expression: p-e '->' template[opt] id-expression
     993                 :       // postfix-expression: p-e '.' template[opt] id-expression
     994             2208:       tok::TokenKind OpKind = Tok.getKind();
     995             2208:       SourceLocation OpLoc = ConsumeToken();  // Eat the "." or "->" token.
     996                 : 
     997             2208:       CXXScopeSpec SS;
     998             2208:       Action::TypeTy *ObjectType = 0;
                      892: branch 1 taken
                     1316: branch 2 taken
                      890: branch 4 taken
                        2: branch 5 taken
                      890: branch 6 taken
                     1318: branch 7 taken
     999             2208:       if (getLang().CPlusPlus && !LHS.isInvalid()) {
    1000                 :         LHS = Actions.ActOnStartCXXMemberReference(CurScope, move(LHS),
    1001              890:                                                    OpLoc, OpKind, ObjectType);
                       12: branch 1 taken
                      878: branch 2 taken
    1002              890:         if (LHS.isInvalid())
    1003               12:           break;
    1004              878:         ParseOptionalCXXScopeSpecifier(SS, ObjectType, false);
    1005                 :       }
    1006                 : 
                       10: branch 1 taken
                     2186: branch 2 taken
    1007             2196:       if (Tok.is(tok::code_completion)) {
    1008                 :         // Code completion for a member access expression.
    1009                 :         Actions.CodeCompleteMemberReferenceExpr(CurScope, LHS.get(),
    1010               10:                                                 OpLoc, OpKind == tok::arrow);
    1011                 :         
    1012               10:         ConsumeToken();
    1013                 :       }
    1014                 :       
    1015             2196:       UnqualifiedId Name;
                       22: branch 1 taken
                     2174: branch 2 taken
    1016             2196:       if (ParseUnqualifiedId(SS, 
    1017                 :                              /*EnteringContext=*/false, 
    1018                 :                              /*AllowDestructorName=*/true,
    1019                 :                              /*AllowConstructorName=*/false, 
    1020                 :                              ObjectType,
    1021                 :                              Name))
    1022               22:         return ExprError();
    1023                 :       
                     2168: branch 1 taken
                        6: branch 2 taken
    1024             2174:       if (!LHS.isInvalid())
    1025                 :         LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, OpKind,
    1026                 :                                             SS, Name, ObjCImpDecl,
    1027             2168:                                             Tok.is(tok::l_paren));
    1028                 :       
                       22: branch 1 taken
                     2174: branch 2 taken
    1029             2196:       break;
    1030                 :     }
    1031                 :     case tok::plusplus:    // postfix-expression: postfix-expression '++'
    1032                 :     case tok::minusminus:  // postfix-expression: postfix-expression '--'
                      348: branch 1 taken
                        7: branch 2 taken
    1033              355:       if (!LHS.isInvalid()) {
    1034                 :         LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(),
    1035              348:                                           Tok.getKind(), move(LHS));
    1036                 :       }
    1037              355:       ConsumeToken();
    1038                 :       break;
    1039                 :     }
    1040                 :   }
    1041                 : }
    1042                 : 
    1043                 : /// ParseExprAfterTypeofSizeofAlignof - We parsed a typeof/sizeof/alignof and
    1044                 : /// we are at the start of an expression or a parenthesized type-id.
    1045                 : /// OpTok is the operand token (typeof/sizeof/alignof). Returns the expression
    1046                 : /// (isCastExpr == false) or the type (isCastExpr == true).
    1047                 : ///
    1048                 : ///       unary-expression:  [C99 6.5.3]
    1049                 : ///         'sizeof' unary-expression
    1050                 : ///         'sizeof' '(' type-name ')'
    1051                 : /// [GNU]   '__alignof' unary-expression
    1052                 : /// [GNU]   '__alignof' '(' type-name ')'
    1053                 : /// [C++0x] 'alignof' '(' type-id ')'
    1054                 : ///
    1055                 : /// [GNU]   typeof-specifier:
    1056                 : ///           typeof ( expressions )
    1057                 : ///           typeof ( type-name )
    1058                 : /// [GNU/C++] typeof unary-expression
    1059                 : ///
    1060                 : Parser::OwningExprResult
    1061                 : Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
    1062                 :                                           bool &isCastExpr,
    1063                 :                                           TypeTy *&CastTy,
    1064              887:                                           SourceRange &CastRange) {
    1065                 : 
    1066                 :   assert((OpTok.is(tok::kw_typeof)    || OpTok.is(tok::kw_sizeof) ||
    1067                 :           OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof)) &&
                      623: branch 1 taken
                      264: branch 2 taken
                       54: branch 4 taken
                      569: branch 5 taken
                        7: branch 7 taken
                       47: branch 8 taken
                        7: branch 10 taken
                        0: branch 11 not taken
    1068              887:           "Not a typeof/sizeof/alignof expression!");
    1069                 : 
    1070              887:   OwningExprResult Operand(Actions);
    1071                 : 
    1072                 :   // If the operand doesn't start with an '(', it must be an expression.
                       15: branch 1 taken
                      872: branch 2 taken
    1073              887:   if (Tok.isNot(tok::l_paren)) {
    1074               15:     isCastExpr = false;
                        1: branch 1 taken
                       14: branch 2 taken
                        0: branch 4 not taken
                        1: branch 5 taken
                        0: branch 6 not taken
                       15: branch 7 taken
    1075               15:     if (OpTok.is(tok::kw_typeof) && !getLang().CPlusPlus) {
    1076                0:       Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
    1077                0:       return ExprError();
    1078                 :     }
    1079                 : 
    1080                 :     // C++0x [expr.sizeof]p1:
    1081                 :     //   [...] The operand is either an expression, which is an unevaluated
    1082                 :     //   operand (Clause 5) [...]
    1083                 :     //
    1084                 :     // The GNU typeof and alignof extensions also behave as unevaluated
    1085                 :     // operands.
    1086                 :     EnterExpressionEvaluationContext Unevaluated(Actions,
    1087               15:                                                  Action::Unevaluated);
    1088               15:     Operand = ParseCastExpression(true/*isUnaryExpression*/);
    1089                 :   } else {
    1090                 :     // If it starts with a '(', we know that it is either a parenthesized
    1091                 :     // type-name, or it is a unary-expression that starts with a compound
    1092                 :     // literal, or starts with a primary-expression that is a parenthesized
    1093                 :     // expression.
    1094              872:     ParenParseOption ExprType = CastExpr;
    1095              872:     SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
    1096                 : 
    1097                 :     // C++0x [expr.sizeof]p1:
    1098                 :     //   [...] The operand is either an expression, which is an unevaluated
    1099                 :     //   operand (Clause 5) [...]
    1100                 :     //
    1101                 :     // The GNU typeof and alignof extensions also behave as unevaluated
    1102                 :     // operands.
    1103                 :     EnterExpressionEvaluationContext Unevaluated(Actions,
    1104              872:                                                  Action::Unevaluated);
    1105                 :     Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 
    1106                 :                                    0/*TypeOfCast*/,
    1107              872:                                    CastTy, RParenLoc);
    1108              872:     CastRange = SourceRange(LParenLoc, RParenLoc);
    1109                 : 
    1110                 :     // If ParseParenExpression parsed a '(typename)' sequence only, then this is
    1111                 :     // a type.
                      443: branch 0 taken
                      429: branch 1 taken
    1112              872:     if (ExprType == CastExpr) {
    1113              443:       isCastExpr = true;
    1114              443:       return ExprEmpty();
    1115                 :     }
    1116                 : 
    1117                 :     // If this is a parenthesized expression, it is the start of a
    1118                 :     // unary-expression, but doesn't include any postfix pieces.  Parse these
    1119                 :     // now if present.
                      429: branch 10 taken
                      443: branch 11 taken
    1120              429:     Operand = ParsePostfixExpressionSuffix(move(Operand));
    1121                 :   }
    1122                 : 
    1123                 :   // If we get here, the operand to the typeof/sizeof/alignof was an expresion.
    1124              444:   isCastExpr = false;
    1125              444:   return move(Operand);
    1126                 : }
    1127                 : 
    1128                 : 
    1129                 : /// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
    1130                 : ///       unary-expression:  [C99 6.5.3]
    1131                 : ///         'sizeof' unary-expression
    1132                 : ///         'sizeof' '(' type-name ')'
    1133                 : /// [GNU]   '__alignof' unary-expression
    1134                 : /// [GNU]   '__alignof' '(' type-name ')'
    1135                 : /// [C++0x] 'alignof' '(' type-id ')'
    1136              623: Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() {
    1137                 :   assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
    1138                 :           || Tok.is(tok::kw_alignof)) &&
                       54: branch 1 taken
                      569: branch 2 taken
                        7: branch 4 taken
                       47: branch 5 taken
                        7: branch 7 taken
                        0: branch 8 not taken
    1139              623:          "Not a sizeof/alignof expression!");
    1140              623:   Token OpTok = Tok;
    1141              623:   ConsumeToken();
    1142                 : 
    1143                 :   bool isCastExpr;
    1144                 :   TypeTy *CastTy;
    1145              623:   SourceRange CastRange;
    1146                 :   OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
    1147                 :                                                                isCastExpr,
    1148                 :                                                                CastTy,
    1149              623:                                                                CastRange);
    1150                 : 
                      424: branch 0 taken
                      199: branch 1 taken
    1151              623:   if (isCastExpr)
    1152                 :     return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
    1153                 :                                           OpTok.is(tok::kw_sizeof),
    1154                 :                                           /*isType=*/true, CastTy,
    1155              424:                                           CastRange);
    1156                 : 
    1157                 :   // If we get here, the operand to the sizeof/alignof was an expresion.
                      198: branch 1 taken
                        1: branch 2 taken
    1158              199:   if (!Operand.isInvalid())
    1159                 :     Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
    1160                 :                                              OpTok.is(tok::kw_sizeof),
    1161                 :                                              /*isType=*/false,
    1162              198:                                              Operand.release(), CastRange);
    1163              199:   return move(Operand);
    1164                 : }
    1165                 : 
    1166                 : /// ParseBuiltinPrimaryExpression
    1167                 : ///
    1168                 : ///       primary-expression: [C99 6.5.1]
    1169                 : /// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
    1170                 : /// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
    1171                 : /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
    1172                 : ///                                     assign-expr ')'
    1173                 : /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
    1174                 : ///
    1175                 : /// [GNU] offsetof-member-designator:
    1176                 : /// [GNU]   identifier
    1177                 : /// [GNU]   offsetof-member-designator '.' identifier
    1178                 : /// [GNU]   offsetof-member-designator '[' expression ']'
    1179                 : ///
    1180              234: Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
    1181              234:   OwningExprResult Res(Actions);
    1182              234:   const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
    1183                 : 
    1184              234:   tok::TokenKind T = Tok.getKind();
    1185              234:   SourceLocation StartLoc = ConsumeToken();   // Eat the builtin identifier.
    1186                 : 
    1187                 :   // All of these start with an open paren.
                        0: branch 1 not taken
                      234: branch 2 taken
    1188              234:   if (Tok.isNot(tok::l_paren))
    1189                 :     return ExprError(Diag(Tok, diag::err_expected_lparen_after_id)
    1190                0:                        << BuiltinII);
    1191                 : 
    1192              234:   SourceLocation LParenLoc = ConsumeParen();
    1193                 :   // TODO: Build AST.
    1194                 : 
                        0: branch 0 not taken
                       35: branch 1 taken
                      128: branch 2 taken
                       33: branch 3 taken
                       38: branch 4 taken
    1195              234:   switch (T) {
    1196                0:   default: assert(0 && "Not a builtin primary expression!");
    1197                 :   case tok::kw___builtin_va_arg: {
    1198               35:     OwningExprResult Expr(ParseAssignmentExpression());
                        1: branch 1 taken
                       34: branch 2 taken
    1199               35:     if (Expr.isInvalid()) {
    1200                1:       SkipUntil(tok::r_paren);
    1201                1:       return ExprError();
    1202                 :     }
    1203                 : 
                        0: branch 1 not taken
                       34: branch 2 taken
    1204               34:     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
    1205                0:       return ExprError();
    1206                 : 
    1207               34:     TypeResult Ty = ParseTypeName();
    1208                 : 
                        0: branch 1 not taken
                       34: branch 2 taken
    1209               34:     if (Tok.isNot(tok::r_paren)) {
    1210                0:       Diag(Tok, diag::err_expected_rparen);
    1211                0:       return ExprError();
    1212                 :     }
                        0: branch 1 not taken
                       34: branch 2 taken
    1213               34:     if (Ty.isInvalid())
    1214                0:       Res = ExprError();
    1215                 :     else
    1216               34:       Res = Actions.ActOnVAArg(StartLoc, move(Expr), Ty.get(), ConsumeParen());
                        1: branch 1 taken
                       34: branch 2 taken
    1217               35:     break;
    1218                 :   }
    1219                 :   case tok::kw___builtin_offsetof: {
    1220              128:     SourceLocation TypeLoc = Tok.getLocation();
    1221              128:     TypeResult Ty = ParseTypeName();
                        1: branch 1 taken
                      127: branch 2 taken
    1222              128:     if (Ty.isInvalid()) {
    1223                1:       SkipUntil(tok::r_paren);
    1224                1:       return ExprError();
    1225                 :     }
    1226                 : 
                        0: branch 1 not taken
                      127: branch 2 taken
    1227              127:     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
    1228                0:       return ExprError();
    1229                 : 
    1230                 :     // We must have at least one identifier here.
                        0: branch 1 not taken
                      127: branch 2 taken
    1231              127:     if (Tok.isNot(tok::identifier)) {
    1232                0:       Diag(Tok, diag::err_expected_ident);
    1233                0:       SkipUntil(tok::r_paren);
    1234                0:       return ExprError();
    1235                 :     }
    1236                 : 
    1237                 :     // Keep track of the various subcomponents we see.
    1238              127:     llvm::SmallVector<Action::OffsetOfComponent, 4> Comps;
    1239                 : 
    1240              127:     Comps.push_back(Action::OffsetOfComponent());
    1241              127:     Comps.back().isBrackets = false;
    1242              127:     Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
    1243              127:     Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
    1244                 : 
    1245                 :     // FIXME: This loop leaks the index expressions on error.
    1246               16:     while (1) {
                        7: branch 1 taken
                      136: branch 2 taken
    1247              143:       if (Tok.is(tok::period)) {
    1248                 :         // offsetof-member-designator: offsetof-member-designator '.' identifier
    1249                7:         Comps.push_back(Action::OffsetOfComponent());
    1250                7:         Comps.back().isBrackets = false;
    1251                7:         Comps.back().LocStart = ConsumeToken();
    1252                 : 
                        0: branch 1 not taken
                        7: branch 2 taken
    1253                7:         if (Tok.isNot(tok::identifier)) {
    1254                0:           Diag(Tok, diag::err_expected_ident);
    1255                0:           SkipUntil(tok::r_paren);
    1256                0:           return ExprError();
    1257                 :         }
    1258                7:         Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
    1259                7:         Comps.back().LocEnd = ConsumeToken();
    1260                 : 
                        9: branch 1 taken
                      127: branch 2 taken
    1261              136:       } else if (Tok.is(tok::l_square)) {
    1262                 :         // offsetof-member-designator: offsetof-member-design '[' expression ']'
    1263                9:         Comps.push_back(Action::OffsetOfComponent());
    1264                9:         Comps.back().isBrackets = true;
    1265                9:         Comps.back().LocStart = ConsumeBracket();
    1266                9:         Res = ParseExpression();
                        0: branch 1 not taken
                        9: branch 2 taken
    1267                9:         if (Res.isInvalid()) {
    1268                0:           SkipUntil(tok::r_paren);
    1269                0:           return move(Res);
    1270                 :         }
    1271                9:         Comps.back().U.E = Res.release();
    1272                 : 
    1273                 :         Comps.back().LocEnd =
    1274                9:           MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
    1275                 :       } else {
                        2: branch 1 taken
                      125: branch 2 taken
    1276              127:         if (Tok.isNot(tok::r_paren)) {
    1277                2:           MatchRHSPunctuation(tok::r_paren, LParenLoc);
    1278                2:           Res = ExprError();
                        0: branch 1 not taken
                      125: branch 2 taken
    1279              125:         } else if (Ty.isInvalid()) {
    1280                0:           Res = ExprError();
    1281                 :         } else {
    1282                 :           Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc,
    1283                 :                                              Ty.get(), &Comps[0],
    1284              125:                                              Comps.size(), ConsumeParen());
    1285                 :         }
    1286                 :         break;
    1287                 :       }
    1288                 :     }
                        0: branch 1 not taken
                      127: branch 2 taken
    1289              127:     break;
    1290                 :   }
    1291                 :   case tok::kw___builtin_choose_expr: {
    1292               33:     OwningExprResult Cond(ParseAssignmentExpression());
                        0: branch 1 not taken
                       33: branch 2 taken
    1293               33:     if (Cond.isInvalid()) {
    1294                0:       SkipUntil(tok::r_paren);
    1295                0:       return move(Cond);
    1296                 :     }
                        0: branch 1 not taken
                       33: branch 2 taken
    1297               33:     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
    1298                0:       return ExprError();
    1299                 : 
    1300               33:     OwningExprResult Expr1(ParseAssignmentExpression());
                        0: branch 1 not taken
                       33: branch 2 taken
    1301               33:     if (Expr1.isInvalid()) {
    1302                0:       SkipUntil(tok::r_paren);
    1303                0:       return move(Expr1);
    1304                 :     }
                        0: branch 1 not taken
                       33: branch 2 taken
    1305               33:     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
    1306                0:       return ExprError();
    1307                 : 
    1308               33:     OwningExprResult Expr2(ParseAssignmentExpression());
                        0: branch 1 not taken
                       33: branch 2 taken
    1309               33:     if (Expr2.isInvalid()) {
    1310                0:       SkipUntil(tok::r_paren);
    1311                0:       return move(Expr2);
    1312                 :     }
                        0: branch 1 not taken
                       33: branch 2 taken
    1313               33:     if (Tok.isNot(tok::r_paren)) {
    1314                0:       Diag(Tok, diag::err_expected_rparen);
    1315                0:       return ExprError();
    1316                 :     }
    1317                 :     Res = Actions.ActOnChooseExpr(StartLoc, move(Cond), move(Expr1),
    1318               33:                                   move(Expr2), ConsumeParen());
                        0: branch 1 not taken
                       33: branch 2 taken
                        0: branch 4 not taken
                       33: branch 5 taken
                        0: branch 7 not taken
                       33: branch 8 taken
    1319               33:     break;
    1320                 :   }
    1321                 :   case tok::kw___builtin_types_compatible_p:
    1322               38:     TypeResult Ty1 = ParseTypeName();
    1323                 : 
                        0: branch 1 not taken
                       38: branch 2 taken
    1324               38:     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
    1325                0:       return ExprError();
    1326                 : 
    1327               38:     TypeResult Ty2 = ParseTypeName();
    1328                 : 
                        0: branch 1 not taken
                       38: branch 2 taken
    1329               38:     if (Tok.isNot(tok::r_paren)) {
    1330                0:       Diag(Tok, diag::err_expected_rparen);
    1331                0:       return ExprError();
    1332                 :     }
    1333                 : 
                       38: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                       38: branch 5 taken
                        0: branch 6 not taken
                       38: branch 7 taken
    1334               38:     if (Ty1.isInvalid() || Ty2.isInvalid())
    1335                0:       Res = ExprError();
    1336                 :     else
    1337                 :       Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1.get(), Ty2.get(),
    1338               38:                                              ConsumeParen());
    1339                 :     break;
    1340                 :   }
    1341                 : 
    1342                 :   // These can be followed by postfix-expr pieces because they are
    1343                 :   // primary-expressions.
    1344              232:   return ParsePostfixExpressionSuffix(move(Res));
    1345                 : }
    1346                 : 
    1347                 : /// ParseParenExpression - This parses the unit that starts with a '(' token,
    1348                 : /// based on what is allowed by ExprType.  The actual thing parsed is returned
    1349                 : /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
    1350                 : /// not the parsed cast-expression.
    1351                 : ///
    1352                 : ///       primary-expression: [C99 6.5.1]
    1353                 : ///         '(' expression ')'
    1354                 : /// [GNU]   '(' compound-statement ')'      (if !ParenExprOnly)
    1355                 : ///       postfix-expression: [C99 6.5.2]
    1356                 : ///         '(' type-name ')' '{' initializer-list '}'
    1357                 : ///         '(' type-name ')' '{' initializer-list ',' '}'
    1358                 : ///       cast-expression: [C99 6.5.4]
    1359                 : ///         '(' type-name ')' cast-expression
    1360                 : ///
    1361                 : Parser::OwningExprResult
    1362                 : Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
    1363                 :                              TypeTy *TypeOfCast, TypeTy *&CastTy,
    1364             9509:                              SourceLocation &RParenLoc) {
                     9509: branch 1 taken
                        0: branch 2 not taken
    1365             9509:   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
    1366             9509:   GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
    1367             9509:   SourceLocation OpenLoc = ConsumeParen();
    1368             9509:   OwningExprResult Result(Actions, true);
    1369                 :   bool isAmbiguousTypeId;
    1370             9509:   CastTy = 0;
    1371                 : 
                     9509: branch 0 taken
                        0: branch 1 not taken
                       65: branch 3 taken
                     9444: branch 4 taken
                       65: branch 5 taken
                     9444: branch 6 taken
    1372            19018:   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
    1373               65:     Diag(Tok, diag::ext_gnu_statement_expr);
    1374               65:     OwningStmtResult Stmt(ParseCompoundStatement(0, true));
    1375               65:     ExprType = CompoundStmt;
    1376                 : 
    1377                 :     // If the substmt parsed correctly, build the AST node.
                       65: branch 1 taken
                        0: branch 2 not taken
                       65: branch 4 taken
                        0: branch 5 not taken
                       65: branch 6 taken
                        0: branch 7 not taken
    1378               65:     if (!Stmt.isInvalid() && Tok.is(tok::r_paren))
    1379               65:       Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation());
    1380                 : 
                     9444: branch 0 taken
                        0: branch 1 not taken
                     5586: branch 3 taken
                     3858: branch 4 taken
                     5586: branch 5 taken
                     3858: branch 6 taken
    1381             9444:   } else if (ExprType >= CompoundLiteral &&
    1382                 :              isTypeIdInParens(isAmbiguousTypeId)) {
    1383                 : 
    1384                 :     // Otherwise, this is a compound literal expression or cast expression.
    1385                 : 
    1386                 :     // In C++, if the type-id is ambiguous we disambiguate based on context.
    1387                 :     // If stopIfCastExpr is true the context is a typeof/sizeof/alignof
    1388                 :     // in which case we should treat it as type-id.
    1389                 :     // if stopIfCastExpr is false, we need to determine the context past the
    1390                 :     // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
                       36: branch 0 taken
                     5550: branch 1 taken
                       35: branch 2 taken
                        1: branch 3 taken
    1391             5586:     if (isAmbiguousTypeId && !stopIfCastExpr)
    1392                 :       return ParseCXXAmbiguousParenExpression(ExprType, CastTy,
    1393               35:                                               OpenLoc, RParenLoc);
    1394                 : 
    1395             5551:     TypeResult Ty = ParseTypeName();
    1396                 : 
    1397                 :     // Match the ')'.
                     5549: branch 1 taken
                        2: branch 2 taken
    1398             5551:     if (Tok.is(tok::r_paren))
    1399             5549:       RParenLoc = ConsumeParen();
    1400                 :     else
    1401                2:       MatchRHSPunctuation(tok::r_paren, OpenLoc);
    1402                 : 
                      291: branch 1 taken
                     5260: branch 2 taken
    1403             5551:     if (Tok.is(tok::l_brace)) {
    1404              291:       ExprType = CompoundLiteral;
    1405              291:       return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
    1406                 :     }
    1407                 : 
                     5260: branch 0 taken
                        0: branch 1 not taken
    1408             5260:     if (ExprType == CastExpr) {
    1409                 :       // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
    1410                 : 
                        4: branch 1 taken
                     5256: branch 2 taken
    1411             5260:       if (Ty.isInvalid())
    1412                4:         return ExprError();
    1413                 : 
    1414             5256:       CastTy = Ty.get();
    1415                 : 
                      439: branch 0 taken
                     4817: branch 1 taken
    1416             5256:       if (stopIfCastExpr) {
    1417                 :         // Note that this doesn't parse the subsequent cast-expression, it just
    1418                 :         // returns the parsed type to the callee.
    1419              439:         return OwningExprResult(Actions);
    1420                 :       }
    1421                 : 
    1422                 :       // Parse the cast-expression that follows it next.
    1423                 :       // TODO: For cast expression with CastTy.
    1424             4817:       Result = ParseCastExpression(false, false, CastTy);
                     4681: branch 1 taken
                      136: branch 2 taken
    1425             4817:       if (!Result.isInvalid())
    1426                 :         Result = Actions.ActOnCastExpr(CurScope, OpenLoc, CastTy, RParenLoc,
    1427             4681:                                        move(Result));
    1428             4817:       return move(Result);
    1429                 :     }
    1430                 : 
    1431                0:     Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
    1432                0:     return ExprError();
                      461: branch 0 taken
                     3397: branch 1 taken
    1433             3858:   } else if (TypeOfCast) {
    1434                 :     // Parse the expression-list.
    1435              461:     ExprVector ArgExprs(Actions);
    1436              461:     CommaLocsTy CommaLocs;
    1437                 : 
                      419: branch 1 taken
                       42: branch 2 taken
    1438              461:     if (!ParseExpressionList(ArgExprs, CommaLocs)) {
    1439              419:       ExprType = SimpleExpr;
    1440                 :       Result = Actions.ActOnParenOrParenListExpr(OpenLoc, Tok.getLocation(),
    1441              419:                                           move_arg(ArgExprs), TypeOfCast);
    1442              461:     }
    1443                 :   } else {
    1444             3397:     Result = ParseExpression();
    1445             3397:     ExprType = SimpleExpr;
                     3392: branch 1 taken
                        5: branch 2 taken
                     3392: branch 4 taken
                        0: branch 5 not taken
                     3392: branch 6 taken
                        5: branch 7 taken
    1446             3397:     if (!Result.isInvalid() && Tok.is(tok::r_paren))
    1447             3392:       Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), move(Result));
    1448                 :   }
    1449                 : 
    1450                 :   // Match the ')'.
                       48: branch 1 taken
                     3875: branch 2 taken
    1451             3923:   if (Result.isInvalid()) {
    1452               48:     SkipUntil(tok::r_paren);
    1453               48:     return ExprError();
    1454                 :   }
    1455                 : 
                     3875: branch 1 taken
                        0: branch 2 not taken
    1456             3875:   if (Tok.is(tok::r_paren))
    1457             3875:     RParenLoc = ConsumeParen();
    1458                 :   else
    1459                0:     MatchRHSPunctuation(tok::r_paren, OpenLoc);
    1460                 : 
    1461             3875:   return move(Result);
    1462                 : }
    1463                 : 
    1464                 : /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
    1465                 : /// and we are at the left brace.
    1466                 : ///
    1467                 : ///       postfix-expression: [C99 6.5.2]
    1468                 : ///         '(' type-name ')' '{' initializer-list '}'
    1469                 : ///         '(' type-name ')' '{' initializer-list ',' '}'
    1470                 : ///
    1471                 : Parser::OwningExprResult
    1472                 : Parser::ParseCompoundLiteralExpression(TypeTy *Ty,
    1473                 :                                        SourceLocation LParenLoc,
    1474              291:                                        SourceLocation RParenLoc) {
                      291: branch 1 taken
                        0: branch 2 not taken
    1475              291:   assert(Tok.is(tok::l_brace) && "Not a compound literal!");
                       50: branch 1 taken
                      241: branch 2 taken
    1476              291:   if (!getLang().C99)   // Compound literals don't exist in C90.
    1477               50:     Diag(LParenLoc, diag::ext_c99_compound_literal);
    1478              291:   OwningExprResult Result = ParseInitializer();
                      291: branch 1 taken
                        0: branch 2 not taken
                      282: branch 3 taken
                        9: branch 4 taken
                      282: branch 5 taken
                        9: branch 6 taken
    1479              291:   if (!Result.isInvalid() && Ty)
    1480              282:     return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, move(Result));
    1481                9:   return move(Result);
    1482                 : }
    1483                 : 
    1484                 : /// ParseStringLiteralExpression - This handles the various token types that
    1485                 : /// form string literals, and also handles string concatenation [C99 5.1.1.2,
    1486                 : /// translation phase #6].
    1487                 : ///
    1488                 : ///       primary-expression: [C99 6.5.1]
    1489                 : ///         string-literal
    1490             1790: Parser::OwningExprResult Parser::ParseStringLiteralExpression() {
                     1790: branch 1 taken
                        0: branch 2 not taken
    1491             1790:   assert(isTokenStringLiteral() && "Not a string literal!");
    1492                 : 
    1493                 :   // String concat.  Note that keywords like __func__ and __FUNCTION__ are not
    1494                 :   // considered to be strings for concatenation purposes.
    1495             1790:   llvm::SmallVector<Token, 4> StringToks;
    1496                 : 
                      175: branch 1 taken
                     1790: branch 2 taken
    1497             1965:   do {
    1498             1965:     StringToks.push_back(Tok);
    1499             1965:     ConsumeStringToken();
    1500                 :   } while (isTokenStringLiteral());
    1501                 : 
    1502                 :   // Pass the set of string tokens, ready for concatenation, to the actions.
    1503             1790:   return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size());
    1504                 : }
    1505                 : 
    1506                 : /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
    1507                 : ///
    1508                 : ///       argument-expression-list:
    1509                 : ///         assignment-expression
    1510                 : ///         argument-expression-list , assignment-expression
    1511                 : ///
    1512                 : /// [C++] expression-list:
    1513                 : /// [C++]   assignment-expression
    1514                 : /// [C++]   expression-list , assignment-expression
    1515                 : ///
    1516                 : bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
    1517                 :                                  void (Action::*Completer)(Scope *S, 
    1518                 :                                                            void *Data,
    1519                 :                                                            ExprTy **Args,
    1520                 :                                                            unsigned NumArgs),
    1521            10348:                                  void *Data) {
                     4346: branch 1 taken
                     6002: branch 2 taken
    1522            10348:   while (1) {
                        4: branch 1 taken
                    10344: branch 2 taken
    1523            10348:     if (Tok.is(tok::code_completion)) {
                        4: branch 0 taken
                        0: branch 1 not taken
    1524                4:       if (Completer)
                        4: branch 0 taken
                        0: branch 1 not taken
    1525                4:         (Actions.*Completer)(CurScope, Data, Exprs.data(), Exprs.size());
    1526                4:       ConsumeToken();
    1527                 :     }
    1528                 :     
    1529            10348:     OwningExprResult Expr(ParseAssignmentExpression());
                       69: branch 1 taken
                    10279: branch 2 taken
    1530            10348:     if (Expr.isInvalid())
    1531               69:       return true;
    1532                 : 
    1533            10279:     Exprs.push_back(Expr.release());
    1534                 : 
                     5933: branch 1 taken
                     4346: branch 2 taken
    1535            10279:     if (Tok.isNot(tok::comma))
    1536             5933:       return false;
    1537                 :     // Move to the next argument, remember where the comma was.
    1538             4346:     CommaLocs.push_back(ConsumeToken());
    1539                 :   }
    1540                 : }
    1541                 : 
    1542                 : /// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
    1543                 : ///
    1544                 : /// [clang] block-id:
    1545                 : /// [clang]   specifier-qualifier-list block-declarator
    1546                 : ///
    1547               25: void Parser::ParseBlockId() {
    1548                 :   // Parse the specifier-qualifier-list piece.
    1549               25:   DeclSpec DS;
    1550               25:   ParseSpecifierQualifierList(DS);
    1551                 : 
    1552                 :   // Parse the block-declarator.
    1553               25:   Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
    1554               25:   ParseDeclarator(DeclaratorInfo);
    1555                 : 
    1556                 :   // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
    1557                 :   DeclaratorInfo.AddAttributes(DS.TakeAttributes(),
    1558               25:                                SourceLocation());
    1559                 : 
                        0: branch 1 not taken
                       25: branch 2 taken
    1560               25:   if (Tok.is(tok::kw___attribute)) {
    1561                0:     SourceLocation Loc;
    1562                0:     AttributeList *AttrList = ParseGNUAttributes(&Loc);
    1563                0:     DeclaratorInfo.AddAttributes(AttrList, Loc);
    1564                 :   }
    1565                 : 
    1566                 :   // Inform sema that we are starting a block.
    1567               25:   Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
    1568               25: }
    1569                 : 
    1570                 : /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
    1571                 : /// like ^(int x){ return x+1; }
    1572                 : ///
    1573                 : ///         block-literal:
    1574                 : /// [clang]   '^' block-args[opt] compound-statement
    1575                 : /// [clang]   '^' block-id compound-statement
    1576                 : /// [clang] block-args:
    1577                 : /// [clang]   '(' parameter-list ')'
    1578                 : ///
    1579              264: Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
                      264: branch 1 taken
                        0: branch 2 not taken
    1580              264:   assert(Tok.is(tok::caret) && "block literal starts with ^");
    1581              264:   SourceLocation CaretLoc = ConsumeToken();
    1582                 : 
    1583                 :   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), CaretLoc,
    1584              264:                                 "block literal parsing");
    1585                 : 
    1586                 :   // Enter a scope to hold everything within the block.  This includes the
    1587                 :   // argument decls, decls within the compound expression, etc.  This also
    1588                 :   // allows determining whether a variable reference inside the block is
    1589                 :   // within or outside of the block.
    1590                 :   ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
    1591                 :                               Scope::BreakScope | Scope::ContinueScope |
    1592              264:                               Scope::DeclScope);
    1593                 : 
    1594                 :   // Inform sema that we are starting a block.
    1595              264:   Actions.ActOnBlockStart(CaretLoc, CurScope);
    1596                 : 
    1597                 :   // Parse the return type if present.
    1598              264:   DeclSpec DS;
    1599              264:   Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
    1600                 :   // FIXME: Since the return type isn't actually parsed, it can't be used to
    1601                 :   // fill ParamInfo with an initial valid range, so do it manually.
    1602              264:   ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
    1603                 : 
    1604                 :   // If this block has arguments, parse them.  There is no ambiguity here with
    1605                 :   // the expression case, because the expression case requires a parameter list.
                       59: branch 1 taken
                      205: branch 2 taken
    1606              264:   if (Tok.is(tok::l_paren)) {
    1607               59:     ParseParenDeclarator(ParamInfo);
    1608                 :     // Parse the pieces after the identifier as if we had "int(...)".
    1609                 :     // SetIdentifier sets the source range end, but in this case we're past
    1610                 :     // that location.
    1611               59:     SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
    1612               59:     ParamInfo.SetIdentifier(0, CaretLoc);
    1613               59:     ParamInfo.SetRangeEnd(Tmp);
                        0: branch 1 not taken
                       59: branch 2 taken
    1614               59:     if (ParamInfo.isInvalidType()) {
    1615                 :       // If there was an error parsing the arguments, they may have
    1616                 :       // tried to use ^(x+y) which requires an argument list.  Just
    1617                 :       // skip the whole block literal.
    1618                0:       Actions.ActOnBlockError(CaretLoc, CurScope);
    1619                0:       return ExprError();
    1620                 :     }
    1621                 : 
                        2: branch 1 taken
                       57: branch 2 taken
    1622               59:     if (Tok.is(tok::kw___attribute)) {
    1623                2:       SourceLocation Loc;
    1624                2:       AttributeList *AttrList = ParseGNUAttributes(&Loc);
    1625                2:       ParamInfo.AddAttributes(AttrList, Loc);
    1626                 :     }
    1627                 : 
    1628                 :     // Inform sema that we are starting a block.
    1629               59:     Actions.ActOnBlockArguments(ParamInfo, CurScope);
                       25: branch 1 taken
                      180: branch 2 taken
    1630              205:   } else if (!Tok.is(tok::l_brace)) {
    1631               25:     ParseBlockId();
    1632                 :   } else {
    1633                 :     // Otherwise, pretend we saw (void).
    1634                 :     ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
    1635                 :                                                        SourceLocation(),
    1636                 :                                                        0, 0, 0,
    1637                 :                                                        false, SourceLocation(),
    1638                 :                                                        false, 0, 0, 0,
    1639                 :                                                        CaretLoc, CaretLoc,
    1640                 :                                                        ParamInfo),
    1641              180:                           CaretLoc);
    1642                 : 
                        0: branch 1 not taken
                      180: branch 2 taken
    1643              180:     if (Tok.is(tok::kw___attribute)) {
    1644                0:       SourceLocation Loc;
    1645                0:       AttributeList *AttrList = ParseGNUAttributes(&Loc);
    1646                0:       ParamInfo.AddAttributes(AttrList, Loc);
    1647                 :     }
    1648                 : 
    1649                 :     // Inform sema that we are starting a block.
    1650              180:     Actions.ActOnBlockArguments(ParamInfo, CurScope);
    1651                 :   }
    1652                 : 
    1653                 : 
    1654              264:   OwningExprResult Result(Actions, true);
                        1: branch 1 taken
                      263: branch 2 taken
    1655              264:   if (!Tok.is(tok::l_brace)) {
    1656                 :     // Saw something like: ^expr
    1657                1:     Diag(Tok, diag::err_expected_expression);
    1658                1:     Actions.ActOnBlockError(CaretLoc, CurScope);
    1659                1:     return ExprError();
    1660                 :   }
    1661                 : 
    1662              263:   OwningStmtResult Stmt(ParseCompoundStatementBody());
                      263: branch 1 taken
                        0: branch 2 not taken
    1663              263:   if (!Stmt.isInvalid())
    1664              263:     Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope);
    1665                 :   else
    1666                0:     Actions.ActOnBlockError(CaretLoc, CurScope);
    1667              263:   return move(Result);
    1668                 : }

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