diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp | 63 | 
1 files changed, 53 insertions, 10 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp index b658cef234ec..717bcff0c168 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp @@ -259,6 +259,10 @@ Retry:      Res = ParseReturnStatement();      SemiError = "return";      break; +  case tok::kw_co_return:            // C++ Coroutines: co_return statement +    Res = ParseReturnStatement(); +    SemiError = "co_return"; +    break;    case tok::kw_asm: {      ProhibitAttributes(Attrs); @@ -354,6 +358,11 @@ Retry:      HandlePragmaMSPragma();      return StmtEmpty(); +  case tok::annot_pragma_ms_vtordisp: +    ProhibitAttributes(Attrs); +    HandlePragmaMSVtorDisp(); +    return StmtEmpty(); +    case tok::annot_pragma_loop_hint:      ProhibitAttributes(Attrs);      return ParsePragmaLoopHint(Stmts, OnlyStatement, TrailingElseLoc, Attrs); @@ -881,6 +890,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() {      case tok::annot_pragma_ms_pragma:        HandlePragmaMSPragma();        break; +    case tok::annot_pragma_ms_vtordisp: +      HandlePragmaMSVtorDisp(); +      break;      default:        checkForPragmas = false;        break; @@ -944,7 +956,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {        Stmts.push_back(R.get());    } -  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { +  while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && +         Tok.isNot(tok::eof)) {      if (Tok.is(tok::annot_pragma_unused)) {        HandlePragmaUnused();        continue; @@ -1442,7 +1455,10 @@ bool Parser::isForRangeIdentifier() {  ///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement  /// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'  /// [C++]       statement -/// [C++0x] 'for' '(' for-range-declaration : for-range-initializer ) statement +/// [C++0x] 'for' +///             'co_await'[opt]    [Coroutines] +///             '(' for-range-declaration ':' for-range-initializer ')' +///             statement  /// [OBJC2] 'for' '(' declaration 'in' expr ')' statement  /// [OBJC2] 'for' '(' expr 'in' expr ')' statement  /// @@ -1459,6 +1475,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {    assert(Tok.is(tok::kw_for) && "Not a for stmt!");    SourceLocation ForLoc = ConsumeToken();  // eat the 'for'. +  SourceLocation CoawaitLoc; +  if (Tok.is(tok::kw_co_await)) +    CoawaitLoc = ConsumeToken(); +    if (Tok.isNot(tok::l_paren)) {      Diag(Tok, diag::err_expected_lparen_after) << "for";      SkipUntil(tok::semi); @@ -1665,6 +1685,13 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {    // Match the ')'.    T.consumeClose(); +  // C++ Coroutines [stmt.iter]: +  //   'co_await' can only be used for a range-based for statement. +  if (CoawaitLoc.isValid() && !ForRange) { +    Diag(CoawaitLoc, diag::err_for_co_await_not_range_for); +    CoawaitLoc = SourceLocation(); +  } +    // We need to perform most of the semantic analysis for a C++0x for-range    // statememt before parsing the body, in order to be able to deduce the type    // of an auto-typed loop variable. @@ -1672,12 +1699,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {    StmtResult ForEachStmt;    if (ForRange) { -    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.get(), -                                                ForRangeInit.ColonLoc, -                                                ForRangeInit.RangeExpr.get(), -                                                T.getCloseLocation(), -                                                Sema::BFRK_Build); - +    ForRangeStmt = Actions.ActOnCXXForRangeStmt( +        getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(), +        ForRangeInit.ColonLoc, ForRangeInit.RangeExpr.get(), +        T.getCloseLocation(), Sema::BFRK_Build);    // Similarly, we need to do the semantic analysis for a for-range    // statement immediately in order to close over temporaries correctly. @@ -1799,13 +1824,19 @@ StmtResult Parser::ParseBreakStatement() {  /// ParseReturnStatement  ///       jump-statement:  ///         'return' expression[opt] ';' +///         'return' braced-init-list ';' +///         'co_return' expression[opt] ';' +///         'co_return' braced-init-list ';'  StmtResult Parser::ParseReturnStatement() { -  assert(Tok.is(tok::kw_return) && "Not a return stmt!"); +  assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) && +         "Not a return stmt!"); +  bool IsCoreturn = Tok.is(tok::kw_co_return);    SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.    ExprResult R;    if (Tok.isNot(tok::semi)) { -    if (Tok.is(tok::code_completion)) { +    // FIXME: Code completion for co_return. +    if (Tok.is(tok::code_completion) && !IsCoreturn) {        Actions.CodeCompleteReturn(getCurScope());        cutOffParsing();        return StmtError(); @@ -1825,6 +1856,8 @@ StmtResult Parser::ParseReturnStatement() {        return StmtError();      }    } +  if (IsCoreturn) +    return Actions.ActOnCoreturnStmt(ReturnLoc, R.get());    return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());  } @@ -1870,6 +1903,11 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {    PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,                                        "parsing function body"); +  // Save and reset current vtordisp stack if we have entered a C++ method body. +  bool IsCXXMethod = +      getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl); +  Sema::VtorDispStackRAII SavedVtorDispStack(Actions, IsCXXMethod); +    // Do not enter a scope for the brace, as the arguments are in the same scope    // (the function body) as the body itself.  Instead, just read the statement    // list and put it into a CompoundStmt for safe keeping. @@ -1909,6 +1947,11 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {      return Actions.ActOnSkippedFunctionBody(Decl);    } +  // Save and reset current vtordisp stack if we have entered a C++ method body. +  bool IsCXXMethod = +      getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl); +  Sema::VtorDispStackRAII SavedVtorDispStack(Actions, IsCXXMethod); +    SourceLocation LBraceLoc = Tok.getLocation();    StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true));    // If we failed to parse the try-catch, we just give the function an empty  | 
