[cfe-commits] r43979 - in /cfe/trunk: Parse/ParseObjc.cpp Parse/Parser.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/DeclObjC.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

Fariborz Jahanian fjahanian at apple.com
Sat Nov 10 08:31:35 PST 2007


Author: fjahanian
Date: Sat Nov 10 10:31:34 2007
New Revision: 43979

URL: http://llvm.org/viewvc/llvm-project?rev=43979&view=rev
Log:
Represent method definitions as separate AST nodes. Pretty print will come next.

Modified:
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Parse/Parser.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43979&r1=43978&r2=43979&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Sat Nov 10 10:31:34 2007
@@ -1147,7 +1147,7 @@
 
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
-Parser::DeclTy *Parser::ParseObjCInstanceMethodDefinition() {
+void Parser::ParseObjCInstanceMethodDefinition() {
   assert(Tok.is(tok::minus) && "Method definitions should start with '-'");
   DeclTy *MDecl = ParseObjCMethodPrototype(ObjcImpDecl);
   // FIXME: @optional/@protocol??
@@ -1158,14 +1158,14 @@
 
   if (Tok.isNot(tok::l_brace)) {
     Diag (Tok, diag::err_expected_lbrace);
-    return 0;
+    return;
   }
-  return ObjcParseMethodDefinition(MDecl);
+  ObjcParseMethodDefinition(MDecl);
 }
 
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
-Parser::DeclTy *Parser::ParseObjCClassMethodDefinition() {
+void Parser::ParseObjCClassMethodDefinition() {
   assert(Tok.is(tok::plus) && "Class method definitions should start with '+'");
   DeclTy *MDecl = ParseObjCMethodPrototype(ObjcImpDecl);
   // FIXME: @optional/@protocol??
@@ -1175,9 +1175,9 @@
     ConsumeToken();
   if (Tok.isNot(tok::l_brace)) {
     Diag (Tok, diag::err_expected_lbrace);
-    return 0;
+    return;
   }
-  return ObjcParseMethodDefinition(MDecl);
+  ObjcParseMethodDefinition(MDecl);
 }
 
 Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {

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

==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Sat Nov 10 10:31:34 2007
@@ -330,17 +330,17 @@
     // @ is not a legal token unless objc is enabled, no need to check.
     return ParseObjCAtDirectives();
   case tok::minus:
-    if (getLang().ObjC1) {
-      return ParseObjCInstanceMethodDefinition();
-    } else {
+    if (getLang().ObjC1)
+      ParseObjCInstanceMethodDefinition();
+    else {
       Diag(Tok, diag::err_expected_external_declaration);
       ConsumeToken();
     }
     return 0;
   case tok::plus:
-    if (getLang().ObjC1) {
-      return ParseObjCClassMethodDefinition();
-    } else {
+    if (getLang().ObjC1)
+      ParseObjCClassMethodDefinition();
+    else {
       Diag(Tok, diag::err_expected_external_declaration);
       ConsumeToken();
     }
@@ -467,7 +467,7 @@
 
 /// ObjcParseMethodDefinition - This routine parses a method definition and
 /// returns its AST.
-Parser::DeclTy *Parser::ObjcParseMethodDefinition(DeclTy *D) {
+void Parser::ObjcParseMethodDefinition(DeclTy *D) {
   // We should have an opening brace now.
   if (Tok.isNot(tok::l_brace)) {
     Diag(Tok, diag::err_expected_fn_body);
@@ -477,7 +477,7 @@
     
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return 0;
+      return;
   }
   
   SourceLocation BraceLoc = Tok.getLocation();
@@ -487,9 +487,19 @@
   
   // Tell the actions module that we have entered a method definition with the
   // specified Declarator for the method.
-  DeclTy *Res = Actions.ObjcActOnStartOfMethodDef(CurScope, D);
+  Actions.ObjcActOnStartOfMethodDef(CurScope, D);
   
-  return ParseFunctionStatementBody(Res, BraceLoc, BraceLoc);  
+  StmtResult FnBody = ParseCompoundStatementBody();
+  
+  // If the function body could not be parsed, make a bogus compoundstmt.
+  if (FnBody.isInvalid)
+    FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
+  
+  // Leave the function body scope.
+  ExitScope();
+  
+  // TODO: Pass argument information.
+  Actions.ActOnMethodDefBody(D, FnBody.Val);
 }
 
 /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43979&r1=43978&r2=43979&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sat Nov 10 10:31:34 2007
@@ -192,6 +192,7 @@
   virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   virtual DeclTy *ObjcActOnStartOfMethodDef(Scope *S, DeclTy *D);
   virtual DeclTy *ActOnFunctionDefBody(DeclTy *Decl, StmtTy *Body);
+  virtual void ActOnMethodDefBody(DeclTy *Decl, StmtTy *Body);
   
   /// Scope actions.
   virtual void ActOnPopScope(SourceLocation Loc, Scope *S);

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Sat Nov 10 10:31:34 2007
@@ -1023,6 +1023,34 @@
   return FD;
 }
 
+void Sema::ActOnMethodDefBody(DeclTy *D, StmtTy *Body) {
+  ObjcMethodDecl *FD = static_cast<ObjcMethodDecl*>(D);
+  FD->setBody((Stmt*)Body);
+  CurFunctionDecl = 0;
+  
+  // Verify and clean out per-function state.
+  
+  // Check goto/label use.
+  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
+       I = LabelMap.begin(), E = LabelMap.end(); I != E; ++I) {
+    // Verify that we have no forward references left.  If so, there was a goto
+    // or address of a label taken, but no definition of it.  Label fwd
+    // definitions are indicated with a null substmt.
+    if (I->second->getSubStmt() == 0) {
+      LabelStmt *L = I->second;
+      // Emit error.
+      Diag(L->getIdentLoc(), diag::err_undeclared_label_use, L->getName());
+      
+      // At this point, we have gotos that use the bogus label.  Stitch it into
+      // the function body so that they aren't leaked and that the AST is well
+      // formed.
+      L->setSubStmt(new NullStmt(L->getIdentLoc()));
+      cast<CompoundStmt>((Stmt*)Body)->push_back(L);
+    }
+  }
+  LabelMap.clear();
+}
+
 /// ObjcActOnStartOfMethodDef - This routine sets up parameters; invisible
 /// and user declared, in the method definition's AST.
 Sema::DeclTy *Sema::ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sat Nov 10 10:31:34 2007
@@ -255,6 +255,8 @@
   /// List of attributes for this method declaration.
   AttributeList *MethodAttrs;
   
+  Stmt *Body;  // Null if a prototype.
+  
   SourceLocation EndLoc; // the location of the ';' or '{'.
 public:
   ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
@@ -300,6 +302,9 @@
   ImplementationControl  getImplementationControl() const
                            { return DeclImplementation; }
   
+  Stmt *const getBody() const { return Body; }
+  void setBody(Stmt *B) { Body = B; }
+  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; }
   static bool classof(const ObjcMethodDecl *D) { return true; }

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sat Nov 10 10:31:34 2007
@@ -136,7 +136,7 @@
   }
 
   virtual DeclTy *ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
-    // Default to ActOnDeclarator.
+    // Default to ObjcActOnMethodDefinition.
     return ObjcActOnMethodDefinition(FnBodyScope, D, 0);
   }
   
@@ -146,6 +146,9 @@
     return Decl;
   }
 
+  virtual void ActOnMethodDefBody(DeclTy *Decl, StmtTy *Body) {
+    return;
+  }
   
   /// ActOnPopScope - This callback is called immediately before the specified
   /// scope is popped and deleted.

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Nov 10 10:31:34 2007
@@ -250,7 +250,7 @@
   DeclTy *ParseExternalDeclaration();
   DeclTy *ParseDeclarationOrFunctionDefinition();
   DeclTy *ParseFunctionDefinition(Declarator &D);
-  DeclTy *ObjcParseMethodDefinition(DeclTy *D);
+  void ObjcParseMethodDefinition(DeclTy *D);
   void ParseKNRParamDeclarations(Declarator &D);
   void ParseSimpleAsm();
   void ParseAsmStringLiteral();
@@ -302,8 +302,8 @@
   void ParseObjCPropertyAttribute(ObjcDeclSpec &DS);
   DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);
   
-  DeclTy *ParseObjCInstanceMethodDefinition();
-  DeclTy *ParseObjCClassMethodDefinition();
+  void ParseObjCInstanceMethodDefinition();
+  void ParseObjCClassMethodDefinition();
   
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.





More information about the cfe-commits mailing list