[cfe-commits] r38993 - in /cfe/cfe/trunk: AST/Sema.cpp Parse/ParseStmt.cpp Parse/Parser.cpp Sema/Sema.cpp include/clang/AST/Decl.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:26:37 PDT 2007


Author: sabre
Date: Wed Jul 11 11:26:36 2007
New Revision: 38993

URL: http://llvm.org/viewvc/llvm-project?rev=38993&view=rev
Log:
implement action callbacks for almost all the stmts.

Modified:
    cfe/cfe/trunk/AST/Sema.cpp
    cfe/cfe/trunk/Parse/ParseStmt.cpp
    cfe/cfe/trunk/Parse/Parser.cpp
    cfe/cfe/trunk/Sema/Sema.cpp
    cfe/cfe/trunk/include/clang/AST/Decl.h
    cfe/cfe/trunk/include/clang/Parse/Action.h
    cfe/cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/cfe/trunk/AST/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.cpp?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.cpp (original)
+++ cfe/cfe/trunk/AST/Sema.cpp Wed Jul 11 11:26:36 2007
@@ -139,7 +139,9 @@
 Action::DeclTy *
 ASTBuilder::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
   FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
-  // TODO: more stuff.
+  
+  FD->setBody((Stmt*)Body);
+
   return FD;
 }
 

Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:26:36 2007
@@ -68,10 +68,10 @@
 /// [OBC]   '@' 'throw' expression ';'    [TODO]
 /// [OBC]   '@' 'throw' ';'               [TODO]
 /// 
-void Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
+Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
   const char *SemiError = 0;
+  Parser::StmtResult Res;
   
-ParseNextStatement:
   // Cases in this switch statement should fall through if the parser expects
   // the token to end in a semicolon (in which case SemiError should be set),
   // or they directly 'return;' if not.
@@ -86,9 +86,11 @@
     if (!OnlyStatement && isDeclarationSpecifier()) {
       // TODO: warn/disable if declaration is in the middle of a block and !C99.
       ParseDeclaration(Declarator::BlockContext);
-      return;
+      // FIXME: Make a DeclStmt node!
+      return 0;
     } else if (Tok.getKind() == tok::r_brace) {
       Diag(Tok, diag::err_expected_statement);
+      return true;
     } else {
       // expression[opt] ';'
       ExprResult Res = ParseExpression();
@@ -97,71 +99,59 @@
         // doing this opens us up to the possibility of infinite loops if
         // ParseExpression does not consume any tokens.
         SkipUntil(tok::semi);
+        return true;
+      } else {
+        return Actions.ParseExprStmt(Res.Val);
       }
     }
-    return;
     
   case tok::kw_case:                // C99 6.8.1: labeled-statement
-    ParseCaseStatement();
-    if (Tok.getKind() == tok::r_brace) {
-      Diag(Tok, diag::err_label_end_of_compound_statement);
-      return;
-    }
-    OnlyStatement = true;
-    goto ParseNextStatement;
+    return ParseCaseStatement();
   case tok::kw_default:             // C99 6.8.1: labeled-statement
-    ParseDefaultStatement();
-    if (Tok.getKind() == tok::r_brace) {
-      Diag(Tok, diag::err_label_end_of_compound_statement);
-      return;
-    }
-    OnlyStatement = true;
-    goto ParseNextStatement;
+    return ParseDefaultStatement();
     
   case tok::l_brace:                // C99 6.8.2: compound-statement
-    ParseCompoundStatement();
-    return;
+    return ParseCompoundStatement();
   case tok::semi:                   // C99 6.8.3: expression[opt] ';'
+    // TODO: Could return a NullStmt action result if we cared to.
     ConsumeToken();
-    return;
+    return 0;
     
   case tok::kw_if:                  // C99 6.8.4.1: if-statement
-    ParseIfStatement();
-    return;
+    return ParseIfStatement();
   case tok::kw_switch:              // C99 6.8.4.2: switch-statement
-    ParseSwitchStatement();
-    return;
+    return ParseSwitchStatement();
     
   case tok::kw_while:               // C99 6.8.5.1: while-statement
-    ParseWhileStatement();
-    return;
+    return ParseWhileStatement();
   case tok::kw_do:                  // C99 6.8.5.2: do-statement
-    ParseDoStatement();
+    Res = ParseDoStatement();
     SemiError = "do/while loop";
     break;
   case tok::kw_for:                 // C99 6.8.5.3: for-statement
-    ParseForStatement();
-    return;
+    return ParseForStatement();
 
   case tok::kw_goto:                // C99 6.8.6.1: goto-statement
-    ParseGotoStatement();
+    Res = ParseGotoStatement();
     SemiError = "goto statement";
     break;
   case tok::kw_continue:            // C99 6.8.6.2: continue-statement
+    Res = Actions.ParseContinueStmt(Tok.getLocation());
     ConsumeToken();  // eat the 'continue'.
     SemiError = "continue statement";
     break;
   case tok::kw_break:               // C99 6.8.6.3: break-statement
+    Res = Actions.ParseBreakStmt(Tok.getLocation());
     ConsumeToken();  // eat the 'break'.
     SemiError = "break statement";
     break;
   case tok::kw_return:              // C99 6.8.6.4: return-statement
-    ParseReturnStatement();
+    Res = ParseReturnStatement();
     SemiError = "return statement";
     break;
     
   case tok::kw_asm:
-    ParseAsmStatement();
+    Res = ParseAsmStatement();
     SemiError = "asm statement";
     break;
   }
@@ -173,6 +163,7 @@
     Diag(Tok, diag::err_expected_semi_after, SemiError);
     SkipUntil(tok::semi);
   }
+  return Res;
 }
 
 /// ParseIdentifierStatement - Because we don't have two-token lookahead, we
@@ -187,26 +178,31 @@
 ///         declaration                  (if !OnlyStatement)
 ///         expression[opt] ';'
 ///
-void Parser::ParseIdentifierStatement(bool OnlyStatement) {
+Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) {
   IdentifierInfo *II = Tok.getIdentifierInfo();
   assert(Tok.getKind() == tok::identifier && II && "Not an identifier!");
 
-  LexerToken IdentTok = Tok;  // Save the token.
+  LexerToken IdentTok = Tok;  // Save the whole token.
   ConsumeToken();  // eat the identifier.
   
   // identifier ':' statement
   if (Tok.getKind() == tok::colon) {
+    SourceLocation ColonLoc = Tok.getLocation();
     ConsumeToken();
 
     // Read label attributes, if present.
     if (Tok.getKind() == tok::kw___attribute)
+      // TODO: save these somewhere.
       ParseAttributes();
 
-    ParseStatement();
-    return;
+    StmtResult SubStmt = ParseStatement();
+    if (SubStmt.isInvalid) return true;
+    
+    // FIXME: Enter this label into the symbol table for the function.
+    return Actions.ParseLabelStmt(IdentTok, ColonLoc, SubStmt.Val);
   }
   
-  // declaration
+  // Check to see if this is a declaration.
   if (!OnlyStatement &&
       Actions.isTypedefName(*IdentTok.getIdentifierInfo(), CurScope)) {
     // Handle this.  Warn/disable if in middle of block and !C99.
@@ -223,7 +219,8 @@
       // if (!DS.isMissingDeclaratorOk()) Diag(...);
       
       ConsumeToken();
-      return;
+      // FIXME: Return this as a type decl.
+      return 0;
     }
     
     // Parse all the declarators.
@@ -231,18 +228,22 @@
     ParseDeclarator(DeclaratorInfo);
     
     ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
-    return;
+    // FIXME: Return this as a declstmt.
+    return 0;
   }
   
   // Otherwise, this is an expression.  Seed it with II and parse it.
   ExprResult Res = ParseExpressionWithLeadingIdentifier(IdentTok);
-  if (Res.isInvalid)
+  if (Res.isInvalid) {
     SkipUntil(tok::semi);
-  else if (Tok.getKind() == tok::semi)
-    ConsumeToken();
-  else {
+    return true;
+  } else if (Tok.getKind() != tok::semi) {
     Diag(Tok, diag::err_expected_semi_after, "expression");
     SkipUntil(tok::semi);
+    return true;
+  } else {
+    ConsumeToken();
+    return Actions.ParseExprStmt(Res.Val);
   }
 }
 
@@ -253,17 +254,20 @@
 ///
 /// Note that this does not parse the 'statement' at the end.
 ///
-void Parser::ParseCaseStatement() {
+Parser::StmtResult Parser::ParseCaseStatement() {
   assert(Tok.getKind() == tok::kw_case && "Not a case stmt!");
+  SourceLocation CaseLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'case'.
 
-  ExprResult Res = ParseConstantExpression();
-  if (Res.isInvalid) {
+  ExprResult LHS = ParseConstantExpression();
+  if (LHS.isInvalid) {
     SkipUntil(tok::colon);
-    return;
+    return true;
   }
   
   // GNU case range extension.
+  SourceLocation DotDotDotLoc;
+  ExprTy *RHSVal = 0;
   if (Tok.getKind() == tok::ellipsis) {
     Diag(Tok, diag::ext_gnu_case_range);
     ConsumeToken();
@@ -271,16 +275,33 @@
     ExprResult RHS = ParseConstantExpression();
     if (RHS.isInvalid) {
       SkipUntil(tok::colon);
-      return;
+      return true;
     }
+    RHSVal = RHS.Val;
   }
   
-  if (Tok.getKind() == tok::colon) {
-    ConsumeToken();
-  } else {
+  if (Tok.getKind() != tok::colon) {
     Diag(Tok, diag::err_expected_colon_after, "'case'");
     SkipUntil(tok::colon);
+    return true;
   }
+  
+  SourceLocation ColonLoc = Tok.getLocation();
+  ConsumeToken();
+  
+  // Diagnose the common error "switch (X) { case 4: }", which is not valid.
+  if (Tok.getKind() == tok::r_brace) {
+    Diag(Tok, diag::err_label_end_of_compound_statement);
+    return true;
+  }
+  
+  StmtResult SubStmt = ParseStatement();
+  if (SubStmt.isInvalid)
+    return true;
+  
+  // TODO: look up enclosing switch stmt.
+  return Actions.ParseCaseStmt(CaseLoc, LHS.Val, DotDotDotLoc, RHSVal, ColonLoc,
+                               SubStmt.Val);
 }
 
 /// ParseDefaultStatement
@@ -288,16 +309,32 @@
 ///         'default' ':' statement
 /// Note that this does not parse the 'statement' at the end.
 ///
-void Parser::ParseDefaultStatement() {
+Parser::StmtResult Parser::ParseDefaultStatement() {
   assert(Tok.getKind() == tok::kw_default && "Not a default stmt!");
+  SourceLocation DefaultLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'default'.
 
-  if (Tok.getKind() == tok::colon) {
-    ConsumeToken();
-  } else {
+  if (Tok.getKind() != tok::colon) {
     Diag(Tok, diag::err_expected_colon_after, "'default'");
     SkipUntil(tok::colon);
+    return true;
+  }
+  
+  SourceLocation ColonLoc = Tok.getLocation();
+  ConsumeToken();
+  
+  // Diagnose the common error "switch (X) {... default: }", which is not valid.
+  if (Tok.getKind() == tok::r_brace) {
+    Diag(Tok, diag::err_label_end_of_compound_statement);
+    return true;
   }
+
+  StmtResult SubStmt = ParseStatement();
+  if (SubStmt.isInvalid)
+    return true;
+  
+  // TODO: look up enclosing switch stmt.
+  return Actions.ParseDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val);
 }
 
 
@@ -327,122 +364,162 @@
 /// [OMP] openmp-directive:             [TODO]
 /// [OMP]   barrier-directive
 /// [OMP]   flush-directive
-void Parser::ParseCompoundStatement() {
+///
+Parser::StmtResult Parser::ParseCompoundStatement() {
   assert(Tok.getKind() == tok::l_brace && "Not a compount stmt!");
+  SourceLocation LBraceLoc = Tok.getLocation();
   ConsumeBrace();  // eat the '{'.
   
-  while (Tok.getKind() != tok::r_brace && Tok.getKind() != tok::eof)
-    ParseStatementOrDeclaration(false);
+  SmallVector<StmtTy*, 32> Stmts;
+  while (Tok.getKind() != tok::r_brace && Tok.getKind() != tok::eof) {
+    StmtResult R = ParseStatementOrDeclaration(false);
+    if (!R.isInvalid && R.Val)
+      Stmts.push_back(R.Val);
+  }
   
   // We broke out of the while loop because we found a '}' or EOF.
-  if (Tok.getKind() == tok::r_brace)
-    ConsumeBrace();
-  else
+  if (Tok.getKind() != tok::r_brace) {
     Diag(Tok, diag::err_expected_rbrace);
+    return 0;
+  }
+
+  SourceLocation RBraceLoc = Tok.getLocation();
+  ConsumeBrace();
+  return Actions.ParseCompoundStmt(LBraceLoc, RBraceLoc,
+                                   &Stmts[0], Stmts.size());
 }
 
 /// ParseIfStatement
 ///       if-statement: [C99 6.8.4.1]
 ///         'if' '(' expression ')' statement
 ///         'if' '(' expression ')' statement 'else' statement
-void Parser::ParseIfStatement() {
+///
+Parser::StmtResult Parser::ParseIfStatement() {
   assert(Tok.getKind() == tok::kw_if && "Not an if stmt!");
+  SourceLocation IfLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'if'.
 
   if (Tok.getKind() != tok::l_paren) {
     Diag(Tok, diag::err_expected_lparen_after, "if");
     SkipUntil(tok::semi);
-    return;
+    return true;
   }
   
   // Parse the condition.
-  ParseSimpleParenExpression();
+  ExprResult CondExp = ParseSimpleParenExpression();
+  if (CondExp.isInvalid) {
+    SkipUntil(tok::semi);
+    return true;
+  }
   
   // Read the if condition.
-  ParseStatement();
+  StmtResult CondStmt = ParseStatement();
   
   // If it has an else, parse it.
+  SourceLocation ElseLoc;
+  StmtResult ElseStmt(false);
   if (Tok.getKind() == tok::kw_else) {
+    ElseLoc = Tok.getLocation();
     ConsumeToken();
-    ParseStatement();
+    ElseStmt = ParseStatement();
   }
+  
+  if (CondStmt.isInvalid || ElseStmt.isInvalid)
+    return true;
+  
+  return Actions.ParseIfStmt(IfLoc, CondExp.Val, CondStmt.Val,
+                             ElseLoc, ElseStmt.Val);
 }
 
 /// ParseSwitchStatement
 ///       switch-statement:
 ///         'switch' '(' expression ')' statement
-void Parser::ParseSwitchStatement() {
+Parser::StmtResult Parser::ParseSwitchStatement() {
   assert(Tok.getKind() == tok::kw_switch && "Not a switch stmt!");
+  SourceLocation SwitchLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'switch'.
 
   if (Tok.getKind() != tok::l_paren) {
     Diag(Tok, diag::err_expected_lparen_after, "switch");
     SkipUntil(tok::semi);
-    return;
+    return true;
   }
   
   // Parse the condition.
-  ParseSimpleParenExpression();
+  ExprResult Cond = ParseSimpleParenExpression();
   
   // Read the body statement.
-  ParseStatement();
+  StmtResult Body = ParseStatement();
+  
+  if (Cond.isInvalid || Body.isInvalid) return true;
+  
+  return Actions.ParseSwitchStmt(SwitchLoc, Cond.Val, Body.Val);
 }
 
 /// ParseWhileStatement
 ///       while-statement: [C99 6.8.5.1]
 ///         'while' '(' expression ')' statement
-void Parser::ParseWhileStatement() {
+Parser::StmtResult Parser::ParseWhileStatement() {
   assert(Tok.getKind() == tok::kw_while && "Not a while stmt!");
+  SourceLocation WhileLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'while'.
   
   if (Tok.getKind() != tok::l_paren) {
     Diag(Tok, diag::err_expected_lparen_after, "while");
     SkipUntil(tok::semi);
-    return;
+    return true;
   }
   
   // Parse the condition.
-  ParseSimpleParenExpression();
+  ExprResult Cond = ParseSimpleParenExpression();
   
   // Read the body statement.
-  ParseStatement();
+  StmtResult Body = ParseStatement();
+  
+  if (Cond.isInvalid || Body.isInvalid) return true;
+  
+  return Actions.ParseWhileStmt(WhileLoc, Cond.Val, Body.Val);
 }
 
 /// ParseDoStatement
 ///       do-statement: [C99 6.8.5.2]
 ///         'do' statement 'while' '(' expression ')' ';'
 /// Note: this lets the caller parse the end ';'.
-void Parser::ParseDoStatement() {
+Parser::StmtResult Parser::ParseDoStatement() {
   assert(Tok.getKind() == tok::kw_do && "Not a do stmt!");
   SourceLocation DoLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'do'.
   
   // Read the body statement.
-  ParseStatement();
+  StmtResult Body = ParseStatement();
 
   if (Tok.getKind() != tok::kw_while) {
     Diag(Tok, diag::err_expected_while);
     Diag(DoLoc, diag::err_matching, "do");
     SkipUntil(tok::semi);
-    return;
+    return true;
   }
+  SourceLocation WhileLoc = Tok.getLocation();
   ConsumeToken();
   
   if (Tok.getKind() != tok::l_paren) {
     Diag(Tok, diag::err_expected_lparen_after, "do/while");
     SkipUntil(tok::semi);
-    return;
+    return true;
   }
   
   // Parse the condition.
-  ParseSimpleParenExpression();
+  ExprResult Cond = ParseSimpleParenExpression();
+  if (Cond.isInvalid || Body.isInvalid) return true;
+  
+  return Actions.ParseDoStmt(DoLoc, Body.Val, WhileLoc, Cond.Val);
 }
 
 /// ParseForStatement
 ///       for-statement: [C99 6.8.5.3]
 ///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
 ///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
-void Parser::ParseForStatement() {
+Parser::StmtResult Parser::ParseForStatement() {
   assert(Tok.getKind() == tok::kw_for && "Not a for stmt!");
   SourceLocation ForLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'for'.
@@ -450,7 +527,7 @@
   if (Tok.getKind() != tok::l_paren) {
     Diag(Tok, diag::err_expected_lparen_after, "for");
     SkipUntil(tok::semi);
-    return;
+    return true;
   }
 
   SourceLocation LParenLoc = Tok.getLocation();
@@ -506,6 +583,9 @@
   
   // Read the body statement.
   ParseStatement();
+  
+  // FIXME: ACTION FOR FOR STMT.
+  return false;
 }
 
 /// ParseGotoStatement
@@ -515,34 +595,47 @@
 ///
 /// Note: this lets the caller parse the end ';'.
 ///
-void Parser::ParseGotoStatement() {
+Parser::StmtResult Parser::ParseGotoStatement() {
   assert(Tok.getKind() == tok::kw_goto && "Not a goto stmt!");
+  SourceLocation GotoLoc;
   ConsumeToken();  // eat the 'goto'.
   
+  StmtResult Res;
   if (Tok.getKind() == tok::identifier) {
+    Res = Actions.ParseGotoStmt(GotoLoc, Tok);
     ConsumeToken();
   } else if (Tok.getKind() == tok::star && !getLang().NoExtensions) {
     // GNU indirect goto extension.
     Diag(Tok, diag::ext_gnu_indirect_goto);
+    SourceLocation StarLoc = Tok.getLocation();
     ConsumeToken();
     ExprResult R = ParseExpression();
-    if (R.isInvalid)   // Skip to the semicolon, but don't consume it.
+    if (R.isInvalid) {  // Skip to the semicolon, but don't consume it.
       SkipUntil(tok::semi, false, true);
+      return true;
+    }
+    Res = Actions.ParseIndirectGotoStmt(GotoLoc, StarLoc, R.Val);
   }
+  return Res;
 }
 
 /// ParseReturnStatement
 ///       jump-statement:
 ///         'return' expression[opt] ';'
-void Parser::ParseReturnStatement() {
+Parser::StmtResult Parser::ParseReturnStatement() {
   assert(Tok.getKind() == tok::kw_return && "Not a return stmt!");
+  SourceLocation ReturnLoc = Tok.getLocation();
   ConsumeToken();  // eat the 'return'.
   
+  ExprResult R(0);
   if (Tok.getKind() != tok::semi) {
-    ExprResult R = ParseExpression();
-    if (R.isInvalid)   // Skip to the semicolon, but don't consume it.
+    R = ParseExpression();
+    if (R.isInvalid) {  // Skip to the semicolon, but don't consume it.
       SkipUntil(tok::semi, false, true);
+      return true;
+    }
   }
+  return Actions.ParseReturnStmt(ReturnLoc, R.Val);
 }
 
 /// ParseAsmStatement - Parse a GNU extended asm statement.
@@ -560,7 +653,7 @@
 ///         asm-string-literal
 ///         asm-clobbers ',' asm-string-literal
 ///
-void Parser::ParseAsmStatement() {
+Parser::StmtResult Parser::ParseAsmStatement() {
   assert(Tok.getKind() == tok::kw_asm && "Not an asm stmt");
   ConsumeToken();
   
@@ -580,7 +673,7 @@
   if (Tok.getKind() != tok::l_paren) {
     Diag(Tok, diag::err_expected_lparen_after, "asm");
     SkipUntil(tok::r_paren);
-    return;
+    return true;
   }
   Loc = Tok.getLocation();
   ConsumeParen();
@@ -609,6 +702,9 @@
   }
   
   MatchRHSPunctuation(tok::r_paren, Loc);
+  
+  // FIXME: Implement action for asm parsing.
+  return false;
 }
 
 /// ParseAsmOperands - Parse the asm-operands production as used by

Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:26:36 2007
@@ -397,12 +397,12 @@
       return 0;
   }
   
-  // TODO: Get stmt info.
-  StmtTy *FnBody = 0;
-  ParseCompoundStatement();
+  // Parse the function body as a compound stmt.
+  StmtResult FnBody = ParseCompoundStatement();
+  if (FnBody.isInvalid) return 0;
 
   // TODO: Pass argument information.
-  return Actions.ParseFunctionDefinition(CurScope, D, FnBody);
+  return Actions.ParseFunctionDefinition(CurScope, D, FnBody.Val);
 }
 
 /// ParseAsmStringLiteral - This is just a normal string-literal, but is not

Modified: cfe/cfe/trunk/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.cpp?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/cfe/trunk/Sema/Sema.cpp Wed Jul 11 11:26:36 2007
@@ -139,7 +139,9 @@
 Action::DeclTy *
 ASTBuilder::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
   FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
-  // TODO: more stuff.
+  
+  FD->setBody((Stmt*)Body);
+
   return FD;
 }
 

Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:26:36 2007
@@ -20,6 +20,7 @@
 namespace llvm {
 namespace clang {
 class IdentifierInfo;
+class Stmt;
   
 /// Decl - This represents one declaration (or definition), e.g. a variable, 
 /// typedef, function, struct, etc.  
@@ -54,10 +55,13 @@
 /// declaration or definition.
 class FunctionDecl : public Decl {
   // Args etc.
+  Stmt *Body;  // Null if a prototype.
 public:
   FunctionDecl(IdentifierInfo *Id, const Declarator &D, Decl *Next)
-    : Decl(Id, D, Next) {}
-
+    : Decl(Id, D, Next), Body(0) {}
+  
+  Stmt *getBody() const { return Body; }
+  void setBody(Stmt *B) { Body = B; }
 };
 
 /// VarDecl - An instance of this class is created to represent a variable

Modified: cfe/cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Action.h?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:26:36 2007
@@ -51,23 +51,29 @@
   typedef void DeclTy;
   typedef void TypeTy;
   
-  /// ExprResult - This structure is used while parsing/acting on expressions.
-  /// It encapsulates both the expression object returned by the action, plus
+  /// ActionResult - This structure is used while parsing/acting on expressions,
+  /// stmts, etc.  It encapsulates both the object returned by the action, plus
   /// a sense of whether or not it is valid.
-  struct ExprResult {
-    ExprTy *Val;
+  template<unsigned UID>
+  struct ActionResult {
+    void *Val;
     bool isInvalid;
     
-    ExprResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
+    ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
     template<typename ActualExprTy>
-    ExprResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
+    ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
     
-    const ExprResult &operator=(ExprTy *RHS) {
+    const ActionResult &operator=(void *RHS) {
       Val = RHS;
       isInvalid = false;
       return *this;
     }
   };
+
+  /// Expr/StmtResult - Provide a unique type to wrap ExprTy/StmtTy, etc,
+  /// providing strong typing and allowing for failure.
+  typedef ActionResult<0> ExprResult;
+  typedef ActionResult<1> StmtResult;
   
   //===--------------------------------------------------------------------===//
   // Symbol Table Tracking Callbacks.
@@ -107,6 +113,75 @@
   //===--------------------------------------------------------------------===//
   
   //===--------------------------------------------------------------------===//
+  // Statement Parsing Callbacks.
+  //===--------------------------------------------------------------------===//
+  
+  virtual StmtResult ParseCompoundStmt(SourceLocation L, SourceLocation R,
+                                       StmtTy **Elts, unsigned NumElts) {
+    return 0;
+  }
+  virtual StmtResult ParseExprStmt(ExprTy *Expr) {
+    return 0;
+  }
+  
+  /// ParseCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
+  /// which can specify an RHS value.
+  virtual StmtResult ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
+                                   SourceLocation DotDotDotLoc, ExprTy *RHSVal,
+                                   SourceLocation ColonLoc, StmtTy *SubStmt) {
+    return 0;
+  }
+  virtual StmtResult ParseDefaultStmt(SourceLocation DefaultLoc,
+                                      SourceLocation ColonLoc, StmtTy *SubStmt){
+    return 0;
+  }
+  
+  virtual StmtResult ParseLabelStmt(const LexerToken &IdentTok,
+                                    SourceLocation ColonLoc, StmtTy *SubStmt) {
+    return 0;
+  }
+  
+  virtual StmtResult ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
+                                 StmtTy *ThenVal, SourceLocation ElseLoc,
+                                 StmtTy *ElseVal) {
+    return 0; 
+  }
+  
+  virtual StmtResult ParseSwitchStmt(SourceLocation SwitchLoc, ExprTy *Cond,
+                                     StmtTy *Body) {
+    return 0;
+  }
+  virtual StmtResult ParseWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
+                                     StmtTy *Body) {
+    return 0;
+  }
+  virtual StmtResult ParseDoStmt(SourceLocation DoLoc, StmtTy *Body,
+                                 SourceLocation WhileLoc, ExprTy *Cond) {
+    return 0;
+  }
+  // PARSE FOR STMT.
+  virtual StmtResult ParseGotoStmt(SourceLocation GotoLoc,
+                                   const LexerToken &LabelTok) {
+    return 0;
+  }
+  virtual StmtResult ParseContinueStmt(SourceLocation GotoLoc) {
+    return 0;
+  }
+  virtual StmtResult ParseBreakStmt(SourceLocation GotoLoc) {
+    return 0;
+  }
+  virtual StmtResult ParseIndirectGotoStmt(SourceLocation GotoLoc,
+                                           SourceLocation StarLoc,
+                                           ExprTy *DestExp) {
+    return 0;
+  }
+  virtual StmtResult ParseReturnStmt(SourceLocation ReturnLoc,
+                                           ExprTy *RetValExp) {
+    return 0;
+  }
+  
+  
+  //===--------------------------------------------------------------------===//
   // Expression Parsing Callbacks.
   //===--------------------------------------------------------------------===//
   

Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38993&r1=38992&r2=38993&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:26:36 2007
@@ -225,6 +225,7 @@
   // C99 6.5: Expressions.
 
   typedef Action::ExprResult ExprResult;
+  typedef Action::StmtResult StmtResult;
   
   ExprResult ParseExpression();
   ExprResult ParseConstantExpression();
@@ -266,20 +267,20 @@
   //===--------------------------------------------------------------------===//
   // C99 6.8: Statements and Blocks.
   
-  void ParseStatement() { ParseStatementOrDeclaration(true); }
-  void ParseStatementOrDeclaration(bool OnlyStatement = false);
-  void ParseIdentifierStatement(bool OnlyStatement);
-  void ParseCaseStatement();
-  void ParseDefaultStatement();
-  void ParseCompoundStatement();
-  void ParseIfStatement();
-  void ParseSwitchStatement();
-  void ParseWhileStatement();
-  void ParseDoStatement();
-  void ParseForStatement();
-  void ParseGotoStatement();
-  void ParseReturnStatement();
-  void ParseAsmStatement();
+  StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
+  StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
+  StmtResult ParseIdentifierStatement(bool OnlyStatement);
+  StmtResult ParseCaseStatement();
+  StmtResult ParseDefaultStatement();
+  StmtResult ParseCompoundStatement();
+  StmtResult ParseIfStatement();
+  StmtResult ParseSwitchStatement();
+  StmtResult ParseWhileStatement();
+  StmtResult ParseDoStatement();
+  StmtResult ParseForStatement();
+  StmtResult ParseGotoStatement();
+  StmtResult ParseReturnStatement();
+  StmtResult ParseAsmStatement();
   void ParseAsmOperandsOpt();
 
   //===--------------------------------------------------------------------===//





More information about the cfe-commits mailing list