aboutsummaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorErik Verbruggen <[email protected]>2009-07-31 16:03:48 +0200
committerErik Verbruggen <[email protected]>2009-07-31 16:03:48 +0200
commit4a0da2c6f2663d9469bfd929fa682b6df7d42ab7 (patch)
treed8fb1fbbeacaadad06024ecd5ce8e84c8f30d547 /src/shared
parentb713f1772a4de8330bcdd96a00b9cf103541e008 (diff)
Added Semantic checks for ObjC methods.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/cplusplus/AST.cpp11
-rw-r--r--src/shared/cplusplus/AST.h3
-rw-r--r--src/shared/cplusplus/ASTClone.cpp3
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp9
-rw-r--r--src/shared/cplusplus/CPlusPlusForwardDeclarations.h2
-rw-r--r--src/shared/cplusplus/CheckDeclaration.cpp30
-rw-r--r--src/shared/cplusplus/CheckDeclaration.h1
-rw-r--r--src/shared/cplusplus/CheckExpression.cpp25
-rw-r--r--src/shared/cplusplus/CheckExpression.h5
-rw-r--r--src/shared/cplusplus/CheckName.cpp6
-rw-r--r--src/shared/cplusplus/Control.cpp40
-rw-r--r--src/shared/cplusplus/Control.h4
-rw-r--r--src/shared/cplusplus/Name.cpp3
-rw-r--r--src/shared/cplusplus/Name.h3
-rw-r--r--src/shared/cplusplus/NameVisitor.h1
-rw-r--r--src/shared/cplusplus/Names.cpp57
-rw-r--r--src/shared/cplusplus/Names.h33
-rw-r--r--src/shared/cplusplus/Parser.cpp52
-rw-r--r--src/shared/cplusplus/Parser.h4
19 files changed, 257 insertions, 35 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 0a16fa774ca..cba0a7a39dc 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -2080,6 +2080,9 @@ unsigned ObjCMessageExpressionAST::lastToken() const
if (receiver_expression)
return receiver_expression->lastToken();
+ if (selector)
+ return selector->lastToken();
+
if (argument_list)
return argument_list->lastToken();
@@ -2107,7 +2110,7 @@ unsigned ObjCMessageArgumentListAST::lastToken() const
unsigned ObjCMessageArgumentAST::firstToken() const
{
- return parameter_key_identifier;
+ return parameter_value_expression->firstToken();
}
unsigned ObjCMessageArgumentAST::lastToken() const
@@ -2115,10 +2118,8 @@ unsigned ObjCMessageArgumentAST::lastToken() const
if (parameter_value_expression)
return parameter_value_expression->lastToken();
- if (colon_token)
- return colon_token + 1;
-
- return parameter_key_identifier + 1;
+ // ### assert?
+ return 0;
}
unsigned ObjCProtocolExpressionAST::firstToken() const
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index d9e54130287..fb84d4d0a91 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -2644,8 +2644,6 @@ protected:
class CPLUSPLUS_EXPORT ObjCMessageArgumentAST: public AST
{
public:
- unsigned parameter_key_identifier;
- unsigned colon_token;
ExpressionAST *parameter_value_expression;
public:
@@ -2685,6 +2683,7 @@ class CPLUSPLUS_EXPORT ObjCMessageExpressionAST: public ExpressionAST
public:
unsigned lbracket_token;
ExpressionAST *receiver_expression;
+ ObjCSelectorAST *selector;
ObjCMessageArgumentListAST *argument_list;
unsigned rbracket_token;
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 1fbb5a651b1..87e74d9ee48 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1295,6 +1295,7 @@ ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) cons
ObjCMessageExpressionAST *ast = new (pool) ObjCMessageExpressionAST;
ast->lbracket_token = lbracket_token;
if (receiver_expression) ast->receiver_expression = receiver_expression->clone(pool);
+ if (selector) ast->selector = selector->clone(pool);
if (argument_list) ast->argument_list = argument_list->clone(pool);
ast->rbracket_token = rbracket_token;
return ast;
@@ -1311,8 +1312,6 @@ ObjCMessageArgumentListAST *ObjCMessageArgumentListAST::clone(MemoryPool *pool)
ObjCMessageArgumentAST *ObjCMessageArgumentAST::clone(MemoryPool *pool) const
{
ObjCMessageArgumentAST *ast = new (pool) ObjCMessageArgumentAST;
- ast->parameter_key_identifier = parameter_key_identifier;
- ast->colon_token = colon_token;
if (parameter_value_expression) ast->parameter_value_expression = parameter_value_expression->clone(pool);
return ast;
}
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index f258ac1125e..a76d80df6bb 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1220,6 +1220,8 @@ void ObjCMessageExpressionAST::accept0(ASTVisitor *visitor)
// visit ObjCMessageExpressionAST
if (receiver_expression)
accept(receiver_expression, visitor);
+ if (selector)
+ accept(selector, visitor);
if (argument_list)
accept(argument_list, visitor);
// visit ExpressionAST
@@ -1231,10 +1233,9 @@ void ObjCMessageArgumentListAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
// visit ObjCMessageArgumentListAST
- if (arg)
- accept(arg, visitor);
- if (next)
- accept(next, visitor);
+ for (ObjCMessageArgumentListAST *it = this; it; it = it->next)
+ if (it->arg)
+ accept(it->arg, visitor);
// visit AST
}
visitor->endVisit(this);
diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
index 76ee3061dc5..e85dda262f7 100644
--- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
+++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h
@@ -100,6 +100,7 @@ class DestructorNameId;
class OperatorNameId;
class ConversionNameId;
class QualifiedNameId;
+class SelectorNameId;
// types
class FullySpecifiedType;
@@ -138,6 +139,7 @@ class ObjCClass;
class ObjCForwardClassDeclaration;
class ObjCProtocol;
class ObjCForwardProtocolDeclaration;
+class ObjCMethod;
CPLUSPLUS_END_NAMESPACE
CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 1a9877db156..f3157e7bc67 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -598,6 +598,36 @@ bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast)
return false;
}
+bool CheckDeclaration::visit(ObjCMethodDefinitionAST *ast)
+{
+ if (!ast->method_prototype)
+ return false;
+
+ FullySpecifiedType ty = semantic()->check(ast->method_prototype, _scope);
+ Function *fun = ty.type()->asFunctionType();
+ if (!fun)
+ return false;
+
+ Declaration *symbol = control()->newDeclaration(ast->firstToken(), fun->name());
+ symbol->setStartOffset(tokenAt(ast->firstToken()).offset);
+ symbol->setEndOffset(tokenAt(ast->lastToken()).offset);
+
+ symbol->setType(fun->returnType());
+
+ symbol->setVisibility(semantic()->currentVisibility());
+
+ if (semantic()->isObjCClassMethod(ast->method_prototype->method_type_token))
+ symbol->setStorage(Symbol::Static);
+
+ _scope->enterSymbol(symbol);
+
+ if (! semantic()->skipFunctionBodies()) {
+ semantic()->check(ast->function_body, fun->members());
+ }
+
+ return false;
+}
+
bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast)
{
int accessSpecifier = tokenKind(ast->visibility_token);
diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h
index 97c4d5ff449..b1880c5377f 100644
--- a/src/shared/cplusplus/CheckDeclaration.h
+++ b/src/shared/cplusplus/CheckDeclaration.h
@@ -96,6 +96,7 @@ protected:
virtual bool visit(ObjCClassDeclarationAST *ast);
virtual bool visit(ObjCClassInterfaceDefinitionAST *ast);
virtual bool visit(ObjCMethodDeclarationAST *ast);
+ virtual bool visit(ObjCMethodDefinitionAST *ast);
virtual bool visit(ObjCVisibilityDeclarationAST *ast);
private:
diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp
index 25cfe8ba43a..ac93a1a9de0 100644
--- a/src/shared/cplusplus/CheckExpression.cpp
+++ b/src/shared/cplusplus/CheckExpression.cpp
@@ -383,4 +383,29 @@ bool CheckExpression::visit(MemberAccessAST *ast)
return false;
}
+bool CheckExpression::visit(ObjCMessageExpressionAST *ast)
+{
+ semantic()->check(ast->receiver_expression, _scope);
+
+ if (Name *name = semantic()->check(ast->selector, _scope))
+ _scope->addUse(ast->selector->firstToken(), name);
+
+ accept(ast->argument_list);
+ return false;
+}
+
+bool CheckExpression::visit(ObjCEncodeExpressionAST * /*ast*/)
+{
+ // TODO: visit the type name, but store the type here? (EV)
+ return true;
+}
+
+bool CheckExpression::visit(ObjCSelectorExpressionAST *ast)
+{
+ if (Name *name = semantic()->check(ast->selector, _scope))
+ _scope->addUse(ast->selector->firstToken(), name);
+
+ return false;
+}
+
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/CheckExpression.h b/src/shared/cplusplus/CheckExpression.h
index dad53ed3b76..41c3393d7ae 100644
--- a/src/shared/cplusplus/CheckExpression.h
+++ b/src/shared/cplusplus/CheckExpression.h
@@ -110,6 +110,11 @@ protected:
virtual bool visit(PostIncrDecrAST *ast);
virtual bool visit(MemberAccessAST *ast);
+ // ObjC
+ virtual bool visit(ObjCMessageExpressionAST *ast);
+ virtual bool visit(ObjCEncodeExpressionAST *ast);
+ virtual bool visit(ObjCSelectorExpressionAST *ast);
+
private:
ExpressionAST *_expression;
FullySpecifiedType _fullySpecifiedType;
diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp
index 48ab067f03b..0fad66cccf9 100644
--- a/src/shared/cplusplus/CheckName.cpp
+++ b/src/shared/cplusplus/CheckName.cpp
@@ -376,8 +376,10 @@ bool CheckName::visit(TemplateIdAST *ast)
bool CheckName::visit(ObjCSelectorWithoutArgumentsAST *ast)
{
+ std::vector<Name *> names;
Identifier *id = identifier(ast->name_token);
- _name = control()->nameId(id);
+ names.push_back(control()->nameId(id));
+ _name = control()->selectorNameId(&names[0], names.size(), false);
ast->selector_name = _name;
return false;
@@ -392,7 +394,7 @@ bool CheckName::visit(ObjCSelectorWithArgumentsAST *ast)
names.push_back(name);
}
- _name = control()->qualifiedNameId(&names[0], names.size(), false);
+ _name = control()->selectorNameId(&names[0], names.size(), true);
ast->selector_name = _name;
return false;
diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp
index 49f965f7da3..96a67196119 100644
--- a/src/shared/cplusplus/Control.cpp
+++ b/src/shared/cplusplus/Control.cpp
@@ -196,6 +196,15 @@ public:
return it->second;
}
+ SelectorNameId *findOrInsertSelectorNameId(const std::vector<Name *> &names, bool hasArguments)
+ {
+ const SelectorNameIdKey key(names, hasArguments);
+ std::map<SelectorNameIdKey, SelectorNameId *>::iterator it = selectorNameIds.lower_bound(key);
+ if (it == selectorNameIds.end() || it->first != key)
+ it = selectorNameIds.insert(it, std::make_pair(key, new SelectorNameId(&names[0], names.size(), hasArguments)));
+ return it->second;
+ }
+
IntegerType *findOrInsertIntegerType(int kind)
{
const int key = int(kind);
@@ -423,6 +432,27 @@ public:
}
};
+ struct SelectorNameIdKey {
+ std::vector<Name *> _names;
+ bool _hasArguments;
+
+ SelectorNameIdKey(const std::vector<Name *> &names, bool hasArguments): _names(names), _hasArguments(hasArguments) {}
+
+ bool operator==(const SelectorNameIdKey &other) const
+ { return _names == other._names && _hasArguments == other._hasArguments; }
+
+ bool operator!=(const SelectorNameIdKey &other) const
+ { return !operator==(other); }
+
+ bool operator<(const SelectorNameIdKey &other) const
+ {
+ if (_hasArguments == other._hasArguments)
+ return std::lexicographical_compare(_names.begin(), _names.end(), other._names.begin(), other._names.end());
+ else
+ return _hasArguments < other._hasArguments;
+ }
+ };
+
struct ArrayKey {
FullySpecifiedType type;
size_t size;
@@ -491,6 +521,7 @@ public:
std::map<FullySpecifiedType, ConversionNameId *> conversionNameIds;
std::map<TemplateNameIdKey, TemplateNameId *> templateNameIds;
std::map<QualifiedNameIdKey, QualifiedNameId *> qualifiedNameIds;
+ std::map<SelectorNameIdKey, SelectorNameId *> selectorNameIds;
// types
VoidType voidType;
@@ -615,6 +646,15 @@ QualifiedNameId *Control::qualifiedNameId(Name *const *names,
return d->findOrInsertQualifiedNameId(classOrNamespaceNames, isGlobal);
}
+SelectorNameId *Control::selectorNameId(Name *const *names,
+ unsigned nameCount,
+ bool hasArguments)
+{
+ std::vector<Name *> selectorNames(names, names + nameCount);
+ return d->findOrInsertSelectorNameId(selectorNames, hasArguments);
+}
+
+
VoidType *Control::voidType()
{ return &d->voidType; }
diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h
index a9b85b7baee..5e90e0947b9 100644
--- a/src/shared/cplusplus/Control.h
+++ b/src/shared/cplusplus/Control.h
@@ -89,6 +89,10 @@ public:
unsigned nameCount,
bool isGlobal = false);
+ SelectorNameId *selectorNameId(Name *const *names,
+ unsigned nameCount,
+ bool hasArguments);
+
/// Returns a Type object of type VoidType.
VoidType *voidType();
diff --git a/src/shared/cplusplus/Name.cpp b/src/shared/cplusplus/Name.cpp
index b3c9019f7d9..7420bd496bd 100644
--- a/src/shared/cplusplus/Name.cpp
+++ b/src/shared/cplusplus/Name.cpp
@@ -76,6 +76,9 @@ bool Name::isConversionNameId() const
bool Name::isQualifiedNameId() const
{ return asQualifiedNameId() != 0; }
+bool Name::isSelectorNameId() const
+{ return asSelectorNameId() != 0; }
+
void Name::accept(NameVisitor *visitor)
{
if (visitor->preVisit(this))
diff --git a/src/shared/cplusplus/Name.h b/src/shared/cplusplus/Name.h
index 145b3344b98..3604aca570a 100644
--- a/src/shared/cplusplus/Name.h
+++ b/src/shared/cplusplus/Name.h
@@ -71,6 +71,7 @@ public:
bool isOperatorNameId() const;
bool isConversionNameId() const;
bool isQualifiedNameId() const;
+ bool isSelectorNameId() const;
virtual const NameId *asNameId() const { return 0; }
virtual const TemplateNameId *asTemplateNameId() const { return 0; }
@@ -78,6 +79,7 @@ public:
virtual const OperatorNameId *asOperatorNameId() const { return 0; }
virtual const ConversionNameId *asConversionNameId() const { return 0; }
virtual const QualifiedNameId *asQualifiedNameId() const { return 0; }
+ virtual const SelectorNameId *asSelectorNameId() const { return 0; }
virtual NameId *asNameId() { return 0; }
virtual TemplateNameId *asTemplateNameId() { return 0; }
@@ -85,6 +87,7 @@ public:
virtual OperatorNameId *asOperatorNameId() { return 0; }
virtual ConversionNameId *asConversionNameId() { return 0; }
virtual QualifiedNameId *asQualifiedNameId() { return 0; }
+ virtual SelectorNameId *asSelectorNameId() { return 0; }
virtual bool isEqualTo(const Name *other) const = 0;
diff --git a/src/shared/cplusplus/NameVisitor.h b/src/shared/cplusplus/NameVisitor.h
index 18921375632..16ba837d645 100644
--- a/src/shared/cplusplus/NameVisitor.h
+++ b/src/shared/cplusplus/NameVisitor.h
@@ -74,6 +74,7 @@ public:
virtual void visit(OperatorNameId *) {}
virtual void visit(ConversionNameId *) {}
virtual void visit(QualifiedNameId *) {}
+ virtual void visit(SelectorNameId *) {}
};
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/Names.cpp b/src/shared/cplusplus/Names.cpp
index 3dafad910b2..32762841b6f 100644
--- a/src/shared/cplusplus/Names.cpp
+++ b/src/shared/cplusplus/Names.cpp
@@ -268,5 +268,62 @@ bool ConversionNameId::isEqualTo(const Name *other) const
return _type.isEqualTo(c->type());
}
+SelectorNameId::SelectorNameId(Name *const names[],
+ unsigned nameCount,
+ bool hasArguments)
+ : _names(0),
+ _nameCount(nameCount),
+ _hasArguments(hasArguments)
+{
+ if (_nameCount) {
+ _names = new Name *[_nameCount];
+ std::copy(&names[0], &names[nameCount], _names);
+ }
+}
+
+SelectorNameId::~SelectorNameId()
+{ delete[] _names; }
+
+void SelectorNameId::accept0(NameVisitor *visitor)
+{ visitor->visit(this); }
+
+Identifier *SelectorNameId::identifier() const
+{
+ // FIXME: (EV)
+ return nameAt(0)->identifier();
+}
+
+unsigned SelectorNameId::nameCount() const
+{ return _nameCount; }
+
+Name *SelectorNameId::nameAt(unsigned index) const
+{ return _names[index]; }
+
+Name *const *SelectorNameId::names() const
+{ return _names; }
+
+bool SelectorNameId::hasArguments() const
+{ return _hasArguments; }
+
+bool SelectorNameId::isEqualTo(const Name *other) const
+{
+ const SelectorNameId *q = other->asSelectorNameId();
+ if (! q)
+ return false;
+ else if (hasArguments() != q->hasArguments())
+ return false;
+ else {
+ const unsigned count = nameCount();
+ if (count != q->nameCount())
+ return false;
+ for (unsigned i = 0; i < count; ++i) {
+ Name *l = nameAt(i);
+ Name *r = q->nameAt(i);
+ if (! l->isEqualTo(r))
+ return false;
+ }
+ }
+ return true;
+}
CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/Names.h b/src/shared/cplusplus/Names.h
index c5758ba7384..b0dc3956301 100644
--- a/src/shared/cplusplus/Names.h
+++ b/src/shared/cplusplus/Names.h
@@ -271,6 +271,39 @@ private:
FullySpecifiedType _type;
};
+class CPLUSPLUS_EXPORT SelectorNameId: public Name
+{
+public:
+ SelectorNameId(Name *const names[],
+ unsigned nameCount,
+ bool hasArguments);
+ virtual ~SelectorNameId();
+
+ virtual Identifier *identifier() const;
+
+ unsigned nameCount() const;
+ Name *nameAt(unsigned index) const;
+ Name *const *names() const;
+
+ bool hasArguments() const;
+
+ virtual bool isEqualTo(const Name *other) const;
+
+ virtual const SelectorNameId *asSelectorNameId() const
+ { return this; }
+
+ virtual SelectorNameId *asSelectorNameId()
+ { return this; }
+
+protected:
+ virtual void accept0(NameVisitor *visitor);
+
+private:
+ Name **_names;
+ unsigned _nameCount;
+ bool _hasArguments;
+};
+
CPLUSPLUS_END_NAMESPACE
CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index d0a7b05bcbe..ee8e714f64e 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2967,7 +2967,7 @@ bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
ast->lbracket_token = consumeToken();
parseObjCMessageReceiver(ast->receiver_expression);
- parseObjCMessageArguments(ast->argument_list);
+ parseObjCMessageArguments(ast->selector, ast->argument_list);
match(T_RBRACKET, &(ast->rbracket_token));
node = ast;
@@ -2979,25 +2979,34 @@ bool Parser::parseObjCMessageReceiver(ExpressionAST *&node)
return parseExpression(node);
}
-bool Parser::parseObjCMessageArguments(ObjCMessageArgumentListAST *& node)
+bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArgumentListAST *& argNode)
{
if (LA() == T_RBRACKET)
return false; // nothing to do.
unsigned start = cursor();
- ObjCMessageArgumentListAST *ast = new (_pool) ObjCMessageArgumentListAST;
- ObjCMessageArgumentAST *argument = 0;
+ ObjCSelectorArgumentAST *selectorArgument = 0;
+ ObjCMessageArgumentAST *messageArgument = 0;
- if (parseObjCSelectorArg(argument)) {
- ast->arg = argument;
- ObjCMessageArgumentListAST *lastArgument = ast;
+ if (parseObjCSelectorArg(selectorArgument, messageArgument)) {
+ ObjCSelectorArgumentListAST *selAst = new (_pool) ObjCSelectorArgumentListAST;
+ selAst->argument = selectorArgument;
+ ObjCSelectorArgumentListAST *lastSelector = selAst;
- while (parseObjCSelectorArg(argument)) {
+ ObjCMessageArgumentListAST *argAst = new (_pool) ObjCMessageArgumentListAST;
+ argAst->arg = messageArgument;
+ ObjCMessageArgumentListAST *lastArgument = argAst;
+
+ while (parseObjCSelectorArg(selectorArgument, messageArgument)) {
// accept the selector args.
+ lastSelector->next = new (_pool) ObjCSelectorArgumentListAST;
+ lastSelector = lastSelector->next;
+ lastSelector->argument = selectorArgument;
+
lastArgument->next = new (_pool) ObjCMessageArgumentListAST;
lastArgument = lastArgument->next;
- lastArgument->arg = argument;
+ lastArgument->arg = messageArgument;
}
if (LA() == T_COMMA) {
@@ -3011,17 +3020,24 @@ bool Parser::parseObjCMessageArguments(ObjCMessageArgumentListAST *& node)
lastExpression = &(binaryExpression->right_expression);
}
}
+
+ ObjCSelectorWithArgumentsAST *selWithArgs = new (_pool) ObjCSelectorWithArgumentsAST;
+ selWithArgs->selector_arguments = selAst;
+
+ selNode = selWithArgs;
+ argNode = argAst;
} else {
rewind(start);
- ast->arg = new (_pool) ObjCMessageArgumentAST;
- parseObjCSelector(ast->arg->parameter_key_identifier);
+ ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST;
+ parseObjCSelector(sel->name_token);
+ selNode = sel;
+ argNode = 0;
}
- node = ast;
return true;
}
-bool Parser::parseObjCSelectorArg(ObjCMessageArgumentAST *&node)
+bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessageArgumentAST *&argNode)
{
unsigned selector_token = 0;
if (!parseObjCSelector(selector_token))
@@ -3030,12 +3046,12 @@ bool Parser::parseObjCSelectorArg(ObjCMessageArgumentAST *&node)
if (LA() != T_COLON)
return false;
- ObjCMessageArgumentAST *argument = new (_pool) ObjCMessageArgumentAST;
- argument->parameter_key_identifier = selector_token;
- argument->colon_token = consumeToken();
+ selNode = new (_pool) ObjCSelectorArgumentAST;
+ selNode->name_token = selector_token;
+ selNode->colon_token = consumeToken();
- parseAssignmentExpression(argument->parameter_value_expression);
- node = argument;
+ argNode = new (_pool) ObjCMessageArgumentAST;
+ parseAssignmentExpression(argNode->parameter_value_expression);
return true;
}
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index ec40707613d..181e4b6b712 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -226,8 +226,8 @@ public:
bool parseObjCMethodSignature();
bool parseObjCMessageExpression(ExpressionAST *&node);
bool parseObjCMessageReceiver(ExpressionAST *&node);
- bool parseObjCMessageArguments(ObjCMessageArgumentListAST *&node);
- bool parseObjCSelectorArg(ObjCMessageArgumentAST *&node);
+ bool parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArgumentListAST *& argNode);
+ bool parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessageArgumentAST *&argNode);
bool parseObjCMethodDefinitionList(DeclarationListAST *&node);
bool parseObjCMethodDefinition(DeclarationAST *&node);