Ejemplo n.º 1
0
Parser::StmtResult Parser::ParseGotoStmt() {
  SourceLocation Loc = ConsumeToken();
  if(ConsumeIfPresent(tok::l_paren)) {
    // computed goto.
    SmallVector<Expr*, 4> Targets;
    do {
      auto E = ParseStatementLabelReference();
      if(E.isInvalid()) break;
      Targets.append(1, E.get());
    } while(ConsumeIfPresent(tok::comma));
    ExprResult Operand;
    bool ParseOperand = true;
    if(!ExpectAndConsume(tok::r_paren)) {
      if(!SkipUntil(tok::r_paren)) ParseOperand = false;
    }
    if(ParseOperand) Operand = ParseExpectedExpression();
    return Actions.ActOnComputedGotoStmt(Context, Loc, Targets, Operand, StmtLabel);
  }

  auto Destination = ParseStatementLabelReference();
  if(Destination.isInvalid()) {
    if(!IsPresent(tok::identifier)) {
      Diag.Report(getExpectedLoc(), diag::err_expected_stmt_label_after)
          << "GO TO";
      return StmtError();
    }
    auto IDInfo = Tok.getIdentifierInfo();
    auto IDLoc = ConsumeToken();
    auto VD = Actions.ExpectVarRef(IDLoc, IDInfo);
    if(!VD) return StmtError();
    auto Var = VarExpr::Create(Context, IDLoc, VD);

    // Assigned goto
    SmallVector<Expr*, 4> AllowedValues;
    if(ConsumeIfPresent(tok::l_paren)) {
      do {
        auto E = ParseStatementLabelReference();
        if(E.isInvalid()) {
          Diag.Report(getExpectedLoc(), diag::err_expected_stmt_label);
          SkipUntilNextStatement();
          return Actions.ActOnAssignedGotoStmt(Context, Loc, Var, AllowedValues, StmtLabel);
        }
        AllowedValues.append(1, E.get());
      } while(ConsumeIfPresent(tok::comma));
      ExpectAndConsume(tok::r_paren);
    }
    return Actions.ActOnAssignedGotoStmt(Context, Loc, Var, AllowedValues, StmtLabel);
  }
  // Uncoditional goto
  return Actions.ActOnGotoStmt(Context, Loc, Destination, StmtLabel);
}
Ejemplo n.º 2
0
ExprResult Parser::ParseExpectedExpression() {
  if(Tok.isAtStartOfStatement()) {
    Diag.Report(getExpectedLoc(), diag::err_expected_expression);
    return ExprError();
  }
  return ParseExpression();
}
Ejemplo n.º 3
0
Parser::StmtResult Parser::ParseAssignStmt() {
  SourceLocation Loc = ConsumeToken();

  auto Value = ParseStatementLabelReference(false);
  if(Value.isInvalid()) {
    Diag.Report(getExpectedLoc(), diag::err_expected_stmt_label_after)
        << "ASSIGN";
    return StmtError();
  }
  ConsumeToken();
  if(!ExpectAndConsumeFixedFormAmbiguous(tok::kw_TO, diag::err_expected_kw, "to"))
    return StmtError();

  auto IDInfo = Tok.getIdentifierInfo();
  auto IDRange = getTokenRange();
  auto IDLoc = Tok.getLocation();
  if(!ExpectAndConsume(tok::identifier))
    return StmtError();
  auto VD = Actions.ExpectVarRefOrDeclImplicitVar(IDLoc, IDInfo);
  if(!VD)
    return StmtError();
  auto Var = VarExpr::Create(Context, IDRange, VD);

  return Actions.ActOnAssignStmt(Context, Loc, Value, Var, StmtLabel);
}
Ejemplo n.º 4
0
/// \brief Looks at the next token to see if it's an expression
/// and calls ParseExpression if it is, or reports an expected expression
/// error.
ExprResult Parser::ParseExpectedFollowupExpression(const char *DiagAfter) {
  if(Tok.isAtStartOfStatement()) {
    Diag.Report(getExpectedLoc(), diag::err_expected_expression_after)
      << DiagAfter;
    return ExprError();
  }
  return ParseExpression();
}
Ejemplo n.º 5
0
bool Parser::ParseObjectCharLength(SourceLocation Loc, DeclSpec &DS) {
  if(DS.getTypeSpecType() == TST_character && ConsumeIfPresent(tok::star)) {
    if (DS.hasLengthSelector())
      Diag.Report(getExpectedLoc(), diag::err_duplicate_len_selector);
    return ParseCharacterStarLengthSpec(DS);
  }
  return false;
}
Ejemplo n.º 6
0
/// ParseFunctionCallArgumentList - Parses an argument list to a call expression.
ExprResult Parser::ParseFunctionCallArgumentList(SmallVectorImpl<Expr*> &Args, SourceLocation &RParenLoc) {
  if(!ExpectAndConsume(tok::l_paren))
    return ExprError();

  RParenLoc = getExpectedLoc();
  if(ConsumeIfPresent(tok::r_paren))
    return ExprResult();

  auto PunctuationTok = "(";
  do {
    if(Tok.isAtStartOfStatement())
      break;
    auto E = ParseExpectedFollowupExpression(PunctuationTok);
    if(E.isInvalid())
      SkipUntil(tok::comma, tok::r_paren, true, true);
    else Args.push_back(E.get());
    PunctuationTok = ",";
  } while (ConsumeIfPresent(tok::comma));

  RParenLoc = getExpectedLoc();
  ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);
  return ExprResult();
}
Ejemplo n.º 7
0
/// ParseAssignmentStmt
///   [R732]:
///     assignment-stmt :=
///         variable = expr
Parser::StmtResult Parser::ParseAssignmentStmt() {
  ExprResult LHS = ParsePrimaryExpr(true);
  if(LHS.isInvalid()) return StmtError();

  SourceLocation Loc = Tok.getLocation();
  if(!ConsumeIfPresent(tok::equal)) {
    Diag.Report(getExpectedLoc(),diag::err_expected_equal);
    return StmtError();
  }

  ExprResult RHS = ParseExpectedFollowupExpression("=");
  if(RHS.isInvalid()) return StmtError();
  return Actions.ActOnAssignmentStmt(Context, Loc, LHS, RHS, StmtLabel);
}
Ejemplo n.º 8
0
Parser::StmtResult Parser::ParseCallStmt() {
  auto Loc = ConsumeToken();
  SourceLocation RParenLoc = getExpectedLoc();

  auto ID = Tok.getIdentifierInfo();
  auto IDLoc = Tok.getLocation();
  if(!ExpectAndConsume(tok::identifier))
    return StmtError();

  SmallVector<Expr*, 8> Arguments;
  if(!Tok.isAtStartOfStatement()) {
    if(ParseFunctionCallArgumentList(Arguments, RParenLoc).isInvalid())
      SkipUntilNextStatement();
  }

  return Actions.ActOnCallStmt(Context, Loc, RParenLoc, IDLoc, ID, Arguments, StmtLabel);
}
Ejemplo n.º 9
0
/// ParseArrauSubscript - Parse an Array Subscript Expression
ExprResult Parser::ParseArraySubscript(ExprResult Target) {
  SmallVector<Expr*, 8> ExprList;
  auto Loc = ConsumeParen();

  bool IgnoreRParen = false;
  auto PunctuationTok = "(";
  do {
    if(Tok.isAtStartOfStatement())
      IgnoreRParen = true;
    auto E = ParseArraySection(PunctuationTok);
    if(E.isInvalid())
      SkipUntil(tok::comma, tok::r_paren, true, true);
    if(E.isUsable())
      ExprList.push_back(E.get());
    PunctuationTok = ",";
  } while(ConsumeIfPresent(tok::comma));

  auto RParenLoc = getExpectedLoc();
  if(!IgnoreRParen)
    ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);

  return Actions.ActOnSubscriptExpr(Context, Loc, RParenLoc, Target.get(),
                                    ExprList);
}
Ejemplo n.º 10
0
Parser::StmtResult Parser::ParseIfStmt() {
  auto Loc = ConsumeToken();

  ExprResult Condition;
  if (!ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "IF"))
    goto error;
  Condition = ParseExpectedFollowupExpression("(");
  if(Condition.isInvalid()) {
    if(!SkipUntil(tok::r_paren, true, true))
      goto error;
  }
  if (!ExpectAndConsume(tok::r_paren)) goto error;

  if(Features.FixedForm && !Tok.isAtStartOfStatement())
    ReLexAmbiguousIdentifier(FixedFormAmbiguities.getMatcherForKeywordsAfterIF());
  if (!ConsumeIfPresent(tok::kw_THEN)) {
    // if-stmt
    if(Tok.isAtStartOfStatement()) {
      Diag.Report(getExpectedLoc(), diag::err_expected_executable_stmt);
      return StmtError();
    }
    auto Result = Actions.ActOnIfStmt(Context, Loc, Condition, StmtConstructName, StmtLabel);
    if(Result.isInvalid()) return Result;
    // NB: Don't give the action stmt my label
    StmtLabel = nullptr;
    auto Action = ParseActionStmt();
    Actions.ActOnEndIfStmt(Context, Loc, ConstructName(SourceLocation(), nullptr), nullptr);
    return Action.isInvalid()? StmtError() : Result;
  }

  // if-construct.
  return Actions.ActOnIfStmt(Context, Loc, Condition, StmtConstructName, StmtLabel);
error:
  SkipUntilNextStatement();
  return Actions.ActOnIfStmt(Context, Loc, Condition, StmtConstructName, StmtLabel);
}
Ejemplo n.º 11
0
// ParsePrimaryExpr - Parse a primary expression.
//
//   [R701]:
//     primary :=
//         constant
//      or designator
//      or array-constructor
//      or structure-constructor
//      or function-reference
//      or type-param-inquiry
//      or type-param-name
//      or ( expr )
Parser::ExprResult Parser::ParsePrimaryExpr(bool IsLvalue) {
  ExprResult E;
  SourceLocation Loc = Tok.getLocation();

  // FIXME: Add rest of the primary expressions.
  switch (Tok.getKind()) {
  default:
    if (isTokenIdentifier())
      goto possible_keyword_as_ident;
    Diag.Report(getExpectedLoc(), diag::err_expected_expression);
    return ExprError();
  case tok::error:
    Lex();
    return ExprError();
  case tok::l_paren: {
    ConsumeParen();

    E = ParseExpression();
    // complex constant.
    if(ConsumeIfPresent(tok::comma)) {
      if(E.isInvalid()) return E;
      auto ImPart = ParseExpectedFollowupExpression(",");
      if(ImPart.isInvalid()) return ImPart;
      E = Actions.ActOnComplexConstantExpr(Context, Loc,
                                           getMaxLocationOfCurrentToken(),
                                           E, ImPart);
    }

    ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);
    break;
  }
  case tok::l_parenslash : {
    return ParseArrayConstructor();
    break;
  }
  case tok::logical_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = LogicalConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first, Context.LogicalTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::binary_boz_constant:
  case tok::octal_boz_constant:
  case tok::hex_boz_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = BOZConstantExpr::Create(Context, Loc,
                                getMaxLocationOfCurrentToken(),
                                StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::char_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    E = CharacterConstantExpr::Create(Context, getTokenRange(),
                                      StringRef(NumStr), Context.CharacterTy);
    ConsumeToken();
    // Possible substring
    if(IsPresent(tok::l_paren))
      return ParseSubstring(E);
    break;
  }
  case tok::int_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = IntegerConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);

    Lex();
    break;
  }
  case tok::real_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.RealTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::double_precision_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    // Replace the d/D exponent into e exponent
    for(size_t I = 0, Len = NumStr.length(); I < Len; ++I) {
      if(NumStr[I] == 'd' || NumStr[I] == 'D') {
        NumStr[I] = 'e';
        break;
      } else if(NumStr[I] == '_') break;
    }

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.DoublePrecisionTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::identifier:
    possible_keyword_as_ident:
    E = Parser::ParseDesignator(IsLvalue);
    if (E.isInvalid()) return E;
    break;
  case tok::minus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Minus, E);
    break;
  case tok::plus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Plus, E);
    break;
  }

  return E;
}