[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