Mercurial > hg > CbC > CbC_llvm
changeset 5:7a2c806705bf
Enable CbC goto parse. But tail call flag was not set yet, so it's not jmp but call.
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 07 Jun 2013 20:03:58 +0900 |
parents | e68854097132 |
children | c8782e147cac |
files | tools/clang/include/clang/Parse/Parser.h tools/clang/lib/Parse/ParseStmt.cpp |
diffstat | 2 files changed, 67 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/tools/clang/include/clang/Parse/Parser.h Thu Jun 06 15:05:00 2013 +0900 +++ b/tools/clang/include/clang/Parse/Parser.h Fri Jun 07 20:03:58 2013 +0900 @@ -1497,6 +1497,7 @@ StmtResult ParseDoStatement(); StmtResult ParseForStatement(SourceLocation *TrailingElseLoc); StmtResult ParseGotoStatement(); + StmtResult ParseCbCGotoStatement(); StmtResult ParseContinueStatement(); StmtResult ParseBreakStatement(); StmtResult ParseReturnStatement();
--- a/tools/clang/lib/Parse/ParseStmt.cpp Thu Jun 06 15:05:00 2013 +0900 +++ b/tools/clang/lib/Parse/ParseStmt.cpp Fri Jun 07 20:03:58 2013 +0900 @@ -223,7 +223,13 @@ case tok::kw_for: // C99 6.8.5.3: for-statement return ParseForStatement(TrailingElseLoc); - case tok::kw_goto: // C99 6.8.6.1: goto-statement + case tok::kw_goto: // C99 6.8.6.1: goto-statement or CbC goto +#ifndef noCbC + if (PP.LookAhead(1).is(tok::l_paren)) { // is CbC goto : 'goto' codeSegment() ';' + return ParseCbCGotoStatement(); + SemiError = "goto code segment"; + } +#endif Res = ParseGotoStatement(); SemiError = "goto"; break; @@ -1596,32 +1602,72 @@ /// StmtResult Parser::ParseGotoStatement() { assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); - SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. - - StmtResult Res; - if (Tok.is(tok::identifier)) { - LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), - Tok.getLocation()); - Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD); - ConsumeToken(); - } else if (Tok.is(tok::star)) { - // GNU indirect goto extension. - Diag(Tok, diag::ext_gnu_indirect_goto); - SourceLocation StarLoc = ConsumeToken(); - ExprResult R(ParseExpression()); - if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. - SkipUntil(tok::semi, false, true); - return StmtError(); + SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. + + StmtResult Res; + + if (Tok.is(tok::identifier)) { + LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), + Tok.getLocation()); + Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD); + ConsumeToken(); + } else if (Tok.is(tok::star)) { + // GNU indirect goto extension. + Diag(Tok, diag::ext_gnu_indirect_goto); + SourceLocation StarLoc = ConsumeToken(); + ExprResult R(ParseExpression()); + if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. + SkipUntil(tok::semi, false, true); + return StmtError(); + } + Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); } - Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); - } else { + else { Diag(Tok, diag::err_expected_ident); return StmtError(); } - return Res; } +#ifndef noCbC +/// ParseCbCGotoStatement +/// jump-statement: +/// 'goto' codeSegment ';' +/// +/// +StmtResult Parser::ParseCbCGotoStatement() { + assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); + ConsumeToken(); // eat the 'goto'. + + StmtResult Res; + + if (Tok.is(tok::identifier) && NextToken().is(tok::l_paren)) { // 'goto' codeSegment() ';' + // TODO : set code segment flag (tail call elim flag). + CorrectionCandidateCallback DefaultValidator; + DefaultValidator.WantTypeSpecifiers = true; + DefaultValidator.WantExpressionKeywords = true; + DefaultValidator.WantRemainingKeywords = true; + DefaultValidator.WantCXXNamedCasts = false; + + if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator) + == ANK_Error) { + // Handle errors here by skipping up to the next semicolon or '}', and + // eat the semicolon if that's what stopped us. + SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); + if (Tok.is(tok::semi)) + ConsumeToken(); + return StmtError(); + } + Res = ParseExprStatement(); + } + else { + Diag(Tok, diag::err_expected_ident); + return StmtError(); + } + return Res; +} +#endif + /// ParseContinueStatement /// jump-statement: /// 'continue' ';'