summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2009-07-20 11:46:59 +0200
committerErik Verbruggen <erik.verbruggen@nokia.com>2009-07-20 11:46:59 +0200
commit336e1dc5fb596ff7ed84e3a405a1efd578ee4330 (patch)
treea9973006aa82733a3b5cad24f23fc35bf22ec49c /src/shared/cplusplus
parent0eef527746703c067dff7de84a90d71e4509c361 (diff)
downloadqt-creator-336e1dc5fb596ff7ed84e3a405a1efd578ee4330.tar.gz
Fixes for the ObjC AST. Now it should be complete.
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp31
-rw-r--r--src/shared/cplusplus/AST.h41
-rw-r--r--src/shared/cplusplus/ASTClone.cpp17
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp31
-rw-r--r--src/shared/cplusplus/ASTVisitor.h4
-rw-r--r--src/shared/cplusplus/ASTfwd.h2
-rw-r--r--src/shared/cplusplus/Parser.cpp84
-rw-r--r--src/shared/cplusplus/Parser.h4
8 files changed, 183 insertions, 31 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index e8ecfa07cd..0eae1bd0fe 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -1997,7 +1997,10 @@ unsigned ObjCClassInterfaceDeclarationAST::lastToken() const
unsigned ObjCCategoryInterfaceDeclarationAST::firstToken() const
{
- return interface_token;
+ if (attributes)
+ return attributes->firstToken();
+ else
+ return interface_token;
}
unsigned ObjCCategoryInterfaceDeclarationAST::lastToken() const
@@ -2319,6 +2322,32 @@ unsigned ObjCMethodPrototypeAST::lastToken() const
return method_type_token + 1;
}
+unsigned ObjCMethodDeclarationAST::firstToken() const
+{
+ return method_prototype->firstToken();
+}
+
+unsigned ObjCMethodDeclarationAST::lastToken() const
+{
+ if (semicolon_token)
+ return semicolon_token + 1;
+ else
+ return method_prototype->lastToken();
+}
+
+unsigned ObjCMethodDefinitionAST::firstToken() const
+{
+ return method_prototype->firstToken();
+}
+
+unsigned ObjCMethodDefinitionAST::lastToken() const
+{
+ if (function_body)
+ return function_body->lastToken();
+ else
+ return method_prototype->lastToken();
+}
+
unsigned ObjCClassImplementationAST::firstToken() const
{
return implementation_token;
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index f6ab2626eb..cbbbc5da69 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -2511,6 +2511,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCCategoryInterfaceDeclarationAST: public DeclarationAST
{
public:
+ SpecifierAST *attributes;
unsigned interface_token;
unsigned class_identifier_token;
unsigned lparen_token;
@@ -2862,7 +2863,7 @@ protected:
virtual void accept0(ASTVisitor *visitor);
};
-class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public DeclarationAST
+class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public AST
{
public:
unsigned method_type_token;
@@ -2883,6 +2884,44 @@ protected:
virtual void accept0(ASTVisitor *visitor);
};
+class CPLUSPLUS_EXPORT ObjCMethodDeclarationAST: public DeclarationAST
+{
+public:
+ ObjCMethodPrototypeAST *method_prototype;
+ unsigned semicolon_token;
+
+public:
+ virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCMethodDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCMethodDefinitionAST: public DeclarationAST
+{
+public:
+ ObjCMethodPrototypeAST *method_prototype;
+ StatementAST *function_body;
+
+public:
+ virtual ObjCMethodDefinitionAST *asObjCMethodDefinition()
+ { return this; }
+
+ virtual unsigned firstToken() const;
+ virtual unsigned lastToken() const;
+
+ virtual ObjCMethodDefinitionAST *clone(MemoryPool *pool) const;
+
+protected:
+ virtual void accept0(ASTVisitor *visitor);
+};
+
class CPLUSPLUS_EXPORT ObjCClassImplementationAST: public DeclarationAST
{
public:
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 1e160ae274..3340a39f25 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1246,6 +1246,7 @@ ObjCCategoryInterfaceDeclarationAST *ObjCCategoryInterfaceDeclarationAST::clone(
ObjCCategoryInterfaceDeclarationAST *ast = new (pool) ObjCCategoryInterfaceDeclarationAST;
// copy DeclarationAST
// copy ObjCCategoryInterfaceDeclarationAST
+ if (attributes) ast->attributes = attributes->clone(pool);
ast->interface_token = interface_token;
ast->class_identifier_token = class_identifier_token;
if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
@@ -1420,6 +1421,22 @@ ObjCMethodPrototypeAST *ObjCMethodPrototypeAST::clone(MemoryPool *pool) const
return ast;
}
+ObjCMethodDeclarationAST *ObjCMethodDeclarationAST::clone(MemoryPool *pool) const
+{
+ ObjCMethodDeclarationAST *ast = new (pool) ObjCMethodDeclarationAST;
+ if (method_prototype) ast->method_prototype = method_prototype->clone(pool);
+ ast->semicolon_token = semicolon_token;
+ return ast;
+}
+
+ObjCMethodDefinitionAST *ObjCMethodDefinitionAST::clone(MemoryPool *pool) const
+{
+ ObjCMethodDefinitionAST *ast = new (pool) ObjCMethodDefinitionAST;
+ if (method_prototype) ast->method_prototype = method_prototype->clone(pool);
+ if (function_body) ast->function_body = function_body->clone(pool);
+ return ast;
+}
+
ObjCClassImplementationAST *ObjCClassImplementationAST::clone(MemoryPool *pool) const
{
ObjCClassImplementationAST *ast = new (pool) ObjCClassImplementationAST;
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 98fe8a84ad..9b43a34bfd 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1159,7 +1159,12 @@ void ObjCCategoryInterfaceDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
// visit ObjCCategoryInterfaceDeclarationAST
- accept(protocol_refs, visitor);
+ if (attributes)
+ accept(attributes, visitor);
+ if (protocol_refs)
+ accept(protocol_refs, visitor);
+ if (member_declarations)
+ accept(member_declarations, visitor);
// visit DeclarationAST
}
visitor->endVisit(this);
@@ -1368,6 +1373,30 @@ void ObjCMethodPrototypeAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
+void ObjCMethodDeclarationAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCMethodDeclarationAST
+ if (method_prototype)
+ accept(method_prototype, visitor);
+ // visit DeclarationAST
+ }
+ visitor->endVisit(this);
+}
+
+void ObjCMethodDefinitionAST::accept0(ASTVisitor *visitor)
+{
+ if (visitor->visit(this)) {
+ // visit ObjCMethodDefinitionAST
+ if (method_prototype)
+ accept(method_prototype, visitor);
+ if (function_body)
+ accept(function_body, visitor);
+ // visit DeclarationAST
+ }
+ visitor->endVisit(this);
+}
+
void ObjCClassImplementationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 5279d290f5..dc289fdcb5 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -215,6 +215,8 @@ public:
virtual bool visit(ObjcPropertyAttributeListAST *) { return true; }
virtual bool visit(ObjCPropertyDeclarationAST *) { return true; }
virtual bool visit(ObjCMethodPrototypeAST *) { return true; }
+ virtual bool visit(ObjCMethodDeclarationAST *) { return true; }
+ virtual bool visit(ObjCMethodDefinitionAST *) { return true; }
virtual bool visit(ObjCMessageArgumentDeclarationListAST *) { return true; }
virtual bool visit(ObjCMessageArgumentDeclarationAST *) { return true; }
virtual bool visit(ObjCClassImplementationAST *) { return true; }
@@ -350,6 +352,8 @@ public:
virtual void endVisit(ObjcPropertyAttributeListAST *) { }
virtual void endVisit(ObjCPropertyDeclarationAST *) { }
virtual void endVisit(ObjCMethodPrototypeAST *) { }
+ virtual void endVisit(ObjCMethodDeclarationAST *) { }
+ virtual void endVisit(ObjCMethodDefinitionAST *) { }
virtual void endVisit(ObjCMessageArgumentDeclarationListAST *) { }
virtual void endVisit(ObjCMessageArgumentDeclarationAST *) { }
virtual void endVisit(ObjCClassImplementationAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index 5416856614..a6ad826175 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -188,6 +188,8 @@ class ObjCPropertyDeclarationAST;
class ObjcPropertyAttributeListAST;
class ObjcPropertyAttributeAST;
class ObjCMethodPrototypeAST;
+class ObjCMethodDeclarationAST;
+class ObjCMethodDefinitionAST;
class ObjCMessageArgumentDeclarationListAST;
class ObjCMessageArgumentDeclarationAST;
class ObjCCategoryImplementationAST;
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 2856e07622..616d2ed3e2 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -63,7 +63,6 @@ Parser::Parser(TranslationUnit *unit)
: _translationUnit(unit),
_control(_translationUnit->control()),
_pool(_translationUnit->memoryPool()),
- _objcInContextKeyword(_control->findOrInsertIdentifier("in")),
_tokenIndex(1),
_templateArguments(0),
_qtMocRunEnabled(false),
@@ -2178,16 +2177,19 @@ bool Parser::parseForStatement(StatementAST *&node)
unsigned for_token = consumeToken();
unsigned lparen_token = 0;
match(T_LPAREN, &lparen_token);
+
+ // FIXME: for ObjC fast enumeration, this needs a semicolon before the "in" token, which is obviously wrong.
StatementAST *initializer = 0;
parseForInitStatement(initializer);
+ unsigned in_token = 0;
- if (LA() == T_IDENTIFIER && tok().identifier == _objcInContextKeyword) {
+ if (parseObjCContextKeyword(Token_in, in_token)) {
ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST;
ast->for_token = for_token;
ast->lparen_token = lparen_token;
ast->initializer = initializer;
- ast->in_token = consumeToken();
+ ast->in_token = in_token;
parseExpression(ast->fast_enumeratable_expression);
match(T_RPAREN, &ast->rparen_token);
parseStatement(ast->body_statement);
@@ -3978,7 +3980,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
"invalid attributes for category interface declaration");
ObjCCategoryInterfaceDeclarationAST *ast = new (_pool) ObjCCategoryInterfaceDeclarationAST;
- // TODO: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...)
+ ast->attributes = attributes;
ast->interface_token = objc_interface_token;
ast->class_identifier_token = identifier_token;
@@ -4169,27 +4171,28 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
case T_AT_SYNTHESIZE: {
ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
ast->synthesized_token = consumeToken();
- // TODO EV
- unsigned identifier_token = 0;
- match(T_IDENTIFIER, &identifier_token);
+ ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
+ ast->property_identifiers = last;
+ last->synthesized_property = new (_pool) ObjCSynthesizedPropertyAST;
+ match(T_IDENTIFIER, &(last->synthesized_property->property_identifier));
if (LA() == T_EQUAL) {
- consumeToken();
+ last->synthesized_property->equals_token = consumeToken();
- unsigned aliassed_identifier_token = 0;
- match(T_IDENTIFIER, &aliassed_identifier_token);
+ match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier));
}
while (LA() == T_COMMA) {
- consumeToken();
+ last->comma_token = consumeToken();
+ last->next = new (_pool) ObjCSynthesizedPropertyListAST;
+ last = last->next;
- match(T_IDENTIFIER, &identifier_token);
+ match(T_IDENTIFIER, &(last->synthesized_property->property_identifier));
if (LA() == T_EQUAL) {
- consumeToken();
+ last->synthesized_property->equals_token = consumeToken();
- unsigned aliassed_identifier_token = 0;
- match(T_IDENTIFIER, &aliassed_identifier_token);
+ match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier));
}
}
@@ -4246,16 +4249,24 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
bool Parser::parseObjCMethodDefinition(DeclarationAST *&node)
{
- // TODO EV:
- DeclarationAST *ast = 0;
- if (! parseObjCMethodPrototype(ast))
+ ObjCMethodPrototypeAST *method_prototype;
+ if (! parseObjCMethodPrototype(method_prototype))
return false;
- if (LA() == T_SEMICOLON)
- consumeToken();
+ if (LA() == T_SEMICOLON) {
+ // method declaration:
+ ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
+ ast->method_prototype = method_prototype;
+ ast->semicolon_token = consumeToken();
+ node = ast;
+ } else {
+ // method definition:
+ ObjCMethodDefinitionAST *ast = new (_pool) ObjCMethodDefinitionAST;
+ ast->method_prototype = method_prototype;
+ parseFunctionBody(ast->function_body);
+ node = ast;
+ }
- StatementAST *function_body = 0;
- parseFunctionBody(function_body);
return true;
}
@@ -4350,8 +4361,16 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
}
case T_PLUS:
- case T_MINUS:
- return parseObjCMethodPrototype(node);
+ case T_MINUS: {
+ ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
+ if (parseObjCMethodPrototype(ast->method_prototype)) {
+ match(T_SEMICOLON, &(ast->semicolon_token));
+ node = ast;
+ return true;
+ } else {
+ return false;
+ }
+ }
case T_ENUM:
case T_CLASS:
@@ -4431,7 +4450,7 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a
// objc-method-decl ::= objc-type-name? objc-selector
// objc-method-decl ::= objc-type-name? objc-keyword-decl-list objc-parmlist-opt
//
-bool Parser::parseObjCMethodPrototype(DeclarationAST *&node)
+bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
{
if (LA() != T_PLUS && LA() != T_MINUS)
return false;
@@ -4455,7 +4474,7 @@ bool Parser::parseObjCMethodPrototype(DeclarationAST *&node)
(*last)->argument_declaration = declaration;
}
- // TODO: err, what does this parse?
+ // TODO EV: get this in the ast
while (LA() == T_COMMA) {
consumeToken();
@@ -4571,4 +4590,17 @@ bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
return true;
}
+bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token)
+{
+ if (LA() != T_IDENTIFIER)
+ return false;
+
+ Identifier *id = tok().identifier;
+ const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
+ if (k != kind)
+ return false;
+ in_token = consumeToken();
+ return true;
+}
+
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index df017209e1..5fd5253e34 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -238,12 +238,13 @@ public:
bool parseObjCPropertyDeclaration(DeclarationAST *&node,
SpecifierAST *attributes = 0);
bool parseObjCImplementation(DeclarationAST *&node);
- bool parseObjCMethodPrototype(DeclarationAST *&node);
+ bool parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node);
bool parseObjCPropertyAttribute(ObjcPropertyAttributeAST *&node);
bool parseObjCTypeName(ObjCTypeNameAST *&node);
bool parseObjCSelector(unsigned &selector_token);
bool parseObjCKeywordDeclaration(ObjCMessageArgumentDeclarationAST *&node);
bool parseObjCTypeQualifiers(unsigned &type_qualifier);
+ bool parseObjCContextKeyword(int kind, unsigned &in_token);
bool lookAtObjCSelector() const;
@@ -287,7 +288,6 @@ private:
TranslationUnit *_translationUnit;
Control *_control;
MemoryPool *_pool;
- Identifier *_objcInContextKeyword;
unsigned _tokenIndex;
bool _templateArguments: 1;
bool _qtMocRunEnabled: 1;