Added scope calculation for Objective-C classes.

This commit is contained in:
Erik Verbruggen
2009-11-11 09:21:06 +01:00
parent 7938f9def9
commit 72d4493fc2
17 changed files with 513 additions and 28 deletions

View File

@@ -662,15 +662,13 @@ bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast)
Declaration *decl = control()->newDeclaration(ast->firstToken(), methodType->name());
decl->setType(methodType);
symbol = decl;
symbol->setStorage(methodType->storage());
}
symbol->setStartOffset(tokenAt(ast->firstToken()).offset);
symbol->setEndOffset(tokenAt(ast->lastToken()).offset);
symbol->setVisibility(semantic()->currentVisibility());
if (semantic()->isObjCClassMethod(ast->method_prototype->method_type_token))
symbol->setStorage(Symbol::Static);
_scope->enterSymbol(symbol);
return false;

View File

@@ -246,21 +246,32 @@ bool CheckDeclarator::visit(ReferenceAST *)
bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
{
if (!ast)
return false;
if (!ast->selector) {
// TODO: (EV) this currently happens when parsing:
// + (id<NSSomeProtocol>) zoo;
// where the parser will start doing template magic. We'll need to disambiguate this case.
return false;
}
FullySpecifiedType returnType = semantic()->check(ast->type_name, _scope);
unsigned location = ast->firstToken();
Name *name = semantic()->check(ast->selector, _scope);
semantic()->check(ast->selector, _scope);
ObjCMethod *method = control()->newObjCMethod(location, name);
ObjCMethod *method = control()->newObjCMethod(location, ast->selector->selector_name);
ast->symbol = method;
method->setSourceLocation(location);
method->setScope(_scope);
method->setVisibility(semantic()->currentVisibility());
method->setReturnType(returnType);
if (semantic()->isObjCClassMethod(tokenKind(ast->method_type_token)))
method->setStorage(Symbol::Static);
if (ast->selector && ast->selector->asObjCSelectorWithArguments()) {
// TODO: add arguments (EV)
for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
ObjCMessageArgumentDeclarationAST *argDecl = it->value;
@@ -273,8 +284,6 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
_fullySpecifiedType = FullySpecifiedType(method);
// TODO: check which specifiers are allowed here (EV)
return false;
}

View File

@@ -368,7 +368,7 @@ bool CheckExpression::visit(MemberAccessAST *ast)
bool CheckExpression::visit(ObjCMessageExpressionAST *ast)
{
semantic()->check(ast->receiver_expression, _scope);
(void) semantic()->check(ast->receiver_expression, _scope);
(void) semantic()->check(ast->selector, _scope);
accept(ast->argument_list); // ### not necessary.

View File

@@ -379,8 +379,9 @@ bool CheckName::visit(TemplateIdAST *ast)
bool CheckName::visit(ObjCSelectorWithoutArgumentsAST *ast)
{
std::vector<Name *> names;
Identifier *id = identifier(ast->name_token);
names.push_back(control()->nameId(id));
Identifier *id = control()->findOrInsertIdentifier(spell(ast->name_token));
NameId *nameId = control()->nameId(id);
names.push_back(nameId);
_name = control()->selectorNameId(&names[0], names.size(), false);
ast->selector_name = _name;
@@ -391,10 +392,9 @@ bool CheckName::visit(ObjCSelectorWithArgumentsAST *ast)
{
std::vector<Name *> names;
for (ObjCSelectorArgumentListAST *it = ast->selector_argument_list; it; it = it->next) {
Identifier *id = identifier(it->value->name_token);
Name *name = control()->nameId(id);
names.push_back(name);
Identifier *id = control()->findOrInsertIdentifier(spell(it->value->name_token));
NameId *nameId = control()->nameId(id);
names.push_back(nameId);
}
if (!names.empty()) {

View File

@@ -289,7 +289,9 @@ void SelectorNameId::accept0(NameVisitor *visitor)
Identifier *SelectorNameId::identifier() const
{
// FIXME: (EV)
if (! _nameCount)
return 0;
return nameAt(0)->identifier();
}

View File

@@ -245,6 +245,9 @@ Symbol *Scope::lookat(Identifier *id) const
break;
} else if (identity->isQualifiedNameId()) {
assert(0);
} else if (SelectorNameId *selectorNameId = identity->asSelectorNameId()) {
if (selectorNameId->identifier()->isEqualTo(id))
break;
}
}
return symbol;

View File

@@ -232,9 +232,7 @@ bool Semantic::isObjCClassMethod(int tokenKind) const
case T_PLUS:
return true;
case T_MINUS:
return false;
default:
// TODO EV: assert here?
return false;
}
}

View File

@@ -104,6 +104,9 @@ protected:
virtual void visit(QualifiedNameId *name)
{ _value = operator()(name->unqualifiedNameId()); }
virtual void visit(SelectorNameId *name)
{ _value = name->identifier()->hashCode(); }
private:
unsigned _value;
};
@@ -151,6 +154,9 @@ protected:
virtual void visit(QualifiedNameId *name)
{ _identity = name->unqualifiedNameId(); }
virtual void visit(SelectorNameId *name)
{ _identity = name; }
private:
Name *_identity;
};
@@ -461,6 +467,12 @@ bool Symbol::isArgument() const
bool Symbol::isBaseClass() const
{ return asBaseClass() != 0; }
bool Symbol::isObjCBaseClass() const
{ return asObjCBaseClass() != 0; }
bool Symbol::isObjCBaseProtocol() const
{ return asObjCBaseProtocol() != 0; }
bool Symbol::isObjCClass() const
{ return asObjCClass() != 0; }