Commit 463f8363 authored by Roberto Raggi's avatar Roberto Raggi

Speed up the comutation of the local members.

parent 517d4f63
......@@ -540,6 +540,14 @@ Scope *FindUsages::enclosingScope()
if (foreachStmt->symbol)
return foreachStmt->symbol->members();
} else if (SwitchStatementAST *switchStmt = ast->asSwitchStatement()) {
if (switchStmt->symbol)
return switchStmt->symbol->members();
} else if (CatchClauseAST *catchClause = ast->asCatchClause()) {
if (catchClause->symbol)
return catchClause->symbol->members();
}
}
......
......@@ -392,6 +392,14 @@ Scope *CheckSymbols::enclosingScope() const
if (foreachStmt->symbol)
return foreachStmt->symbol->members();
} else if (SwitchStatementAST *switchStmt = ast->asSwitchStatement()) {
if (switchStmt->symbol)
return switchStmt->symbol->members();
} else if (CatchClauseAST *catchClause = ast->asCatchClause()) {
if (catchClause->symbol)
return catchClause->symbol->members();
}
}
......
......@@ -81,205 +81,167 @@ public:
protected:
using ASTVisitor::visit;
using ASTVisitor::endVisit;
bool findMember(Scope *scope, NameAST *ast, unsigned line, unsigned column)
void enterScope(Scope *scope)
{
if (! (ast && ast->name))
return false;
const Identifier *id = ast->name->identifier();
if (scope) {
for (Symbol *member = scope->lookat(id); member; member = member->next()) {
if (member->identifier() != id)
continue;
else if (member->line() < line || (member->line() == line && member->column() <= column)) {
localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local));
return true;
_scopeStack.append(scope);
for (unsigned i = 0; i < scope->symbolCount(); ++i) {
if (Symbol *member = scope->symbolAt(i)) {
if (member->isDeclaration() || member->isArgument()) {
if (member->name() && member->name()->isNameId()) {
const Identifier *id = member->identifier();
unsigned line, column;
getTokenStartPosition(member->sourceLocation(), &line, &column);
localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local));
}
}
}
}
return false;
}
void searchUsesInTemplateArguments(NameAST *name)
virtual bool visit(IdExpressionAST *ast)
{
if (! name)
return;
else if (TemplateIdAST *template_id = name->asTemplateId()) {
for (TemplateArgumentListAST *it = template_id->template_argument_list; it; it = it->next) {
accept(it->value);
if (SimpleNameAST *simpleName = ast->name->asSimpleName()) {
const Identifier *id = identifier(simpleName->identifier_token);
for (int i = _scopeStack.size() - 1; i != -1; --i) {
if (Symbol *member = _scopeStack.at(i)->lookat(id)) {
if (member->sourceLocation() < ast->firstToken() || member->scope()->isPrototypeScope()) {
unsigned line, column;
getTokenStartPosition(simpleName->identifier_token, &line, &column);
localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local));
return false;
}
}
}
}
}
virtual bool visit(SimpleNameAST *ast)
{ return findMemberForToken(ast->firstToken(), ast); }
return true;
}
bool findMemberForToken(unsigned tokenIdx, NameAST *ast)
virtual bool visit(QtMemberDeclarationAST *ast)
{
const Token &tok = tokenAt(tokenIdx);
if (tok.generated())
return false;
unsigned line, column;
getTokenStartPosition(tokenIdx, &line, &column);
Scope *scope = _doc->scopeAt(line, column);
while (scope) {
if (scope->isPrototypeScope()) {
Function *fun = scope->owner()->asFunction();
if (findMember(fun->members(), ast, line, column))
return false;
else if (findMember(fun->members(), ast, line, column))
return false;
} else if (scope->isObjCMethodScope()) {
ObjCMethod *method = scope->owner()->asObjCMethod();
if (findMember(method->members(), ast, line, column))
return false;
else if (findMember(method->arguments(), ast, line, column))
return false;
} else if (scope->isBlockScope()) {
if (findMember(scope, ast, line, column))
return false;
} else {
break;
}
scope = scope->enclosingScope();
}
if (tokenKind(ast->q_token) == T_Q_D)
hasD = true;
else
hasQ = true;
return false;
return true;
}
virtual bool visit(MemInitializerAST *ast)
virtual bool visit(FunctionDefinitionAST *ast)
{
accept(ast->expression_list);
return false;
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(TemplateIdAST *ast)
virtual void endVisit(FunctionDefinitionAST *ast)
{
for (TemplateArgumentListAST *arg = ast->template_argument_list; arg; arg = arg->next)
accept(arg->value);
const Token &tok = tokenAt(ast->identifier_token);
if (tok.generated())
return false;
unsigned line, column;
getTokenStartPosition(ast->firstToken(), &line, &column);
Scope *scope = _doc->scopeAt(line, column);
while (scope) {
if (scope->isPrototypeScope()) {
Function *fun = scope->owner()->asFunction();
if (findMember(fun->members(), ast, line, column))
return false;
else if (fun->block() && findMember(fun->block()->members(), ast, line, column))
return false;
} else if (scope->isBlockScope()) {
if (findMember(scope, ast, line, column))
return false;
} else {
break;
}
scope = scope->enclosingScope();
}
return false;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(QualifiedNameAST *ast)
virtual bool visit(CompoundStatementAST *ast)
{
for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next)
searchUsesInTemplateArguments(it->value->class_or_namespace_name);
searchUsesInTemplateArguments(ast->unqualified_name);
return false;
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(MemberAccessAST *ast)
virtual void endVisit(CompoundStatementAST *ast)
{
// accept only the base expression
accept(ast->base_expression);
// and ignore the member name.
return false;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(ElaboratedTypeSpecifierAST *)
virtual bool visit(IfStatementAST *ast)
{
// ### template args
return false;
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(ClassSpecifierAST *)
virtual void endVisit(IfStatementAST *ast)
{
// ### template args
return false;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(EnumSpecifierAST *)
virtual bool visit(WhileStatementAST *ast)
{
// ### template args
return false;
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(UsingDirectiveAST *)
virtual void endVisit(WhileStatementAST *ast)
{
return false;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(UsingAST *ast)
virtual bool visit(ForStatementAST *ast)
{
accept(ast->name);
return false;
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(QtMemberDeclarationAST *ast)
virtual void endVisit(ForStatementAST *ast)
{
if (tokenKind(ast->q_token) == T_Q_D)
hasD = true;
else
hasQ = true;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(ForeachStatementAST *ast)
{
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
virtual void endVisit(ForeachStatementAST *ast)
{
accept(ast->declaration);
return false;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(FunctionDeclaratorAST *ast)
virtual bool visit(SwitchStatementAST *ast)
{
accept(ast->parameters);
for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next)
accept(it->value);
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
accept(ast->exception_specification);
virtual void endVisit(SwitchStatementAST *ast)
{
if (ast->symbol)
_scopeStack.removeLast();
}
return false;
virtual bool visit(CatchClauseAST *ast)
{
if (ast->symbol)
enterScope(ast->symbol->members());
return true;
}
virtual bool visit(ObjCMethodPrototypeAST *ast)
virtual void endVisit(CatchClauseAST *ast)
{
accept(ast->argument_list);
return false;
if (ast->symbol)
_scopeStack.removeLast();
}
virtual bool visit(ObjCMessageArgumentDeclarationAST *ast)
virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
{
accept(ast->param_name);
accept(ast->declaration);
return false;
}
private:
QList<Scope *> _scopeStack;
};
} // end of anonymous namespace
......
......@@ -187,12 +187,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
_scope, &name);
unsigned location = semantic()->location(it->value);
if (! location) {
if (it->value)
location = it->value->firstToken();
else
location = ast->firstToken();
}
if (! location)
location = ast->firstToken();
Function *fun = 0;
if (declTy && 0 != (fun = declTy->asFunctionType())) {
......
......@@ -123,7 +123,7 @@ bool CheckExpression::visit(ConditionAST *ast)
const Name *name = 0;
FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(),
_scope, &name);
Declaration *decl = control()->newDeclaration(ast->declarator->firstToken(), name);
Declaration *decl = control()->newDeclaration(semantic()->location(ast->declarator), name);
decl->setType(declTy);
_scope->enterSymbol(decl);
return false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment