Skip to content

Commit

Permalink
Represent method definitions as separate AST nodes. Pretty print will…
Browse files Browse the repository at this point in the history
… come next.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43979 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Fariborz Jahanian committed Nov 10, 2007
1 parent eae5cd0 commit 60fbca0
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 20 deletions.
12 changes: 6 additions & 6 deletions Parse/ParseObjc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {

/// 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??
Expand All @@ -1158,14 +1158,14 @@ Parser::DeclTy *Parser::ParseObjCInstanceMethodDefinition() {

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??
Expand All @@ -1175,9 +1175,9 @@ Parser::DeclTy *Parser::ParseObjCClassMethodDefinition() {
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) {
Expand Down
30 changes: 20 additions & 10 deletions Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,17 +330,17 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
// @ 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();
}
Expand Down Expand Up @@ -467,7 +467,7 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {

/// 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);
Expand All @@ -477,7 +477,7 @@ Parser::DeclTy *Parser::ObjcParseMethodDefinition(DeclTy *D) {

// If we didn't find the '{', bail out.
if (Tok.isNot(tok::l_brace))
return 0;
return;
}

SourceLocation BraceLoc = Tok.getLocation();
Expand All @@ -487,9 +487,19 @@ Parser::DeclTy *Parser::ObjcParseMethodDefinition(DeclTy *D) {

// 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
Expand Down
1 change: 1 addition & 0 deletions Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ class Sema : public Action {
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);
Expand Down
28 changes: 28 additions & 0 deletions Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,34 @@ Sema::DeclTy *Sema::ActOnFunctionDefBody(DeclTy *D, StmtTy *Body) {
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) {
Expand Down
5 changes: 5 additions & 0 deletions include/clang/AST/DeclObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ class ObjcMethodDecl : public Decl {
/// 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,
Expand Down Expand Up @@ -300,6 +302,9 @@ class ObjcMethodDecl : public Decl {
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; }
Expand Down
5 changes: 4 additions & 1 deletion include/clang/Parse/Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class Action {
}

virtual DeclTy *ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
// Default to ActOnDeclarator.
// Default to ObjcActOnMethodDefinition.
return ObjcActOnMethodDefinition(FnBodyScope, D, 0);
}

Expand All @@ -146,6 +146,9 @@ class Action {
return Decl;
}

virtual void ActOnMethodDefBody(DeclTy *Decl, StmtTy *Body) {
return;
}

/// ActOnPopScope - This callback is called immediately before the specified
/// scope is popped and deleted.
Expand Down
6 changes: 3 additions & 3 deletions include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ class Parser {
DeclTy *ParseExternalDeclaration();
DeclTy *ParseDeclarationOrFunctionDefinition();
DeclTy *ParseFunctionDefinition(Declarator &D);
DeclTy *ObjcParseMethodDefinition(DeclTy *D);
void ObjcParseMethodDefinition(DeclTy *D);
void ParseKNRParamDeclarations(Declarator &D);
void ParseSimpleAsm();
void ParseAsmStringLiteral();
Expand Down Expand Up @@ -302,8 +302,8 @@ class Parser {
void ParseObjCPropertyAttribute(ObjcDeclSpec &DS);
DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);

DeclTy *ParseObjCInstanceMethodDefinition();
DeclTy *ParseObjCClassMethodDefinition();
void ParseObjCInstanceMethodDefinition();
void ParseObjCClassMethodDefinition();

//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
Expand Down

0 comments on commit 60fbca0

Please sign in to comment.