[cfe-commits] r41667 - in /cfe/trunk: Parse/ParseObjc.cpp include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h
Fariborz Jahanian
fjahanian at apple.com
Fri Aug 31 17:26:16 PDT 2007
Author: fjahanian
Date: Fri Aug 31 19:26:16 2007
New Revision: 41667
URL: http://llvm.org/viewvc/llvm-project?rev=41667&view=rev
Log:
Patch to parse @implementation prologue, method definitions,
objc2's @synthesize and @dynamic.
Modified:
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/include/clang/Basic/TokenKinds.def
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=41667&r1=41666&r2=41667&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Fri Aug 31 19:26:16 2007
@@ -37,11 +37,15 @@
case tok::objc_protocol:
return ParseObjCAtProtocolDeclaration(AtLoc);
case tok::objc_implementation:
- return ParseObjCAtImplementationDeclaration();
+ return ParseObjCAtImplementationDeclaration(AtLoc);
case tok::objc_end:
- return ParseObjCAtEndDeclaration();
+ return ParseObjCAtEndDeclaration(AtLoc);
case tok::objc_compatibility_alias:
return ParseObjCAtAliasDeclaration();
+ case tok::objc_synthesize:
+ return ParseObjCPropertySynthesize(AtLoc);
+ case tok::objc_dynamic:
+ return ParseObjCPropertyDynamic(AtLoc);
default:
Diag(AtLoc, diag::err_unexpected_at);
SkipUntil(tok::semi);
@@ -232,7 +236,7 @@
}
}
if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
- ParseObjCMethodPrototype();
+ ParseObjCMethodPrototype(true);
continue;
}
if (Tok.getKind() == tok::semi)
@@ -339,8 +343,9 @@
}
/// objc-methodproto:
-/// objc-instance-method objc-method-decl objc-method-attributes[opt] ';'
-/// objc-class-method objc-method-decl objc-method-attributes[opt] ';'
+/// objc-instance-method objc-method-decl objc-method-attributes[opt]
+/// ';'[opt]
+/// objc-class-method objc-method-decl objc-method-attributes[opt] ';'[opt]
///
/// objc-instance-method: '-'
/// objc-class-method: '+'
@@ -348,7 +353,7 @@
/// objc-method-attributes: [OBJC2]
/// __attribute__((deprecated))
///
-void Parser::ParseObjCMethodPrototype() {
+void Parser::ParseObjCMethodPrototype(bool decl) {
assert((Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) &&
"expected +/-");
@@ -362,8 +367,9 @@
if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
ParseAttributes();
- // Consume the ';'.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
+ if (decl)
+ // Consume the ';'.
+ ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
}
/// objc-selector:
@@ -700,12 +706,60 @@
/// objc-category-implementation-prologue:
/// @implementation identifier ( identifier )
-Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration() {
- assert(0 && "Unimp");
+Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration(
+ SourceLocation atLoc) {
+ assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
+ "ParseObjCAtImplementationDeclaration(): Expected @implementation");
+ ConsumeToken(); // the "implementation" identifier
+
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident); // missing class or category name.
+ return 0;
+ }
+ // We have a class or category name - consume it.
+ SourceLocation nameLoc = ConsumeToken(); // consume class or category name
+
+ if (Tok.getKind() == tok::l_paren) {
+ // we have a category implementation.
+ SourceLocation lparenLoc = ConsumeParen();
+ SourceLocation categoryLoc, rparenLoc;
+ IdentifierInfo *categoryId = 0;
+
+ if (Tok.getKind() == tok::identifier) {
+ categoryId = Tok.getIdentifierInfo();
+ categoryLoc = ConsumeToken();
+ } else {
+ Diag(Tok, diag::err_expected_ident); // missing category name.
+ return 0;
+ }
+ if (Tok.getKind() != tok::r_paren) {
+ Diag(Tok, diag::err_expected_rparen);
+ SkipUntil(tok::r_paren, false); // don't stop at ';'
+ return 0;
+ }
+ rparenLoc = ConsumeParen();
+ return 0;
+ }
+ // We have a class implementation
+ if (Tok.getKind() == tok::colon) {
+ // We have a super class
+ ConsumeToken();
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident); // missing super class name.
+ return 0;
+ }
+ ConsumeToken(); // Consume super class name
+ }
+ if (Tok.getKind() == tok::l_brace)
+ ParseObjCClassInstanceVariables(0/*FIXME*/); // we have ivars
+
return 0;
}
-Parser::DeclTy *Parser::ParseObjCAtEndDeclaration() {
- assert(0 && "Unimp");
+Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
+ assert(Tok.isObjCAtKeyword(tok::objc_end) &&
+ "ParseObjCAtEndDeclaration(): Expected @end");
+ ConsumeToken(); // the "end" identifier
+
return 0;
}
Parser::DeclTy *Parser::ParseObjCAtAliasDeclaration() {
@@ -713,12 +767,104 @@
return 0;
}
+/// property-synthesis:
+/// @synthesize property-ivar-list ';'
+///
+/// property-ivar-list:
+/// property-ivar
+/// property-ivar-list ',' property-ivar
+///
+/// property-ivar:
+/// identifier
+/// identifier '=' identifier
+///
+Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
+ assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
+ "ParseObjCPropertyDynamic(): Expected '@synthesize'");
+ SourceLocation loc = ConsumeToken(); // consume dynamic
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident);
+ return 0;
+ }
+ while (Tok.getKind() == tok::identifier) {
+ ConsumeToken(); // consume property name
+ if (Tok.getKind() == tok::equal) {
+ // property '=' ivar-name
+ ConsumeToken(); // consume '='
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident);
+ break;
+ }
+ ConsumeToken(); // consume ivar-name
+ }
+ if (Tok.getKind() != tok::comma)
+ break;
+ ConsumeToken(); // consume ','
+ }
+ if (Tok.getKind() != tok::semi)
+ Diag(Tok, diag::err_expected_semi_after, "@synthesize");
+ return 0;
+}
+
+/// property-dynamic:
+/// @dynamic property-list
+///
+/// property-list:
+/// identifier
+/// property-list ',' identifier
+///
+Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
+ assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
+ "ParseObjCPropertyDynamic(): Expected '@dynamic'");
+ SourceLocation loc = ConsumeToken(); // consume dynamic
+ if (Tok.getKind() != tok::identifier) {
+ Diag(Tok, diag::err_expected_ident);
+ return 0;
+ }
+ while (Tok.getKind() == tok::identifier) {
+ ConsumeToken(); // consume property name
+ if (Tok.getKind() != tok::comma)
+ break;
+ ConsumeToken(); // consume ','
+ }
+ if (Tok.getKind() != tok::semi)
+ Diag(Tok, diag::err_expected_semi_after, "@dynamic");
+ return 0;
+}
+
+/// objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+///
void Parser::ParseObjCInstanceMethodDefinition() {
- assert(0 && "Parser::ParseObjCInstanceMethodDefinition():: Unimp");
+ assert(Tok.getKind() == tok::minus &&
+ "ParseObjCInstanceMethodDefinition(): Expected '-'");
+ ParseObjCMethodPrototype(false);
+ // parse optional ';'
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+
+ if (Tok.getKind() != tok::l_brace) {
+ Diag (Tok, diag::err_expected_lbrace);
+ return;
+ }
+
+ StmtResult FnBody = ParseCompoundStatementBody();
}
+/// objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+///
void Parser::ParseObjCClassMethodDefinition() {
- assert(0 && "Parser::ParseObjCClassMethodDefinition():: Unimp");
+ assert(Tok.getKind() == tok::plus &&
+ "ParseObjCClassMethodDefinition(): Expected '+'");
+ ParseObjCMethodPrototype(false);
+ // parse optional ';'
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+ if (Tok.getKind() != tok::l_brace) {
+ Diag (Tok, diag::err_expected_lbrace);
+ return;
+ }
+
+ StmtResult FnBody = ParseCompoundStatementBody();
}
Parser::ExprResult Parser::ParseObjCExpression() {
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=41667&r1=41666&r2=41667&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri Aug 31 19:26:16 2007
@@ -347,11 +347,12 @@
OBJC1_AT_KEYWORD(finally)
OBJC1_AT_KEYWORD(synchronized)
-// I'm guessing this is an objc2 keyword, what are the others?
OBJC2_AT_KEYWORD(property)
OBJC2_AT_KEYWORD(package)
OBJC2_AT_KEYWORD(required)
OBJC2_AT_KEYWORD(optional)
+OBJC2_AT_KEYWORD(synthesize)
+OBJC2_AT_KEYWORD(dynamic)
// TODO: What to do about context-sensitive keywords like:
// bycopy/byref/in/inout/oneway/out?
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=41667&r1=41666&r2=41667&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Aug 31 19:26:16 2007
@@ -262,9 +262,11 @@
bool ParseObjCProtocolReferences();
void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
- DeclTy *ParseObjCAtImplementationDeclaration();
- DeclTy *ParseObjCAtEndDeclaration();
+ DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
+ DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
DeclTy *ParseObjCAtAliasDeclaration();
+ DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc);
+ DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc);
IdentifierInfo *ParseObjCSelector();
// Definitions for Objective-c context sensitive keywords recognition.
@@ -284,7 +286,7 @@
void ParseObjCTypeName();
void ParseObjCMethodRequirement();
- void ParseObjCMethodPrototype();
+ void ParseObjCMethodPrototype(bool decl);
void ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
More information about the cfe-commits
mailing list