示例#1
0
bool Parser::ParseDimensionAttributeSpec(SourceLocation Loc, DeclSpec &DS) {
  SmallVector<ArraySpec*, 8> Dimensions;
  if (ParseArraySpec(Dimensions))
    return true;
  Actions.ActOnDimensionAttrSpec(Context, Loc, DS, Dimensions);
  return false;
}
示例#2
0
/// ParseCOMMONStmt - Parse the COMMON statement.
///
///   [5.5.2] R557:
///     common-stmt :=
///         COMMON #
///         # [ / [common-block-name] / ] common-block-object-list #
///         # [ [,] / [common-block-name / #
///         #   common-block-object-list ] ...
Parser::StmtResult Parser::ParseCOMMONStmt() {
  // Check if this is an assignment.
  if (IsNextToken(tok::equal))
    return StmtResult();

  auto Loc = ConsumeToken();
  SmallVector<Stmt*, 8> StmtList;
  SmallVector<Expr*, 8> ObjectList;

  SourceLocation BlockIDLoc;
  const IdentifierInfo *BlockID = nullptr;

  bool Error = false;
  do {
    if(ConsumeIfPresent(tok::slash)) {
      if(ConsumeIfPresent(tok::slash))
        BlockID = nullptr;
      else {
        BlockIDLoc = Tok.getLocation();
        BlockID = Tok.getIdentifierInfo();
        if(!ExpectAndConsume(tok::identifier)) {
          Error = true;
          break;
        }
        if(!ExpectAndConsume(tok::slash)) {
          Error = true;
          break;
        }
      }
    } else if(ConsumeIfPresent(tok::slashslash))
      BlockID = nullptr;

    auto IDLoc = Tok.getLocation();
    auto IDInfo = Tok.getIdentifierInfo();
    SmallVector<ArraySpec*, 8> Dimensions;

    if(!ExpectAndConsume(tok::identifier)) {
      Error = true;
      break;
    }
    if(IsPresent(tok::l_paren)) {
      if(ParseArraySpec(Dimensions)) {
        Error = true;
        break;
      }
    }

    Actions.ActOnCOMMON(Context, Loc, BlockIDLoc,
                        IDLoc, BlockID, IDInfo,
                        Dimensions);
  } while(ConsumeIfPresent(tok::comma));


  if(Error) SkipUntilNextStatement();
  else ExpectStatementEnd();

  return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}
示例#3
0
bool Parser::ParseObjectArraySpec(SourceLocation Loc, DeclSpec &DS) {
  if(IsPresent(tok::l_paren)) {
    SmallVector<ArraySpec*, 8> Dimensions;
    if (ParseArraySpec(Dimensions))
      return true;
    Actions.ActOnObjectArraySpec(Context, Loc, DS, Dimensions);
  }
  return false;
}
示例#4
0
/// ParseDIMENSIONStmt - Parse the DIMENSION statement.
///
///   [R535]:
///     dimension-stmt :=
///         DIMENSION [::] array-name ( array-spec ) #
///         # [ , array-name ( array-spec ) ] ...
Parser::StmtResult Parser::ParseDIMENSIONStmt() {
  // Check if this is an assignment.
  if (IsNextToken(tok::equal))
    return StmtResult();

  auto Loc = ConsumeToken();
  ConsumeIfPresent(tok::coloncolon);

  SmallVector<Stmt*, 8> StmtList;
  SmallVector<ArraySpec*, 4> Dimensions;
  while (true) {
    auto IDLoc = Tok.getLocation();
    auto II = Tok.getIdentifierInfo();
    if(!ExpectAndConsume(tok::identifier)) {
      if(!SkipUntil(tok::comma, tok::identifier, true, true)) break;
      if(ConsumeIfPresent(tok::comma)) continue;
      else {
        IDLoc = Tok.getLocation();
        II = Tok.getIdentifierInfo();
        ConsumeToken();
      }
    }

    // FIXME: improve error recovery
    Dimensions.clear();
    if(ParseArraySpec(Dimensions)) return StmtError();

    auto Stmt = Actions.ActOnDIMENSION(Context, Loc, IDLoc, II,
                                       Dimensions, nullptr);
    if(Stmt.isUsable()) StmtList.push_back(Stmt.take());

    if(Tok.isAtStartOfStatement()) break;
    if(!ExpectAndConsume(tok::comma)) {
      if(!SkipUntil(tok::comma)) break;
    }
  }

  return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}