Represent method definitions as separate AST nodes. Pretty print will come next.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43979 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 9816e81..31b5410 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -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);
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 1fb2219..65e7af5 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -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) {