diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 31d75c346f7165de3aaa6d8e6029aa1d483ae71c..7b79b0ac16d2c2ac16acdebf8aaefa52ad307c86 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -458,3 +458,30 @@ bool FindUsages::visit(SimpleDeclarationAST *) void FindUsages::endVisit(SimpleDeclarationAST *) { --_inSimpleDeclaration; } + +bool FindUsages::visit(ObjCSelectorWithoutArgumentsAST *ast) +{ + const Identifier *id = identifier(ast->name_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList<Symbol *> candidates = context.resolve(ast->selector_name); + reportResult(ast->name_token, candidates); + } + + return false; +} + +bool FindUsages::visit(ObjCSelectorWithArgumentsAST *ast) +{ + for (ObjCSelectorArgumentListAST *iter = ast->selector_argument_list; iter; + iter = iter->next) { + const Identifier *id = identifier(iter->value->name_token); + if (id == _id) { + LookupContext context = currentContext(iter->value); + const QList<Symbol *> candidates = context.resolve(ast->selector_name); + reportResult(iter->value->name_token, candidates); + } + } + + return false; +} diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h index 1a61cca4e6c57b1aeb168860541c6fb7b9450f75..2b066fa2fa53b7f2aaf7101c767e27f008fbd6cf 100644 --- a/src/libs/cplusplus/FindUsages.h +++ b/src/libs/cplusplus/FindUsages.h @@ -100,6 +100,8 @@ protected: virtual bool visit(FunctionDeclaratorAST *ast); virtual bool visit(SimpleDeclarationAST *); virtual void endVisit(SimpleDeclarationAST *); + virtual bool visit(ObjCSelectorWithoutArgumentsAST *ast); + virtual bool visit(ObjCSelectorWithArgumentsAST *ast); private: const Identifier *_id; diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 86976b03400f795c965731a6307c3e5f8f033b4a..c4fdf3518e9642f7885cab89c25b6806a463f390 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -261,9 +261,6 @@ protected: virtual bool visit(SimpleNameAST *ast) { return findMemberForToken(ast->firstToken(), ast); } - virtual bool visit(ObjCMessageArgumentDeclarationAST *ast) - { return findMemberForToken(ast->param_name_token, ast); } - bool findMemberForToken(unsigned tokenIdx, NameAST *ast) { unsigned line, column; @@ -1276,6 +1273,49 @@ void CPPEditor::switchDeclarationDefinition() } } +static inline LookupItem skipForwardDeclarations(const QList<LookupItem> &resolvedSymbols) +{ + QList<LookupItem> candidates = resolvedSymbols; + + LookupItem result = candidates.first(); + const FullySpecifiedType ty = result.type().simplified(); + + if (ty->isForwardClassDeclarationType()) { + while (! candidates.isEmpty()) { + LookupItem r = candidates.takeFirst(); + + if (! r.type()->isForwardClassDeclarationType()) { + result = r; + break; + } + } + } + + if (ty->isObjCForwardClassDeclarationType()) { + while (! candidates.isEmpty()) { + LookupItem r = candidates.takeFirst(); + + if (! r.type()->isObjCForwardClassDeclarationType()) { + result = r; + break; + } + } + } + + if (ty->isObjCForwardProtocolDeclarationType()) { + while (! candidates.isEmpty()) { + LookupItem r = candidates.takeFirst(); + + if (! r.type()->isObjCForwardProtocolDeclarationType()) { + result = r; + break; + } + } + } + + return result; +} + CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor, bool resolveTarget) { @@ -1340,41 +1380,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor, typeOfExpression(expression, doc, lastSymbol); if (!resolvedSymbols.isEmpty()) { - LookupItem result = resolvedSymbols.first(); - const FullySpecifiedType ty = result.type().simplified(); - - if (ty->isForwardClassDeclarationType()) { - while (! resolvedSymbols.isEmpty()) { - LookupItem r = resolvedSymbols.takeFirst(); - - if (! r.type()->isForwardClassDeclarationType()) { - result = r; - break; - } - } - } - - if (ty->isObjCForwardClassDeclarationType()) { - while (! resolvedSymbols.isEmpty()) { - LookupItem r = resolvedSymbols.takeFirst(); - - if (! r.type()->isObjCForwardClassDeclarationType()) { - result = r; - break; - } - } - } - - if (ty->isObjCForwardProtocolDeclarationType()) { - while (! resolvedSymbols.isEmpty()) { - LookupItem r = resolvedSymbols.takeFirst(); - - if (! r.type()->isObjCForwardProtocolDeclarationType()) { - result = r; - break; - } - } - } + LookupItem result = skipForwardDeclarations(resolvedSymbols); if (Symbol *symbol = result.lastVisibleSymbol()) { Symbol *def = 0; diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 348f9cddd72deb1362d6d72fd5c57c46d7b944ca..4504d9eadc165fbf46a3c12178791d83e7c74e6b 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2250,13 +2250,13 @@ unsigned ObjCMessageArgumentDeclarationAST::firstToken() const if (type_name) return type_name->firstToken(); else - return param_name_token; + return param_name->firstToken(); } unsigned ObjCMessageArgumentDeclarationAST::lastToken() const { - if (param_name_token) - return param_name_token + 1; + if (param_name) + return param_name->lastToken(); else if (type_name) return type_name->lastToken(); diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index eef6ec7528bc83b3d31d67299156d2ee408eee0f..11bcaf0f1c01cee284aa5c95397e0a4bddbdf2d4 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2996,12 +2996,12 @@ protected: virtual bool match0(AST *, ASTMatcher *); }; -class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public NameAST +class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public AST { public: ObjCTypeNameAST* type_name; SpecifierListAST *attribute_list; - unsigned param_name_token; + SimpleNameAST *param_name; public: // annotations Argument *argument; diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 183cce037a6bb5b6a50a99f050debcb90eeaa80b..805e7837b7a728c64ef6e195c2ee14b7a0e5c5b1 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1466,7 +1466,8 @@ ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclarationAST::clone(Memo for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list; iter; iter = iter->next, ast_iter = &(*ast_iter)->next) *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0); - ast->param_name_token = param_name_token; + if (param_name) + ast->param_name = param_name->clone(pool); return ast; } diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp index 6992a1d1cc2f488a2dbc9459da6c2db778867e9e..7f86349551c2ce993470733c5f456e77d65dc90f 100644 --- a/src/shared/cplusplus/ASTMatcher.cpp +++ b/src/shared/cplusplus/ASTMatcher.cpp @@ -2459,7 +2459,10 @@ bool ASTMatcher::match(ObjCMessageArgumentDeclarationAST *node, ObjCMessageArgum else if (! AST::match(node->attribute_list, pattern->attribute_list, this)) return false; - pattern->param_name_token = node->param_name_token; + if (! pattern->param_name) + pattern->param_name = node->param_name; + else if (! AST::match(node->param_name, pattern->param_name, this)) + return false; return true; } diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 22d9bd20ded0af877a04a0e5c82f30fc1b793a64..1b9f50df58d3a06645e5c9e1f5f2de4d968870bd 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1087,6 +1087,7 @@ void ObjCMessageArgumentDeclarationAST::accept0(ASTVisitor *visitor) if (visitor->visit(this)) { accept(type_name, visitor); accept(attribute_list, visitor); + accept(param_name, visitor); } visitor->endVisit(this); } diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index faeac37e106dff9d837479a9473d67888f31b5be..7ad7662af319efc0ff42c891b92ea9357afad66f 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -319,18 +319,14 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast) const bool isQ_SLOT = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; -#ifdef ICHECK_BUILD - const bool isQ_INVOKABLE = (ast->invoke_token > 0); -#endif + const bool isQ_INVOKABLE = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_INVOKABLE; if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) fun->setMethodKey(Function::SlotMethod); -#ifdef ICHECK_BUILD else if (isQ_INVOKABLE) - fun->setInvokable(true); -#endif + fun->setMethodKey(Function::InvokableMethod); checkFunctionArguments(fun); @@ -672,10 +668,14 @@ bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast) bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast) { - if (!ast->method_prototype) + ObjCMethodPrototypeAST *methodProto = ast->method_prototype; + if (!methodProto) + return false; + ObjCSelectorAST *selector = methodProto->selector; + if (!selector) return false; - FullySpecifiedType ty = semantic()->check(ast->method_prototype, _scope); + FullySpecifiedType ty = semantic()->check(methodProto, _scope); ObjCMethod *methodTy = ty.type()->asObjCMethodType(); if (!methodTy) return false; @@ -688,15 +688,15 @@ bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast) symbol = methodTy; } else { - Declaration *decl = control()->newDeclaration(ast->firstToken(), methodTy->name()); + Declaration *decl = control()->newDeclaration(selector->firstToken(), methodTy->name()); decl->setType(methodTy); symbol = decl; symbol->setStorage(methodTy->storage()); } - symbol->setStartOffset(tokenAt(ast->firstToken()).offset); - symbol->setEndOffset(tokenAt(ast->lastToken()).offset); - symbol->setVisibility(semantic()->currentVisibility()); + symbol->setStartOffset(tokenAt(selector->firstToken()).offset); + symbol->setEndOffset(tokenAt(selector->lastToken()).offset); + symbol->setVisibility(semantic()->currentObjCVisibility()); _scope->enterSymbol(symbol); diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp index afee09023b43f92687c0ac912e40ed63fb6f133d..b16806139364f593b7e6f34db05bf91356a56ff3 100644 --- a/src/shared/cplusplus/CheckDeclarator.cpp +++ b/src/shared/cplusplus/CheckDeclarator.cpp @@ -259,7 +259,7 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast) FullySpecifiedType returnType = semantic()->check(ast->type_name, _scope); - unsigned location = ast->firstToken(); + unsigned location = ast->selector->firstToken(); semantic()->check(ast->selector, _scope); diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp index 26fa9c21ee1a7b4180016f54a2c28d4278a32ba6..98b5adea253fef3361805974cbe266d8d9dcd405 100644 --- a/src/shared/cplusplus/CheckName.cpp +++ b/src/shared/cplusplus/CheckName.cpp @@ -418,12 +418,11 @@ bool CheckName::visit(ObjCMessageArgumentDeclarationAST *ast) if (ast->type_name) type = semantic()->check(ast->type_name, _scope); - if (ast->param_name_token) { - const Identifier *id = identifier(ast->param_name_token); - _name = control()->nameId(id); - ast->name = _name; + if (ast->param_name) { + accept(ast->param_name); - Argument *arg = control()->newArgument(ast->param_name_token, _name); + Argument *arg = control()->newArgument(ast->param_name->firstToken(), + ast->param_name->name); ast->argument = arg; arg->setType(type); arg->setInitializer(0); diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 60828aa6fe5640d651493a6916cbbc7794e7d1ea..86fb18dd2c3bb66e97901929f715ff0fa3a9eb2a 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -5269,7 +5269,8 @@ bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, Obj while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; - match(T_IDENTIFIER, &node->param_name_token); + node->param_name = new (_pool) SimpleNameAST; + match(T_IDENTIFIER, &node->param_name->identifier_token); return true; }