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) {