summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2009-10-05 18:02:01 +0200
committerErik Verbruggen <erik.verbruggen@nokia.com>2009-10-05 18:02:01 +0200
commitf1e665463b221ff33d714d55683033afdaf46576 (patch)
treea580aec2664c9977be748d6f93c7d295bb854a50 /src/shared/cplusplus
parentb43f279227e7eb074f68f2222a908c568b1e749e (diff)
downloadqt-creator-f1e665463b221ff33d714d55683033afdaf46576.tar.gz
Added protocol & class definedness checks, and added property attribute checks.
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp2
-rw-r--r--src/shared/cplusplus/AST.h1
-rw-r--r--src/shared/cplusplus/CPlusPlusForwardDeclarations.h2
-rw-r--r--src/shared/cplusplus/CheckDeclaration.cpp117
-rw-r--r--src/shared/cplusplus/CheckDeclaration.h5
-rw-r--r--src/shared/cplusplus/CheckDeclarator.cpp5
-rw-r--r--src/shared/cplusplus/CheckSpecifier.cpp4
-rw-r--r--src/shared/cplusplus/Control.cpp24
-rw-r--r--src/shared/cplusplus/Control.h3
-rw-r--r--src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp132
-rw-r--r--src/shared/cplusplus/ObjectiveCTypeQualifiers.h8
-rw-r--r--src/shared/cplusplus/Parser.cpp63
-rw-r--r--src/shared/cplusplus/Symbol.h7
-rw-r--r--src/shared/cplusplus/SymbolVisitor.h2
-rw-r--r--src/shared/cplusplus/Symbols.cpp26
-rw-r--r--src/shared/cplusplus/Symbols.h65
16 files changed, 430 insertions, 36 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 148cad3b95..21e8a1504c 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -2359,6 +2359,8 @@ unsigned ObjCMethodPrototypeAST::lastToken() const
{
if (attributes)
return attributes->lastToken();
+ else if (dot_dot_dot_token)
+ return dot_dot_dot_token + 1;
else if (arguments)
return arguments->lastToken();
else if (type_name)
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index b118a1dd16..4af1971e2e 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -2994,6 +2994,7 @@ public:
ObjCTypeNameAST *type_name;
ObjCSelectorAST *selector;
ObjCMessageArgumentDeclarationListAST *arguments;
+ unsigned dot_dot_dot_token;
SpecifierAST *attributes;
public: // annotations
diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
index eaa49eb173..2467d4c56b 100644
--- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
+++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
@@ -137,6 +137,8 @@ class ForwardClassDeclaration;
class Token;
// Objective-C symbols
+class ObjCBaseClass;
+class ObjCBaseProtocol;
class ObjCClass;
class ObjCForwardClassDeclaration;
class ObjCProtocol;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 69e645b1be..4b2604de40 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -57,6 +57,7 @@
#include "Control.h"
#include "Literals.h"
#include <cassert>
+#include <QtCore/QByteArray>
CPLUSPLUS_BEGIN_NAMESPACE
@@ -506,11 +507,25 @@ bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast)
ObjCProtocol *protocol = control()->newObjCProtocol(sourceLocation, protocolName);
protocol->setStartOffset(tokenAt(ast->firstToken()).offset);
protocol->setEndOffset(tokenAt(ast->lastToken()).offset);
- ast->symbol = protocol;
+ if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
+ for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
+ NameAST* name = iter->name;
+ Name *protocolName = semantic()->check(name, _scope);
+ ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
+ protocol->addProtocol(baseProtocol);
+ }
+ }
+
+ int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Public);
+ for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) {
+ semantic()->check(it->declaration, protocol->members());
+ }
+ (void) semantic()->switchObjCVisibility(previousObjCVisibility);
+
+ ast->symbol = protocol;
_scope->enterSymbol(protocol);
- // TODO EV: walk protocols and method prototypes
return false;
}
@@ -562,7 +577,21 @@ bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast)
klass->setCategoryName(categoryName);
}
- // TODO: super-class, and protocols (EV)
+ if (ast->superclass) {
+ Name *superClassName = semantic()->check(ast->superclass, _scope);
+ ObjCBaseClass *superKlass = control()->newObjCBaseClass(ast->superclass->firstToken(), superClassName);
+ klass->setBaseClass(superKlass);
+ }
+
+ if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
+ for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
+ NameAST* name = iter->name;
+ Name *protocolName = semantic()->check(name, _scope);
+ ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
+ klass->addProtocol(baseProtocol);
+ }
+ }
+
_scope->enterSymbol(klass);
int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Protected);
@@ -627,4 +656,86 @@ bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast)
return false;
}
+enum PropertyAttributes {
+ None = 0,
+ Assign = 1 << 0,
+ Retain = 1 << 1,
+ Copy = 1 << 2,
+ ReadOnly = 1 << 3,
+ ReadWrite = 1 << 4,
+ Getter = 1 << 5,
+ Setter = 1 << 6,
+ NonAtomic = 1 << 7,
+
+ WritabilityMask = ReadOnly | ReadWrite,
+ SetterSemanticsMask = Assign | Retain | Copy,
+};
+
+bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
+ int &flags,
+ int attr)
+{
+ if (flags & attr) {
+ translationUnit()->warning(attrAst->attribute_identifier_token,
+ "duplicate property attribute \"%s\"",
+ spell(attrAst->attribute_identifier_token));
+ return false;
+ } else {
+ flags |= attr;
+ return true;
+ }
+}
+
+bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
+{
+ int propAttrs = None;
+
+ for (ObjCPropertyAttributeListAST *iter= ast->property_attributes; iter; iter = iter->next) {
+ ObjCPropertyAttributeAST *attrAst = iter->attr;
+ if (!attrAst)
+ continue;
+
+ const char *attrName = spell(attrAst->attribute_identifier_token);
+ if (!qstrcmp("getter", attrName)) {
+ if (checkPropertyAttribute(attrAst, propAttrs, Getter)) {
+ // TODO: find method declaration for getter
+ }
+ } else if (!qstrcmp("setter", attrName)) {
+ if (checkPropertyAttribute(attrAst, propAttrs, Setter)) {
+ // TODO: find method declaration for setter
+ }
+ } else if (!qstrcmp("readwrite", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, ReadWrite);
+ } else if (!qstrcmp("readonly", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, ReadOnly);
+ } else if (!qstrcmp("assign", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, Assign);
+ } else if (!qstrcmp("retain", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, Retain);
+ } else if (!qstrcmp("copy", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, Copy);
+ } else if (!qstrcmp("nonatomic", attrName)) {
+ checkPropertyAttribute(attrAst, propAttrs, NonAtomic);
+ }
+ }
+
+ if (propAttrs & ReadOnly && propAttrs & ReadWrite)
+ // Should this be an error instead of only a warning?
+ translationUnit()->warning(ast->property_token,
+ "property can have at most one attribute \"readonly\" or \"readwrite\" specified");
+ int setterSemAttrs = propAttrs & SetterSemanticsMask;
+ if (setterSemAttrs
+ && setterSemAttrs != Assign
+ && setterSemAttrs != Retain
+ && setterSemAttrs != Copy) {
+ // Should this be an error instead of only a warning?
+ translationUnit()->warning(ast->property_token,
+ "property can have at most one attribute \"assign\", \"retain\", or \"copy\" specified");
+ }
+
+ // TODO: Check if the next line is correct (EV)
+ semantic()->check(ast->simple_declaration, _scope);
+ return false;
+}
+
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h
index 27869c75ca..93ef59f941 100644
--- a/src/shared/cplusplus/CheckDeclaration.h
+++ b/src/shared/cplusplus/CheckDeclaration.h
@@ -97,8 +97,13 @@ protected:
virtual bool visit(ObjCClassForwardDeclarationAST *ast);
virtual bool visit(ObjCMethodDeclarationAST *ast);
virtual bool visit(ObjCVisibilityDeclarationAST *ast);
+ virtual bool visit(ObjCPropertyDeclarationAST *ast);
private:
+ bool checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
+ int &flags,
+ int attr);
+private:
DeclarationAST *_declaration;
Scope *_scope;
TemplateParameters *_templateParameters;
diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp
index 5186055bca..5867d6180a 100644
--- a/src/shared/cplusplus/CheckDeclarator.cpp
+++ b/src/shared/cplusplus/CheckDeclarator.cpp
@@ -265,14 +265,15 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
method->setReturnType(returnType);
if (ast->selector && ast->selector->asObjCSelectorWithArguments()) {
- // TODO: check the parameters (EV)
- // fun->setVariadic(...);
// TODO: add arguments (EV)
for (ObjCMessageArgumentDeclarationListAST *it = ast->arguments; it; it = it->next) {
ObjCMessageArgumentDeclarationAST *argDecl = it->argument_declaration;
semantic()->check(argDecl, method->arguments());
}
+
+ if (ast->dot_dot_dot_token)
+ method->setVariadic(true);
}
_fullySpecifiedType = FullySpecifiedType(method);
diff --git a/src/shared/cplusplus/CheckSpecifier.cpp b/src/shared/cplusplus/CheckSpecifier.cpp
index 9cbef35377..d4de2c5517 100644
--- a/src/shared/cplusplus/CheckSpecifier.cpp
+++ b/src/shared/cplusplus/CheckSpecifier.cpp
@@ -416,8 +416,8 @@ bool CheckSpecifier::visit(AttributeSpecifierAST *ast)
bool CheckSpecifier::visit(ObjCTypeNameAST * /*ast*/)
{
// TODO: implement this (EV)
- _fullySpecifiedType = FullySpecifiedType();
- return false;
+// _fullySpecifiedType = FullySpecifiedType();
+ return true;
}
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp
index 07e46fd1ae..6338d99fd2 100644
--- a/src/shared/cplusplus/Control.cpp
+++ b/src/shared/cplusplus/Control.cpp
@@ -128,6 +128,8 @@ public:
delete_array_entries(enums);
delete_array_entries(usingDeclarations);
delete_array_entries(classForwardDeclarations);
+ delete_array_entries(objcBaseClasses);
+ delete_array_entries(objcBaseProtocols);
delete_array_entries(objcClasses);
delete_array_entries(objcProtocols);
delete_array_entries(objcForwardClassDeclarations);
@@ -348,6 +350,20 @@ public:
return c;
}
+ ObjCBaseClass *newObjCBaseClass(unsigned sourceLocation, Name *name)
+ {
+ ObjCBaseClass *c = new ObjCBaseClass(translationUnit, sourceLocation, name);
+ objcBaseClasses.push_back(c);
+ return c;
+ }
+
+ ObjCBaseProtocol *newObjCBaseProtocol(unsigned sourceLocation, Name *name)
+ {
+ ObjCBaseProtocol *p = new ObjCBaseProtocol(translationUnit, sourceLocation, name);
+ objcBaseProtocols.push_back(p);
+ return p;
+ }
+
ObjCClass *newObjCClass(unsigned sourceLocation, Name *name)
{
ObjCClass *c = new ObjCClass(translationUnit, sourceLocation, name);
@@ -561,6 +577,8 @@ public:
std::vector<Enum *> enums;
std::vector<UsingDeclaration *> usingDeclarations;
std::vector<ForwardClassDeclaration *> classForwardDeclarations;
+ std::vector<ObjCBaseClass *> objcBaseClasses;
+ std::vector<ObjCBaseProtocol *> objcBaseProtocols;
std::vector<ObjCClass *> objcClasses;
std::vector<ObjCProtocol *> objcProtocols;
std::vector<ObjCForwardClassDeclaration *> objcForwardClassDeclarations;
@@ -740,6 +758,12 @@ ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLoca
Name *name)
{ return d->newForwardClassDeclaration(sourceLocation, name); }
+ObjCBaseClass *Control::newObjCBaseClass(unsigned sourceLocation, Name *name)
+{ return d->newObjCBaseClass(sourceLocation, name); }
+
+ObjCBaseProtocol *Control::newObjCBaseProtocol(unsigned sourceLocation, Name *name)
+{ return d->newObjCBaseProtocol(sourceLocation, name); }
+
ObjCClass *Control::newObjCClass(unsigned sourceLocation, Name *name)
{ return d->newObjCClass(sourceLocation, name); }
diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h
index 323740b742..060be182b6 100644
--- a/src/shared/cplusplus/Control.h
+++ b/src/shared/cplusplus/Control.h
@@ -166,6 +166,9 @@ public:
/// Creates a new ForwardClassDeclaration symbol.
ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name = 0);
+ ObjCBaseClass *newObjCBaseClass(unsigned sourceLocation, Name *name);
+ ObjCBaseProtocol *newObjCBaseProtocol(unsigned sourceLocation, Name *name);
+
/// Creates a new Objective-C class symbol.
ObjCClass *newObjCClass(unsigned sourceLocation, Name *name = 0);
diff --git a/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp b/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp
index fa2b7d3314..d12d7c322c 100644
--- a/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp
+++ b/src/shared/cplusplus/ObjectiveCTypeQualifiers.cpp
@@ -51,6 +51,19 @@ static inline int classify3(const char *s) {
return Token_identifier;
}
+static inline int classify4(const char *s) {
+ if (s[0] == 'c') {
+ if (s[1] == 'o') {
+ if (s[2] == 'p') {
+ if (s[3] == 'y') {
+ return Token_copy;
+ }
+ }
+ }
+ }
+ return Token_identifier;
+}
+
static inline int classify5(const char *s) {
if (s[0] == 'b') {
if (s[1] == 'y') {
@@ -78,7 +91,20 @@ static inline int classify5(const char *s) {
}
static inline int classify6(const char *s) {
- if (s[0] == 'b') {
+ if (s[0] == 'a') {
+ if (s[1] == 's') {
+ if (s[2] == 's') {
+ if (s[3] == 'i') {
+ if (s[4] == 'g') {
+ if (s[5] == 'n') {
+ return Token_assign;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0] == 'b') {
if (s[1] == 'y') {
if (s[2] == 'c') {
if (s[3] == 'o') {
@@ -91,6 +117,32 @@ static inline int classify6(const char *s) {
}
}
}
+ else if (s[0] == 'g') {
+ if (s[1] == 'e') {
+ if (s[2] == 't') {
+ if (s[3] == 't') {
+ if (s[4] == 'e') {
+ if (s[5] == 'r') {
+ return Token_getter;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0] == 's') {
+ if (s[1] == 'e') {
+ if (s[2] == 't') {
+ if (s[3] == 't') {
+ if (s[4] == 'e') {
+ if (s[5] == 'r') {
+ return Token_setter;
+ }
+ }
+ }
+ }
+ }
+ }
else if (s[0] == 'o') {
if (s[1] == 'n') {
if (s[2] == 'e') {
@@ -104,15 +156,93 @@ static inline int classify6(const char *s) {
}
}
}
+ else if (s[0] == 'r') {
+ if (s[1] == 'e') {
+ if (s[2] == 't') {
+ if (s[3] == 'a') {
+ if (s[4] == 'i') {
+ if (s[5] == 'n') {
+ return Token_retain;
+ }
+ }
+ }
+ }
+ }
+ }
return Token_identifier;
}
+static inline int classify8(const char *s) {
+ if (s[0] == 'r') {
+ if (s[1] == 'e') {
+ if (s[2] == 'a') {
+ if (s[3] == 'd') {
+ if (s[4] == 'o') {
+ if (s[5] == 'n') {
+ if (s[6] == 'l') {
+ if (s[7] == 'y') {
+ return Token_readonly;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Token_identifier;
+}
+
+static inline int classify9(const char *s) {
+ if (s[0] == 'n') {
+ if (s[1] == 'o') {
+ if (s[2] == 'n') {
+ if (s[3] == 'a') {
+ if (s[4] == 't') {
+ if (s[5] == 'o') {
+ if (s[6] == 'm') {
+ if (s[7] == 'i') {
+ if (s[8] == 'c') {
+ return Token_nonatomic;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (s[0] == 'r') {
+ if (s[1] == 'e') {
+ if (s[2] == 'a') {
+ if (s[3] == 'd') {
+ if (s[4] == 'w') {
+ if (s[5] == 'r') {
+ if (s[6] == 'i') {
+ if (s[7] == 't') {
+ if (s[8] == 'e') {
+ return Token_readwrite;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Token_identifier;
+}
+
int classifyObjectiveCTypeQualifiers(const char *s, int n) {
switch (n) {
case 2: return classify2(s);
case 3: return classify3(s);
+ case 4: return classify4(s);
case 5: return classify5(s);
case 6: return classify6(s);
+ case 8: return classify8(s);
+ case 9: return classify9(s);
default: return Token_identifier;
} // switch
}
diff --git a/src/shared/cplusplus/ObjectiveCTypeQualifiers.h b/src/shared/cplusplus/ObjectiveCTypeQualifiers.h
index 35a69e9299..0f9cdfd677 100644
--- a/src/shared/cplusplus/ObjectiveCTypeQualifiers.h
+++ b/src/shared/cplusplus/ObjectiveCTypeQualifiers.h
@@ -37,10 +37,18 @@ CPLUSPLUS_BEGIN_NAMESPACE
enum {
Token_in,
Token_out,
+ Token_copy,
Token_byref,
Token_inout,
+ Token_assign,
Token_bycopy,
+ Token_getter,
+ Token_retain,
+ Token_setter,
Token_oneway,
+ Token_readonly,
+ Token_nonatomic,
+ Token_readwrite,
Token_identifier
};
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 45905829fc..d335b5ebff 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -4544,7 +4544,13 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a
last->comma_token = consumeToken();
last->next = new (_pool) ObjCPropertyAttributeListAST;
last = last->next;
- parseObjCPropertyAttribute(last->attr);
+ if (!parseObjCPropertyAttribute(last->attr)) {
+ _translationUnit->error(_tokenIndex, "expected token `%s' got `%s'",
+ Token::name(T_IDENTIFIER), tok().spell());
+ while (LA() != T_RPAREN)
+ consumeToken();
+ break;
+ }
}
}
@@ -4597,15 +4603,15 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
lastArg->argument_declaration = declaration;
}
- // TODO EV: get this in the ast
while (LA() == T_COMMA) {
consumeToken();
if (LA() == T_DOT_DOT_DOT) {
- consumeToken();
+ ast->dot_dot_dot_token = consumeToken();
break;
}
+ // TODO: Is this still valid, and if so, should it be stored in the AST? (EV)
DeclarationAST *parameter_declaration = 0;
parseParameterDeclaration(parameter_declaration);
}
@@ -4639,28 +4645,43 @@ bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node)
return false;
node = new (_pool) ObjCPropertyAttributeAST;
- match(T_IDENTIFIER, &(node->attribute_identifier_token));
- if (LA() == T_EQUAL) {
- node->equals_token = consumeToken();
- unsigned identifier_token = 0;
- match(T_IDENTIFIER, &identifier_token);
+ Identifier *id = tok().identifier;
+ const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
+ switch (k) {
+ case Token_copy:
+ case Token_assign:
+ case Token_retain:
+ case Token_readonly:
+ case Token_readwrite:
+ case Token_nonatomic:
+ node->attribute_identifier_token = consumeToken();
+ return true;
- if (LA() == T_COLON) {
- ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST;
- selector->selector_arguments = new (_pool) ObjCSelectorArgumentListAST;
- selector->selector_arguments->argument = new (_pool) ObjCSelectorArgumentAST;
- selector->selector_arguments->argument->name_token = identifier_token;
- selector->selector_arguments->argument->colon_token = consumeToken();
- node->method_selector = selector;
- } else {
- ObjCSelectorWithoutArgumentsAST *selector = new (_pool) ObjCSelectorWithoutArgumentsAST;
- selector->name_token = identifier_token;
- node->method_selector = selector;
- }
+ case Token_getter: {
+ node->attribute_identifier_token = consumeToken();
+ match(T_EQUAL, &(node->equals_token));
+ ObjCSelectorWithoutArgumentsAST *selector = new (_pool) ObjCSelectorWithoutArgumentsAST;
+ match(T_IDENTIFIER, &(selector->name_token));
+ node->method_selector = selector;
+ return true;
}
- return true;
+ case Token_setter: {
+ node->attribute_identifier_token = consumeToken();
+ match(T_EQUAL, &(node->equals_token));
+ ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST;
+ selector->selector_arguments = new (_pool) ObjCSelectorArgumentListAST;
+ selector->selector_arguments->argument = new (_pool) ObjCSelectorArgumentAST;
+ match(T_IDENTIFIER, &(selector->selector_arguments->argument->name_token));
+ match(T_COLON, &(selector->selector_arguments->argument->colon_token));
+ node->method_selector = selector;
+ return true;
+ }
+
+ default:
+ return false;
+ }
}
// objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h
index d0de211a52..511e14c9f2 100644
--- a/src/shared/cplusplus/Symbol.h
+++ b/src/shared/cplusplus/Symbol.h
@@ -210,6 +210,9 @@ public:
/// Returns true if this Symbol is a ForwardClassDeclaration.
bool isForwardClassDeclaration() const;
+ bool isObjCBaseClass() const;
+ bool isObjCBaseProtocol() const;
+
/// Returns true if this Symbol is an Objective-C Class declaration.
bool isObjCClass() const;
@@ -237,6 +240,8 @@ public:
virtual const Argument *asArgument() const { return 0; }
virtual const BaseClass *asBaseClass() const { return 0; }
virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return 0; }
+ virtual const ObjCBaseClass *asObjCBaseClass() const { return 0; }
+ virtual const ObjCBaseProtocol *asObjCBaseProtocol() const { return 0; }
virtual const ObjCClass *asObjCClass() const { return 0; }
virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const { return 0; }
virtual const ObjCProtocol *asObjCProtocol() const { return 0; }
@@ -255,6 +260,8 @@ public:
virtual Argument *asArgument() { return 0; }
virtual BaseClass *asBaseClass() { return 0; }
virtual ForwardClassDeclaration *asForwardClassDeclaration() { return 0; }
+ virtual ObjCBaseClass *asObjCBaseClass() { return 0; }
+ virtual ObjCBaseProtocol *asObjCBaseProtocol() { return 0; }
virtual ObjCClass *asObjCClass() { return 0; }
virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() { return 0; }
virtual ObjCProtocol *asObjCProtocol() { return 0; }
diff --git a/src/shared/cplusplus/SymbolVisitor.h b/src/shared/cplusplus/SymbolVisitor.h
index 939dad9068..8708ab0321 100644
--- a/src/shared/cplusplus/SymbolVisitor.h
+++ b/src/shared/cplusplus/SymbolVisitor.h
@@ -81,6 +81,8 @@ public:
virtual bool visit(ForwardClassDeclaration *) { return true; }
// Objective-C
+ virtual bool visit(ObjCBaseClass *) { return true; }
+ virtual bool visit(ObjCBaseProtocol *) { return true; }
virtual bool visit(ObjCClass *) { return true; }
virtual bool visit(ObjCForwardClassDeclaration *) { return true; }
virtual bool visit(ObjCProtocol *) { return true; }
diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp
index c5259c9fe8..d5fa07a99b 100644
--- a/src/shared/cplusplus/Symbols.cpp
+++ b/src/shared/cplusplus/Symbols.cpp
@@ -561,6 +561,32 @@ void Class::visitSymbol0(SymbolVisitor *visitor)
}
}
+ObjCBaseClass::ObjCBaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name)
+ : Symbol(translationUnit, sourceLocation, name)
+{ }
+
+ObjCBaseClass::~ObjCBaseClass()
+{ }
+
+FullySpecifiedType ObjCBaseClass::type() const
+{ return FullySpecifiedType(); }
+
+void ObjCBaseClass::visitSymbol0(SymbolVisitor *visitor)
+{ visitor->visit(this); }
+
+ObjCBaseProtocol::ObjCBaseProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name)
+ : Symbol(translationUnit, sourceLocation, name)
+{ }
+
+ObjCBaseProtocol::~ObjCBaseProtocol()
+{ }
+
+FullySpecifiedType ObjCBaseProtocol::type() const
+{ return FullySpecifiedType(); }
+
+void ObjCBaseProtocol::visitSymbol0(SymbolVisitor *visitor)
+{ visitor->visit(this); }
+
ObjCClass::ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name):
ScopedSymbol(translationUnit, sourceLocation, name),
_categoryName(0),
diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h
index 3ac7182c9a..10eb0366bf 100644
--- a/src/shared/cplusplus/Symbols.h
+++ b/src/shared/cplusplus/Symbols.h
@@ -476,6 +476,48 @@ private:
Array<BaseClass *> _baseClasses;
};
+class CPLUSPLUS_EXPORT ObjCBaseClass: public Symbol
+{
+public:
+ ObjCBaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name);
+ virtual ~ObjCBaseClass();
+
+ // Symbol's interface
+ virtual FullySpecifiedType type() const;
+
+ virtual const ObjCBaseClass *asObjCBaseClass() const
+ { return this; }
+
+ virtual ObjCBaseClass *asObjCBaseClass()
+ { return this; }
+
+protected:
+ virtual void visitSymbol0(SymbolVisitor *visitor);
+
+private:
+};
+
+class CPLUSPLUS_EXPORT ObjCBaseProtocol: public Symbol
+{
+public:
+ ObjCBaseProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name);
+ virtual ~ObjCBaseProtocol();
+
+ // Symbol's interface
+ virtual FullySpecifiedType type() const;
+
+ virtual const ObjCBaseProtocol *asObjCBaseProtocol() const
+ { return this; }
+
+ virtual ObjCBaseProtocol *asObjCBaseProtocol()
+ { return this; }
+
+protected:
+ virtual void visitSymbol0(SymbolVisitor *visitor);
+
+private:
+};
+
class CPLUSPLUS_EXPORT ObjCForwardProtocolDeclaration: public Symbol, public Type
{
public:
@@ -511,6 +553,15 @@ public:
ObjCProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name);
virtual ~ObjCProtocol();
+ unsigned protocolCount() const
+ { return _protocols.count(); }
+
+ ObjCBaseProtocol *protocolAt(unsigned index) const
+ { return _protocols.at(index); }
+
+ void addProtocol(ObjCBaseProtocol *protocol)
+ { _protocols.push_back(protocol); }
+
// Symbol's interface
virtual FullySpecifiedType type() const;
@@ -534,7 +585,7 @@ protected:
virtual void accept0(TypeVisitor *visitor);
private:
- Array<ObjCProtocol *> _protocols;
+ Array<ObjCBaseProtocol *> _protocols;
};
class CPLUSPLUS_EXPORT ObjCForwardClassDeclaration: public Symbol, public Type
@@ -579,18 +630,18 @@ public:
Name *categoryName() const { return _categoryName; }
void setCategoryName(Name *categoryName) { _categoryName = categoryName; }
- ObjCClass *baseClass() const
+ ObjCBaseClass *baseClass() const
{ return _baseClass; }
- void setBaseClass(ObjCClass *baseClass)
+ void setBaseClass(ObjCBaseClass *baseClass)
{ _baseClass = baseClass; }
unsigned protocolCount() const
{ return _protocols.count(); }
- ObjCProtocol *protocolAt(unsigned index) const
+ ObjCBaseProtocol *protocolAt(unsigned index) const
{ return _protocols.at(index); }
- void addProtocol(ObjCProtocol *protocol)
+ void addProtocol(ObjCBaseProtocol *protocol)
{ _protocols.push_back(protocol); }
// Symbol's interface
@@ -618,8 +669,8 @@ protected:
private:
bool _isInterface;
Name *_categoryName;
- ObjCClass * _baseClass;
- Array<ObjCProtocol *> _protocols;
+ ObjCBaseClass * _baseClass;
+ Array<ObjCBaseProtocol *> _protocols;
};
class CPLUSPLUS_EXPORT ObjCMethod: public ScopedSymbol, public Type