//===--- ParseInit.cpp - Initializer Parsing ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements initializer parsing as specified by C99 6.7.8.
//
//===----------------------------------------------------------------------===//

#include "clang/Parse/Designator.h"
#include "clang/Parse/Parser.h"
#include "AstGuard.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "llvm/ADT/SmallString.h"
using namespace clang;


/// MayBeDesignationStart - Return true if this token might be the start of a
/// designator.  If we can tell it is impossible that it is a designator, return
/// false. 
static bool MayBeDesignationStart(tok::TokenKind K, Preprocessor &PP) {
  switch (K) {
  default: return false;
  case tok::period:      // designator: '.' identifier
  case tok::l_square:    // designator: array-designator
      return true;
  case tok::identifier:  // designation: identifier ':'
    return PP.LookAhead(0).is(tok::colon);
  }
}

/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
/// checking to see if the token stream starts with a designator.
///
///       designation:
///         designator-list '='
/// [GNU]   array-designator
/// [GNU]   identifier ':'
///
///       designator-list:
///         designator
///         designator-list designator
///
///       designator:
///         array-designator
///         '.' identifier
///
///       array-designator:
///         '[' constant-expression ']'
/// [GNU]   '[' constant-expression '...' constant-expression ']'
///
/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
/// initializer (because it is an expression).  We need to consider this case
/// when parsing array designators.
///
Parser::OwningExprResult Parser::
ParseInitializerWithPotentialDesignator(InitListDesignations &Designations,
                                        unsigned InitNum) {

  // If this is the old-style GNU extension:
  //   designation ::= identifier ':'
  // Handle it as a field designator.  Otherwise, this must be the start of a
  // normal expression.
  if (Tok.is(tok::identifier)) {
    Diag(Tok, diag::ext_gnu_old_style_field_designator);
    
    const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
    SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
    
    assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
    SourceLocation ColonLoc = ConsumeToken();

    Designation &D = Designations.CreateDesignation(InitNum);
    D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
    return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, 
                                              ParseInitializer());
  }
  
  // Desig - This is initialized when we see our first designator.  We may have
  // an objc message send with no designator, so we don't want to create this
  // eagerly.
  Designation *Desig = 0;
  
  // Parse each designator in the designator list until we find an initializer.
  while (Tok.is(tok::period) || Tok.is(tok::l_square)) {
    if (Tok.is(tok::period)) {
      // designator: '.' identifier
      SourceLocation DotLoc = ConsumeToken();
      
      // Create designation if we haven't already.
      if (Desig == 0)
        Desig = &Designations.CreateDesignation(InitNum);
      
      if (Tok.isNot(tok::identifier)) {
        Diag(Tok.getLocation(), diag::err_expected_field_designator);
        return ExprError();
      }
      
      Desig->AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc,
                                                Tok.getLocation()));
      ConsumeToken(); // Eat the identifier.
      continue;
    }
    
    // We must have either an array designator now or an objc message send.
    assert(Tok.is(tok::l_square) && "Unexpected token!");
    
    // Handle the two forms of array designator:
    //   array-designator: '[' constant-expression ']'
    //   array-designator: '[' constant-expression '...' constant-expression ']'
    //
    // Also, we have to handle the case where the expression after the
    // designator an an objc message send: '[' objc-message-expr ']'.
    // Interesting cases are:
    //   [foo bar]         -> objc message send
    //   [foo]             -> array designator
    //   [foo ... bar]     -> array designator
    //   [4][foo bar]      -> obsolete GNU designation with objc message send.
    //
    SourceLocation StartLoc = ConsumeBracket();
    
    // If Objective-C is enabled and this is a typename or other identifier
    // receiver, parse this as a message send expression.
    if (getLang().ObjC1 && isTokObjCMessageIdentifierReceiver()) {
      // If we have exactly one array designator, this used the GNU
      // 'designation: array-designator' extension, otherwise there should be no
      // designators at all!
      if (Desig) {
        if (Desig->getNumDesignators() == 1 && 
            (Desig->getDesignator(0).isArrayDesignator() ||
             Desig->getDesignator(0).isArrayRangeDesignator()))
          Diag(StartLoc, diag::ext_gnu_missing_equal_designator);
        else
          Diag(Tok, diag::err_expected_equal_designator);
      }

      IdentifierInfo *Name = Tok.getIdentifierInfo();
      SourceLocation NameLoc = ConsumeToken();
      return ParseAssignmentExprWithObjCMessageExprStart(
                       StartLoc, NameLoc, Name, ExprArg(Actions));
    }

    // Note that we parse this as an assignment expression, not a constant
    // expression (allowing *=, =, etc) to handle the objc case.  Sema needs
    // to validate that the expression is a constant.
    OwningExprResult Idx(ParseAssignmentExpression());
    if (Idx.isInvalid()) {
      SkipUntil(tok::r_square);
      return move(Idx);
    }
    
    // Given an expression, we could either have a designator (if the next
    // tokens are '...' or ']' or an objc message send.  If this is an objc
    // message send, handle it now.  An objc-message send is the start of 
    // an assignment-expression production.
    if (getLang().ObjC1 && Tok.isNot(tok::ellipsis) && 
        Tok.isNot(tok::r_square)) {
      
      // If we have exactly one array designator, this used the GNU
      // 'designation: array-designator' extension, otherwise there should be no
      // designators at all!
      if (Desig) {
        if (Desig->getNumDesignators() == 1 && 
            (Desig->getDesignator(0).isArrayDesignator() ||
             Desig->getDesignator(0).isArrayRangeDesignator()))
          Diag(StartLoc, diag::ext_gnu_missing_equal_designator);
        else
          Diag(Tok, diag::err_expected_equal_designator);
      }

      return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                         SourceLocation(),
                                                         0, move(Idx));
    }

    // Create designation if we haven't already.
    if (Desig == 0)
      Desig = &Designations.CreateDesignation(InitNum);
    
    // If this is a normal array designator, remember it.
    if (Tok.isNot(tok::ellipsis)) {
      Desig->AddDesignator(Designator::getArray(Idx.release(),
                                                StartLoc));
    } else {
      // Handle the gnu array range extension.
      Diag(Tok, diag::ext_gnu_array_range);
      SourceLocation EllipsisLoc = ConsumeToken();

      OwningExprResult RHS(ParseConstantExpression());
      if (RHS.isInvalid()) {
        SkipUntil(tok::r_square);
        return move(RHS);
      }
      Desig->AddDesignator(Designator::getArrayRange(Idx.release(),
                                                     RHS.release(),
                                                     StartLoc, EllipsisLoc));
    }

    SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
    Desig->getDesignator(Desig->getNumDesignators() - 1).setRBracketLoc(EndLoc);
  }

  // Okay, we're done with the designator sequence.  We know that there must be
  // at least one designator, because the only case we can get into this method
  // without a designator is when we have an objc message send.  That case is
  // handled and returned from above.
  assert(Desig && "Designator didn't get created?");

  // Handle a normal designator sequence end, which is an equal.
  if (Tok.is(tok::equal)) {
    SourceLocation EqualLoc = ConsumeToken();
    return Actions.ActOnDesignatedInitializer(*Desig, EqualLoc, false,
                                              ParseInitializer());
  }

  // We read some number of designators and found something that isn't an = or
  // an initializer.  If we have exactly one array designator, this
  // is the GNU 'designation: array-designator' extension.  Otherwise, it is a
  // parse error.
  if (Desig->getNumDesignators() == 1 && 
      (Desig->getDesignator(0).isArrayDesignator() ||
       Desig->getDesignator(0).isArrayRangeDesignator())) {
    Diag(Tok, diag::ext_gnu_missing_equal_designator);
    return ParseInitializer();
  }

  Diag(Tok, diag::err_expected_equal_designator);
  return ExprError();
}


/// ParseBraceInitializer - Called when parsing an initializer that has a
/// leading open brace.
///
///       initializer: [C99 6.7.8]
///         '{' initializer-list '}'
///         '{' initializer-list ',' '}'
/// [GNU]   '{' '}'
///
///       initializer-list:
///         designation[opt] initializer
///         initializer-list ',' designation[opt] initializer
///
Parser::OwningExprResult Parser::ParseBraceInitializer() {
  SourceLocation LBraceLoc = ConsumeBrace();

  /// InitExprs - This is the actual list of expressions contained in the
  /// initializer.
  ExprVector InitExprs(Actions);

  /// ExprDesignators - For each initializer, keep track of the designator that
  /// was specified for it, if any.
  InitListDesignations InitExprDesignations(Actions);

  if (Tok.is(tok::r_brace)) {
    // Empty initializers are a C++ feature and a GNU extension to C.
    if (!getLang().CPlusPlus)
      Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
    // Match the '}'.
    return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions),
                                 InitExprDesignations, ConsumeBrace());
  }

  bool InitExprsOk = true;

  while (1) {
    // Parse: designation[opt] initializer

    // If we know that this cannot be a designation, just parse the nested
    // initializer directly.
    OwningExprResult SubElt(Actions);
    if (!MayBeDesignationStart(Tok.getKind(), PP))
      SubElt = ParseInitializer();
    else {
      SubElt = ParseInitializerWithPotentialDesignator(InitExprDesignations,
                                                       InitExprs.size());
      
      // If we had an erroneous initializer, and we had a potentially valid
      // designator, make sure to remove the designator from
      // InitExprDesignations, otherwise we'll end up with a designator with no
      // matching initializer.
      if (SubElt.isInvalid())
        InitExprDesignations.EraseDesignation(InitExprs.size());
    }
    
    // If we couldn't parse the subelement, bail out.
    if (!SubElt.isInvalid()) {
      InitExprs.push_back(SubElt.release());
    } else {
      InitExprsOk = false;
      
      // We have two ways to try to recover from this error: if the code looks
      // gramatically ok (i.e. we have a comma coming up) try to continue
      // parsing the rest of the initializer.  This allows us to emit
      // diagnostics for later elements that we find.  If we don't see a comma,
      // assume there is a parse error, and just skip to recover.
      // FIXME: This comment doesn't sound right. If there is a r_brace
      // immediately, it can't be an error, since there is no other way of
      // leaving this loop except through this if.
      if (Tok.isNot(tok::comma)) {
        SkipUntil(tok::r_brace, false, true);
        break;
      }
    }

    // If we don't have a comma continued list, we're done.
    if (Tok.isNot(tok::comma)) break;

    // TODO: save comma locations if some client cares.
    ConsumeToken();

    // Handle trailing comma.
    if (Tok.is(tok::r_brace)) break;
  }
  if (InitExprsOk && Tok.is(tok::r_brace))
    return Actions.ActOnInitList(LBraceLoc, move_arg(InitExprs),
                                 InitExprDesignations, ConsumeBrace());

  // Match the '}'.
  MatchRHSPunctuation(tok::r_brace, LBraceLoc);
  return ExprError(); // an error occurred.
}

