//===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Expression parsing implementation.  Expressions in
// C99 basically consist of a bunch of binary operators with unary operators and
// other random stuff at the leaves.
//
// In the C99 grammar, these unary operators bind tightest and are represented
// as the 'cast-expression' production.  Everything else is either a binary
// operator (e.g. '/') or a ternary operator ("?:").  The unary leaves are
// handled by ParseCastExpression, the higher level pieces are handled by
// ParseBinaryExpression.
//
//===----------------------------------------------------------------------===//

#include "clang/Parse/Parser.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallString.h"
using namespace clang;

/// PrecedenceLevels - These are precedences for the binary/ternary operators in
/// the C99 grammar.  These have been named to relate with the C99 grammar
/// productions.  Low precedences numbers bind more weakly than high numbers.
namespace prec {
  enum Level {
    Unknown        = 0,    // Not binary operator.
    Comma          = 1,    // ,
    Assignment     = 2,    // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
    Conditional    = 3,    // ?
    LogicalOr      = 4,    // ||
    LogicalAnd     = 5,    // &&
    InclusiveOr    = 6,    // |
    ExclusiveOr    = 7,    // ^
    And            = 8,    // &
    Equality       = 9,    // ==, !=
    Relational     = 10,   //  >=, <=, >, <
    Shift          = 11,   // <<, >>
    Additive       = 12,   // -, +
    Multiplicative = 13    // *, /, %
  };
}


/// getBinOpPrecedence - Return the precedence of the specified binary operator
/// token.  This returns:
///
static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
  switch (Kind) {
  default:                        return prec::Unknown;
  case tok::comma:                return prec::Comma;
  case tok::equal:
  case tok::starequal:
  case tok::slashequal:
  case tok::percentequal:
  case tok::plusequal:
  case tok::minusequal:
  case tok::lesslessequal:
  case tok::greatergreaterequal:
  case tok::ampequal:
  case tok::caretequal:
  case tok::pipeequal:            return prec::Assignment;
  case tok::question:             return prec::Conditional;
  case tok::pipepipe:             return prec::LogicalOr;
  case tok::ampamp:               return prec::LogicalAnd;
  case tok::pipe:                 return prec::InclusiveOr;
  case tok::caret:                return prec::ExclusiveOr;
  case tok::amp:                  return prec::And;
  case tok::exclaimequal:
  case tok::equalequal:           return prec::Equality;
  case tok::lessequal:
  case tok::less:
  case tok::greaterequal:
  case tok::greater:              return prec::Relational;
  case tok::lessless:
  case tok::greatergreater:       return prec::Shift;
  case tok::plus:
  case tok::minus:                return prec::Additive;
  case tok::percent:
  case tok::slash:
  case tok::star:                 return prec::Multiplicative;
  }
}


/// ParseExpression - Simple precedence-based parser for binary/ternary
/// operators.
///
/// Note: we diverge from the C99 grammar when parsing the assignment-expression
/// production.  C99 specifies that the LHS of an assignment operator should be
/// parsed as a unary-expression, but consistency dictates that it be a
/// conditional-expession.  In practice, the important thing here is that the
/// LHS of an assignment has to be an l-value, which productions between
/// unary-expression and conditional-expression don't produce.  Because we want
/// consistency, we parse the LHS as a conditional-expression, then check for
/// l-value-ness in semantic analysis stages.
///
///       multiplicative-expression: [C99 6.5.5]
///         cast-expression
///         multiplicative-expression '*' cast-expression
///         multiplicative-expression '/' cast-expression
///         multiplicative-expression '%' cast-expression
///
///       additive-expression: [C99 6.5.6]
///         multiplicative-expression
///         additive-expression '+' multiplicative-expression
///         additive-expression '-' multiplicative-expression
///
///       shift-expression: [C99 6.5.7]
///         additive-expression
///         shift-expression '<<' additive-expression
///         shift-expression '>>' additive-expression
///
///       relational-expression: [C99 6.5.8]
///         shift-expression
///         relational-expression '<' shift-expression
///         relational-expression '>' shift-expression
///         relational-expression '<=' shift-expression
///         relational-expression '>=' shift-expression
///
///       equality-expression: [C99 6.5.9]
///         relational-expression
///         equality-expression '==' relational-expression
///         equality-expression '!=' relational-expression
///
///       AND-expression: [C99 6.5.10]
///         equality-expression
///         AND-expression '&' equality-expression
///
///       exclusive-OR-expression: [C99 6.5.11]
///         AND-expression
///         exclusive-OR-expression '^' AND-expression
///
///       inclusive-OR-expression: [C99 6.5.12]
///         exclusive-OR-expression
///         inclusive-OR-expression '|' exclusive-OR-expression
///
///       logical-AND-expression: [C99 6.5.13]
///         inclusive-OR-expression
///         logical-AND-expression '&&' inclusive-OR-expression
///
///       logical-OR-expression: [C99 6.5.14]
///         logical-AND-expression
///         logical-OR-expression '||' logical-AND-expression
///
///       conditional-expression: [C99 6.5.15]
///         logical-OR-expression
///         logical-OR-expression '?' expression ':' conditional-expression
/// [GNU]   logical-OR-expression '?' ':' conditional-expression
///
///       assignment-expression: [C99 6.5.16]
///         conditional-expression
///         unary-expression assignment-operator assignment-expression
///
///       assignment-operator: one of
///         = *= /= %= += -= <<= >>= &= ^= |=
///
///       expression: [C99 6.5.17]
///         assignment-expression
///         expression ',' assignment-expression
///
Parser::ExprResult Parser::ParseExpression() {
  ExprResult LHS = ParseCastExpression(false);
  if (LHS.isInvalid) return LHS;
  
  return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}

/// This routine is called when the '@' is seen and consumed. 
/// Current token is an Identifier and is not a 'try'. This
/// routine is necessary to disambiguate @try-statement from,
/// for example, @encode-expression.
///
Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
  ExprResult LHS = ParseObjCAtExpression(AtLoc);
  if (LHS.isInvalid) return LHS;
 
  return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}

/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
///
Parser::ExprResult Parser::ParseAssignmentExpression() {
  ExprResult LHS = ParseCastExpression(false);
  if (LHS.isInvalid) return LHS;
  
  return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
}

Parser::ExprResult Parser::ParseConstantExpression() {
  ExprResult LHS = ParseCastExpression(false);
  if (LHS.isInvalid) return LHS;
  
  // TODO: Validate that this is a constant expr!
  return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
}

/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
/// in contexts where we have already consumed an identifier (which we saved in
/// 'IdTok'), then discovered that the identifier was really the leading token
/// of part of an expression.  For example, in "A[1]+B", we consumed "A" (which
/// is now in 'IdTok') and the current token is "[".
Parser::ExprResult Parser::
ParseExpressionWithLeadingIdentifier(const Token &IdTok) {
  // We know that 'IdTok' must correspond to this production:
  //   primary-expression: identifier
  
  // Let the actions module handle the identifier.
  ExprResult Res = Actions.ActOnIdentifierExpr(CurScope, IdTok.getLocation(),
                                               *IdTok.getIdentifierInfo(),
                                               Tok.is(tok::l_paren));
  
  // Because we have to parse an entire cast-expression before starting the
  // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
  // need to handle the 'postfix-expression' rules.  We do this by invoking
  // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
  Res = ParsePostfixExpressionSuffix(Res);
  if (Res.isInvalid) return Res;

  // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
  // done, we know we don't have to do anything for cast-expression, because the
  // only non-postfix-expression production starts with a '(' token, and we know
  // we have an identifier.  As such, we can invoke ParseRHSOfBinaryExpression
  // to consume any trailing operators (e.g. "+" in this example) and connected
  // chunks of the expression.
  return ParseRHSOfBinaryExpression(Res, prec::Comma);
}

/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
/// in contexts where we have already consumed an identifier (which we saved in
/// 'IdTok'), then discovered that the identifier was really the leading token
/// of part of an assignment-expression.  For example, in "A[1]+B", we consumed
/// "A" (which is now in 'IdTok') and the current token is "[".
Parser::ExprResult Parser::
ParseAssignmentExprWithLeadingIdentifier(const Token &IdTok) {
  // We know that 'IdTok' must correspond to this production:
  //   primary-expression: identifier
  
  // Let the actions module handle the identifier.
  ExprResult Res = Actions.ActOnIdentifierExpr(CurScope, IdTok.getLocation(),
                                               *IdTok.getIdentifierInfo(),
                                               Tok.is(tok::l_paren));
  
  // Because we have to parse an entire cast-expression before starting the
  // ParseRHSOfBinaryExpression method (which parses any trailing binops), we
  // need to handle the 'postfix-expression' rules.  We do this by invoking
  // ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
  Res = ParsePostfixExpressionSuffix(Res);
  if (Res.isInvalid) return Res;
  
  // At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
  // done, we know we don't have to do anything for cast-expression, because the
  // only non-postfix-expression production starts with a '(' token, and we know
  // we have an identifier.  As such, we can invoke ParseRHSOfBinaryExpression
  // to consume any trailing operators (e.g. "+" in this example) and connected
  // chunks of the expression.
  return ParseRHSOfBinaryExpression(Res, prec::Assignment);
}


/// ParseAssignmentExpressionWithLeadingStar - This special purpose method is
/// used in contexts where we have already consumed a '*' (which we saved in
/// 'StarTok'), then discovered that the '*' was really the leading token of an
/// expression.  For example, in "*(int*)P+B", we consumed "*" (which is
/// now in 'StarTok') and the current token is "(".
Parser::ExprResult Parser::
ParseAssignmentExpressionWithLeadingStar(const Token &StarTok) {
  // We know that 'StarTok' must correspond to this production:
  //  unary-expression: unary-operator cast-expression
  // where 'unary-operator' is '*'.
  
  // Parse the cast-expression that follows the '*'.  This will parse the
  // "*(int*)P" part of "*(int*)P+B".
  ExprResult Res = ParseCastExpression(false);
  if (Res.isInvalid) return Res;

  // Combine StarTok + Res to get the new AST for the combined expression..
  Res = Actions.ActOnUnaryOp(StarTok.getLocation(), tok::star, Res.Val);
  if (Res.isInvalid) return Res;
  
  
  // We have to parse an entire cast-expression before starting the
  // ParseRHSOfBinaryExpression method (which parses any trailing binops). Since
  // we know that the only production above us is the cast-expression
  // production, and because the only alternative productions start with a '('
  // token (we know we had a '*'), there is no work to do to get a whole
  // cast-expression.
  
  // At this point, the "*(int*)P" part of "*(int*)P+B" has been consumed. Once
  // this is done, we can invoke ParseRHSOfBinaryExpression to consume any
  // trailing operators (e.g. "+" in this example) and connected chunks of the
  // assignment-expression.
  return ParseRHSOfBinaryExpression(Res, prec::Assignment);
}


/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
/// LHS and has a precedence of at least MinPrec.
Parser::ExprResult
Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
  unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
  SourceLocation ColonLoc;

  while (1) {
    // If this token has a lower precedence than we are allowed to parse (e.g.
    // because we are called recursively, or because the token is not a binop),
    // then we are done!
    if (NextTokPrec < MinPrec)
      return LHS;

    // Consume the operator, saving the operator token for error reporting.
    Token OpToken = Tok;
    ConsumeToken();
    
    // Special case handling for the ternary operator.
    ExprResult TernaryMiddle(true);
    if (NextTokPrec == prec::Conditional) {
      if (Tok.isNot(tok::colon)) {
        // Handle this production specially:
        //   logical-OR-expression '?' expression ':' conditional-expression
        // In particular, the RHS of the '?' is 'expression', not
        // 'logical-OR-expression' as we might expect.
        TernaryMiddle = ParseExpression();
        if (TernaryMiddle.isInvalid) {
          Actions.DeleteExpr(LHS.Val);
          return TernaryMiddle;
        }
      } else {
        // Special case handling of "X ? Y : Z" where Y is empty:
        //   logical-OR-expression '?' ':' conditional-expression   [GNU]
        TernaryMiddle = ExprResult(false);
        Diag(Tok, diag::ext_gnu_conditional_expr);
      }
      
      if (Tok.isNot(tok::colon)) {
        Diag(Tok, diag::err_expected_colon);
        Diag(OpToken, diag::err_matching, "?");
        Actions.DeleteExpr(LHS.Val);
        Actions.DeleteExpr(TernaryMiddle.Val);
        return ExprResult(true);
      }
      
      // Eat the colon.
      ColonLoc = ConsumeToken();
    }
    
    // Parse another leaf here for the RHS of the operator.
    ExprResult RHS = ParseCastExpression(false);
    if (RHS.isInvalid) {
      Actions.DeleteExpr(LHS.Val);
      Actions.DeleteExpr(TernaryMiddle.Val);
      return RHS;
    }

    // Remember the precedence of this operator and get the precedence of the
    // operator immediately to the right of the RHS.
    unsigned ThisPrec = NextTokPrec;
    NextTokPrec = getBinOpPrecedence(Tok.getKind());

    // Assignment and conditional expressions are right-associative.
    bool isRightAssoc = NextTokPrec == prec::Conditional ||
                        NextTokPrec == prec::Assignment;

    // Get the precedence of the operator to the right of the RHS.  If it binds
    // more tightly with RHS than we do, evaluate it completely first.
    if (ThisPrec < NextTokPrec ||
        (ThisPrec == NextTokPrec && isRightAssoc)) {
      // If this is left-associative, only parse things on the RHS that bind
      // more tightly than the current operator.  If it is left-associative, it
      // is okay, to bind exactly as tightly.  For example, compile A=B=C=D as
      // A=(B=(C=D)), where each paren is a level of recursion here.
      RHS = ParseRHSOfBinaryExpression(RHS, ThisPrec + !isRightAssoc);
      if (RHS.isInvalid) {
        Actions.DeleteExpr(LHS.Val);
        Actions.DeleteExpr(TernaryMiddle.Val);
        return RHS;
      }

      NextTokPrec = getBinOpPrecedence(Tok.getKind());
    }
    assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
  
    if (!LHS.isInvalid) {
      // Combine the LHS and RHS into the LHS (e.g. build AST).
      if (TernaryMiddle.isInvalid)
        LHS = Actions.ActOnBinOp(OpToken.getLocation(), OpToken.getKind(),
                                 LHS.Val, RHS.Val);
      else
        LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
                                         LHS.Val, TernaryMiddle.Val, RHS.Val);
    } else {
      // We had a semantic error on the LHS.  Just free the RHS and continue.
      Actions.DeleteExpr(TernaryMiddle.Val);
      Actions.DeleteExpr(RHS.Val);
    }
  }
}

/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
/// true, parse a unary-expression.
///
///       cast-expression: [C99 6.5.4]
///         unary-expression
///         '(' type-name ')' cast-expression
///
///       unary-expression:  [C99 6.5.3]
///         postfix-expression
///         '++' unary-expression
///         '--' unary-expression
///         unary-operator cast-expression
///         'sizeof' unary-expression
///         'sizeof' '(' type-name ')'
/// [GNU]   '__alignof' unary-expression
/// [GNU]   '__alignof' '(' type-name ')'
/// [GNU]   '&&' identifier
///
///       unary-operator: one of
///         '&'  '*'  '+'  '-'  '~'  '!'
/// [GNU]   '__extension__'  '__real'  '__imag'
///
///       primary-expression: [C99 6.5.1]
///         identifier
///         constant
///         string-literal
/// [C++]   boolean-literal  [C++ 2.13.5]
///         '(' expression ')'
///         '__func__'        [C99 6.4.2.2]
/// [GNU]   '__FUNCTION__'
/// [GNU]   '__PRETTY_FUNCTION__'
/// [GNU]   '(' compound-statement ')'
/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
///                                     assign-expr ')'
/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
/// [OBJC]  '[' objc-message-expr ']'    
/// [OBJC]  '@selector' '(' objc-selector-arg ')'      [TODO]
/// [OBJC]  '@protocol' '(' identifier ')'             
/// [OBJC]  '@encode' '(' type-name ')'                
/// [OBJC]  objc-string-literal
/// [C++]   'const_cast' '<' type-name '>' '(' expression ')'       [C++ 5.2p1]
/// [C++]   'dynamic_cast' '<' type-name '>' '(' expression ')'     [C++ 5.2p1]
/// [C++]   'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++]   'static_cast' '<' type-name '>' '(' expression ')'      [C++ 5.2p1]
///
///       constant: [C99 6.4.4]
///         integer-constant
///         floating-constant
///         enumeration-constant -> identifier
///         character-constant
///
Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
  ExprResult Res;
  tok::TokenKind SavedKind = Tok.getKind();
  
  // This handles all of cast-expression, unary-expression, postfix-expression,
  // and primary-expression.  We handle them together like this for efficiency
  // and to simplify handling of an expression starting with a '(' token: which
  // may be one of a parenthesized expression, cast-expression, compound literal
  // expression, or statement expression.
  //
  // If the parsed tokens consist of a primary-expression, the cases below
  // call ParsePostfixExpressionSuffix to handle the postfix expression
  // suffixes.  Cases that cannot be followed by postfix exprs should
  // return without invoking ParsePostfixExpressionSuffix.
  switch (SavedKind) {
  case tok::l_paren: {
    // If this expression is limited to being a unary-expression, the parent can
    // not start a cast expression.
    ParenParseOption ParenExprType =
      isUnaryExpression ? CompoundLiteral : CastExpr;
    TypeTy *CastTy;
    SourceLocation LParenLoc = Tok.getLocation();
    SourceLocation RParenLoc;
    Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
    if (Res.isInvalid) return Res;
    
    switch (ParenExprType) {
    case SimpleExpr:   break;    // Nothing else to do.
    case CompoundStmt: break;  // Nothing else to do.
    case CompoundLiteral:
      // We parsed '(' type-name ')' '{' ... '}'.  If any suffixes of
      // postfix-expression exist, parse them now.
      break;
    case CastExpr:
      // We parsed '(' type-name ')' and the thing after it wasn't a '{'.  Parse
      // the cast-expression that follows it next.
      // TODO: For cast expression with CastTy.
      Res = ParseCastExpression(false);
      if (!Res.isInvalid)
        Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.Val);
      return Res;
    }
      
    // These can be followed by postfix-expr pieces.
    return ParsePostfixExpressionSuffix(Res);
  }
    
    // primary-expression
  case tok::numeric_constant:
    // constant: integer-constant
    // constant: floating-constant
    
    Res = Actions.ActOnNumericConstant(Tok);
    ConsumeToken();
    
    // These can be followed by postfix-expr pieces.
    return ParsePostfixExpressionSuffix(Res);

  case tok::kw_true:
  case tok::kw_false:
    return ParseCXXBoolLiteral();

  case tok::identifier: {      // primary-expression: identifier
                               // constant: enumeration-constant
    // Consume the identifier so that we can see if it is followed by a '('.
    // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
    // need to know whether or not this identifier is a function designator or
    // not.
    IdentifierInfo &II = *Tok.getIdentifierInfo();
    SourceLocation L = ConsumeToken();
    Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
    // These can be followed by postfix-expr pieces.
    return ParsePostfixExpressionSuffix(Res);
  }
  case tok::char_constant:     // constant: character-constant
    Res = Actions.ActOnCharacterConstant(Tok);
    ConsumeToken();
    // These can be followed by postfix-expr pieces.
    return ParsePostfixExpressionSuffix(Res);    
  case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
  case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
  case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
    Res = Actions.ActOnPreDefinedExpr(Tok.getLocation(), SavedKind);
    ConsumeToken();
    // These can be followed by postfix-expr pieces.
    return ParsePostfixExpressionSuffix(Res);
  case tok::string_literal:    // primary-expression: string-literal
  case tok::wide_string_literal:
    Res = ParseStringLiteralExpression();
    if (Res.isInvalid) return Res;
    // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
    return ParsePostfixExpressionSuffix(Res);
  case tok::kw___builtin_va_arg:
  case tok::kw___builtin_offsetof:
  case tok::kw___builtin_choose_expr:
  case tok::kw___builtin_types_compatible_p:
    return ParseBuiltinPrimaryExpression();
  case tok::plusplus:      // unary-expression: '++' unary-expression
  case tok::minusminus: {  // unary-expression: '--' unary-expression
    SourceLocation SavedLoc = ConsumeToken();
    Res = ParseCastExpression(true);
    if (!Res.isInvalid)
      Res = Actions.ActOnUnaryOp(SavedLoc, SavedKind, Res.Val);
    return Res;
  }
  case tok::amp:           // unary-expression: '&' cast-expression
  case tok::star:          // unary-expression: '*' cast-expression
  case tok::plus:          // unary-expression: '+' cast-expression
  case tok::minus:         // unary-expression: '-' cast-expression
  case tok::tilde:         // unary-expression: '~' cast-expression
  case tok::exclaim:       // unary-expression: '!' cast-expression
  case tok::kw___real:     // unary-expression: '__real' cast-expression [GNU]
  case tok::kw___imag:     // unary-expression: '__imag' cast-expression [GNU]
  case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
    // FIXME: Extension should silence extwarns in subexpressions.
    SourceLocation SavedLoc = ConsumeToken();
    Res = ParseCastExpression(false);
    if (!Res.isInvalid)
      Res = Actions.ActOnUnaryOp(SavedLoc, SavedKind, Res.Val);
    return Res;
  }
  case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
                           // unary-expression: 'sizeof' '(' type-name ')'
  case tok::kw___alignof:  // unary-expression: '__alignof' unary-expression
                           // unary-expression: '__alignof' '(' type-name ')'
    return ParseSizeofAlignofExpression();
  case tok::ampamp: {      // unary-expression: '&&' identifier
    SourceLocation AmpAmpLoc = ConsumeToken();
    if (Tok.isNot(tok::identifier)) {
      Diag(Tok, diag::err_expected_ident);
      return ExprResult(true);
    }
    
    Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
    Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
                                 Tok.getIdentifierInfo());
    ConsumeToken();
    return Res;
  }
  case tok::kw_const_cast:
  case tok::kw_dynamic_cast:
  case tok::kw_reinterpret_cast:
  case tok::kw_static_cast:
    return ParseCXXCasts();
  case tok::at: {
    SourceLocation AtLoc = ConsumeToken();
    return ParseObjCAtExpression(AtLoc);
  }
  case tok::l_square:
    // These can be followed by postfix-expr pieces.
    return ParsePostfixExpressionSuffix(ParseObjCMessageExpression());
  default:
    Diag(Tok, diag::err_expected_expression);
    return ExprResult(true);
  }
  
  // unreachable.
  abort();
}

/// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression
/// is parsed, this method parses any suffixes that apply.
///
///       postfix-expression: [C99 6.5.2]
///         primary-expression
///         postfix-expression '[' expression ']'
///         postfix-expression '(' argument-expression-list[opt] ')'
///         postfix-expression '.' identifier
///         postfix-expression '->' identifier
///         postfix-expression '++'
///         postfix-expression '--'
///         '(' type-name ')' '{' initializer-list '}'
///         '(' type-name ')' '{' initializer-list ',' '}'
///
///       argument-expression-list: [C99 6.5.2]
///         argument-expression
///         argument-expression-list ',' assignment-expression
///
Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
  
  // Now that the primary-expression piece of the postfix-expression has been
  // parsed, see if there are any postfix-expression pieces here.
  SourceLocation Loc;
  while (1) {
    switch (Tok.getKind()) {
    default:  // Not a postfix-expression suffix.
      return LHS;
    case tok::l_square: {  // postfix-expression: p-e '[' expression ']'
      Loc = ConsumeBracket();
      ExprResult Idx = ParseExpression();
      
      SourceLocation RLoc = Tok.getLocation();
      
      if (!LHS.isInvalid && !Idx.isInvalid && Tok.is(tok::r_square))
        LHS = Actions.ActOnArraySubscriptExpr(LHS.Val, Loc, Idx.Val, RLoc);
      else 
        LHS = ExprResult(true);

      // Match the ']'.
      MatchRHSPunctuation(tok::r_square, Loc);
      break;
    }
      
    case tok::l_paren: {   // p-e: p-e '(' argument-expression-list[opt] ')'
      llvm::SmallVector<ExprTy*, 8> ArgExprs;
      llvm::SmallVector<SourceLocation, 8> CommaLocs;
      
      Loc = ConsumeParen();
      
      if (Tok.isNot(tok::r_paren)) {
        while (1) {
          ExprResult ArgExpr = ParseAssignmentExpression();
          if (ArgExpr.isInvalid) {
            SkipUntil(tok::r_paren);
            return ExprResult(true);
          } else
            ArgExprs.push_back(ArgExpr.Val);
          
          if (Tok.isNot(tok::comma))
            break;
          // Move to the next argument, remember where the comma was.
          CommaLocs.push_back(ConsumeToken());
        }
      }
        
      // Match the ')'.
      if (!LHS.isInvalid && Tok.is(tok::r_paren)) {
        assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
               "Unexpected number of commas!");
        LHS = Actions.ActOnCallExpr(LHS.Val, Loc, &ArgExprs[0], ArgExprs.size(),
                                    &CommaLocs[0], Tok.getLocation());
      }
      
      MatchRHSPunctuation(tok::r_paren, Loc);
      break;
    }
    case tok::arrow:       // postfix-expression: p-e '->' identifier
    case tok::period: {    // postfix-expression: p-e '.' identifier
      tok::TokenKind OpKind = Tok.getKind();
      SourceLocation OpLoc = ConsumeToken();  // Eat the "." or "->" token.
      
      if (Tok.isNot(tok::identifier)) {
        Diag(Tok, diag::err_expected_ident);
        return ExprResult(true);
      }
      
      if (!LHS.isInvalid)
        LHS = Actions.ActOnMemberReferenceExpr(LHS.Val, OpLoc, OpKind,
                                               Tok.getLocation(),
                                               *Tok.getIdentifierInfo());
      ConsumeToken();
      break;
    }
    case tok::plusplus:    // postfix-expression: postfix-expression '++'
    case tok::minusminus:  // postfix-expression: postfix-expression '--'
      if (!LHS.isInvalid)
        LHS = Actions.ActOnPostfixUnaryOp(Tok.getLocation(), Tok.getKind(),
                                          LHS.Val);
      ConsumeToken();
      break;
    }
  }
}


/// ParseSizeofAlignofExpression - Parse a sizeof or alignof expression.
///       unary-expression:  [C99 6.5.3]
///         'sizeof' unary-expression
///         'sizeof' '(' type-name ')'
/// [GNU]   '__alignof' unary-expression
/// [GNU]   '__alignof' '(' type-name ')'
Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
  assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)) &&
         "Not a sizeof/alignof expression!");
  Token OpTok = Tok;
  ConsumeToken();
  
  // If the operand doesn't start with an '(', it must be an expression.
  ExprResult Operand;
  if (Tok.isNot(tok::l_paren)) {
    Operand = ParseCastExpression(true);
  } else {
    // If it starts with a '(', we know that it is either a parenthesized
    // type-name, or it is a unary-expression that starts with a compound
    // literal, or starts with a primary-expression that is a parenthesized
    // expression.
    ParenParseOption ExprType = CastExpr;
    TypeTy *CastTy;
    SourceLocation LParenLoc = Tok.getLocation(), RParenLoc;
    Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
    
    // If ParseParenExpression parsed a '(typename)' sequence only, the this is
    // sizeof/alignof a type.  Otherwise, it is sizeof/alignof an expression.
    if (ExprType == CastExpr)
      return Actions.ActOnSizeOfAlignOfTypeExpr(OpTok.getLocation(),
                                                OpTok.is(tok::kw_sizeof),
                                                LParenLoc, CastTy, RParenLoc);
    
    // If this is a parenthesized expression, it is the start of a 
    // unary-expression, but doesn't include any postfix pieces.  Parse these
    // now if present.
    Operand = ParsePostfixExpressionSuffix(Operand);
  }
  
  // If we get here, the operand to the sizeof/alignof was an expresion.
  if (!Operand.isInvalid)
    Operand = Actions.ActOnUnaryOp(OpTok.getLocation(), OpTok.getKind(),
                                   Operand.Val);
  return Operand;
}

/// ParseBuiltinPrimaryExpression
///
///       primary-expression: [C99 6.5.1]
/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
///                                     assign-expr ')'
/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
/// 
/// [GNU] offsetof-member-designator:
/// [GNU]   identifier
/// [GNU]   offsetof-member-designator '.' identifier
/// [GNU]   offsetof-member-designator '[' expression ']'
///
Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
  ExprResult Res(false);
  const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();

  tok::TokenKind T = Tok.getKind();
  SourceLocation StartLoc = ConsumeToken();   // Eat the builtin identifier.

  // All of these start with an open paren.
  if (Tok.isNot(tok::l_paren)) {
    Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
    return ExprResult(true);
  }
  
  SourceLocation LParenLoc = ConsumeParen();
  // TODO: Build AST.

  switch (T) {
  default: assert(0 && "Not a builtin primary expression!");
  case tok::kw___builtin_va_arg: {
    ExprResult Expr = ParseAssignmentExpression();
    if (Expr.isInvalid) {
      SkipUntil(tok::r_paren);
      return Res;
    }

    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
      return ExprResult(true);

    TypeTy *Ty = ParseTypeName();
    
    if (Tok.isNot(tok::r_paren)) {
      Diag(Tok, diag::err_expected_rparen);
      return ExprResult(true);
    }
    Res = Actions.ActOnVAArg(StartLoc, Expr.Val, Ty, ConsumeParen());
    break;
  }
  case tok::kw___builtin_offsetof: {
    SourceLocation TypeLoc = Tok.getLocation();
    TypeTy *Ty = ParseTypeName();

    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
      return ExprResult(true);
    
    // We must have at least one identifier here.
    if (Tok.isNot(tok::identifier)) {
      Diag(Tok, diag::err_expected_ident);
      SkipUntil(tok::r_paren);
      return true;
    }
    
    // Keep track of the various subcomponents we see.
    llvm::SmallVector<Action::OffsetOfComponent, 4> Comps;
    
    Comps.push_back(Action::OffsetOfComponent());
    Comps.back().isBrackets = false;
    Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
    Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();

    while (1) {
      if (Tok.is(tok::period)) {
        // offsetof-member-designator: offsetof-member-designator '.' identifier
        Comps.push_back(Action::OffsetOfComponent());
        Comps.back().isBrackets = false;
        Comps.back().LocStart = ConsumeToken();
        
        if (Tok.isNot(tok::identifier)) {
          Diag(Tok, diag::err_expected_ident);
          SkipUntil(tok::r_paren);
          return true;
        }
        Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
        Comps.back().LocEnd = ConsumeToken();
        
      } else if (Tok.is(tok::l_square)) {
        // offsetof-member-designator: offsetof-member-design '[' expression ']'
        Comps.push_back(Action::OffsetOfComponent());
        Comps.back().isBrackets = true;
        Comps.back().LocStart = ConsumeBracket();
        Res = ParseExpression();
        if (Res.isInvalid) {
          SkipUntil(tok::r_paren);
          return Res;
        }
        Comps.back().U.E = Res.Val;

        Comps.back().LocEnd =
          MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
      } else if (Tok.is(tok::r_paren)) {
        Res = Actions.ActOnBuiltinOffsetOf(StartLoc, TypeLoc, Ty, &Comps[0],
                                           Comps.size(), ConsumeParen());
        break;
      } else {
        // Error occurred.
        return ExprResult(true);
      }
    }
    break;
  }
  case tok::kw___builtin_choose_expr: {
    ExprResult Cond = ParseAssignmentExpression();
    if (Cond.isInvalid) {
      SkipUntil(tok::r_paren);
      return Cond;
    }
    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
      return ExprResult(true);
    
    ExprResult Expr1 = ParseAssignmentExpression();
    if (Expr1.isInvalid) {
      SkipUntil(tok::r_paren);
      return Expr1;
    }    
    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
      return ExprResult(true);
    
    ExprResult Expr2 = ParseAssignmentExpression();
    if (Expr2.isInvalid) {
      SkipUntil(tok::r_paren);
      return Expr2;
    }    
    if (Tok.isNot(tok::r_paren)) {
      Diag(Tok, diag::err_expected_rparen);
      return ExprResult(true);
    }
    Res = Actions.ActOnChooseExpr(StartLoc, Cond.Val, Expr1.Val, Expr2.Val,
                                  ConsumeParen());
    break;
  }
  case tok::kw___builtin_types_compatible_p:
    TypeTy *Ty1 = ParseTypeName();
    
    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
      return ExprResult(true);
    
    TypeTy *Ty2 = ParseTypeName();
    
    if (Tok.isNot(tok::r_paren)) {
      Diag(Tok, diag::err_expected_rparen);
      return ExprResult(true);
    }
    Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1, Ty2, ConsumeParen());
    break;
  }      
  
  // These can be followed by postfix-expr pieces because they are
  // primary-expressions.
  return ParsePostfixExpressionSuffix(Res);
}

/// ParseParenExpression - This parses the unit that starts with a '(' token,
/// based on what is allowed by ExprType.  The actual thing parsed is returned
/// in ExprType.
///
///       primary-expression: [C99 6.5.1]
///         '(' expression ')'
/// [GNU]   '(' compound-statement ')'      (if !ParenExprOnly)
///       postfix-expression: [C99 6.5.2]
///         '(' type-name ')' '{' initializer-list '}'
///         '(' type-name ')' '{' initializer-list ',' '}'
///       cast-expression: [C99 6.5.4]
///         '(' type-name ')' cast-expression
///
Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
                                                TypeTy *&CastTy,
                                                SourceLocation &RParenLoc) {
  assert(Tok.is(tok::l_paren) && "Not a paren expr!");
  SourceLocation OpenLoc = ConsumeParen();
  ExprResult Result(true);
  CastTy = 0;
  
  if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
    Diag(Tok, diag::ext_gnu_statement_expr);
    Parser::StmtResult Stmt = ParseCompoundStatement(true);
    ExprType = CompoundStmt;
    
    // If the substmt parsed correctly, build the AST node.
    if (!Stmt.isInvalid && Tok.is(tok::r_paren))
      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.Val, Tok.getLocation());
    
  } else if (ExprType >= CompoundLiteral && isTypeSpecifierQualifier()) {
    // Otherwise, this is a compound literal expression or cast expression.
    TypeTy *Ty = ParseTypeName();

    // Match the ')'.
    if (Tok.is(tok::r_paren))
      RParenLoc = ConsumeParen();
    else
      MatchRHSPunctuation(tok::r_paren, OpenLoc);
    
    if (Tok.is(tok::l_brace)) {
      if (!getLang().C99)   // Compound literals don't exist in C90.
        Diag(OpenLoc, diag::ext_c99_compound_literal);
      Result = ParseInitializer();
      ExprType = CompoundLiteral;
      if (!Result.isInvalid)
        return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val);
    } else if (ExprType == CastExpr) {
      // Note that this doesn't parse the subsequence cast-expression, it just
      // returns the parsed type to the callee.
      ExprType = CastExpr;
      CastTy = Ty;
      return ExprResult(false);
    } else {
      Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
      return ExprResult(true);
    }
    return Result;
  } else {
    Result = ParseExpression();
    ExprType = SimpleExpr;
    if (!Result.isInvalid && Tok.is(tok::r_paren))
      Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.Val);
  }
  
  // Match the ')'.
  if (Result.isInvalid)
    SkipUntil(tok::r_paren);
  else {
    if (Tok.is(tok::r_paren))
      RParenLoc = ConsumeParen();
    else
      MatchRHSPunctuation(tok::r_paren, OpenLoc);
  }
  
  return Result;
}

/// ParseStringLiteralExpression - This handles the various token types that
/// form string literals, and also handles string concatenation [C99 5.1.1.2,
/// translation phase #6].
///
///       primary-expression: [C99 6.5.1]
///         string-literal
Parser::ExprResult Parser::ParseStringLiteralExpression() {
  assert(isTokenStringLiteral() && "Not a string literal!");
  
  // String concat.  Note that keywords like __func__ and __FUNCTION__ are not
  // considered to be strings for concatenation purposes.
  llvm::SmallVector<Token, 4> StringToks;
  
  do {
    StringToks.push_back(Tok);
    ConsumeStringToken();
  } while (isTokenStringLiteral());

  // Pass the set of string tokens, ready for concatenation, to the actions.
  return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size());
}
