bool Parser::ParseDimensionAttributeSpec(SourceLocation Loc, DeclSpec &DS) { SmallVector<ArraySpec*, 8> Dimensions; if (ParseArraySpec(Dimensions)) return true; Actions.ActOnDimensionAttrSpec(Context, Loc, DS, Dimensions); return false; }
/// 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); }
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; }
/// 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); }