diff options
Diffstat (limited to 'src/plugins/cpptools')
| -rw-r--r-- | src/plugins/cpptools/cppchecksymbols.cpp | 30 | ||||
| -rw-r--r-- | src/plugins/cpptools/cppchecksymbols.h | 6 | ||||
| -rw-r--r-- | src/plugins/cpptools/cppcompletion_test.cpp | 520 | ||||
| -rw-r--r-- | src/plugins/cpptools/cppcompletionassist.cpp | 76 | ||||
| -rw-r--r-- | src/plugins/cpptools/cppcompletionassist.h | 8 | ||||
| -rw-r--r-- | src/plugins/cpptools/cpptoolsreuse.cpp | 2 | ||||
| -rw-r--r-- | src/plugins/cpptools/symbolfinder.cpp | 16 | ||||
| -rw-r--r-- | src/plugins/cpptools/symbolfinder.h | 3 |
8 files changed, 86 insertions, 575 deletions
diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index acf3d5c86f6..cbc6baf75e8 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -669,7 +669,7 @@ bool CheckSymbols::visit(NewExpressionAST *ast) if (highlightCtorDtorAsType) { accept(ast->new_type_id); } else { - LookupScope *binding = 0; + ClassOrNamespace *binding = 0; NameAST *nameAST = 0; if (ast->new_type_id) { for (SpecifierListAST *it = ast->new_type_id->type_specifier_list; it; it = it->next) { @@ -735,7 +735,7 @@ void CheckSymbols::checkNamespace(NameAST *name) unsigned line, column; getTokenStartPosition(name->firstToken(), &line, &column); - if (LookupScope *b = _context.lookupType(name->name, enclosingScope())) { + if (ClassOrNamespace *b = _context.lookupType(name->name, enclosingScope())) { foreach (Symbol *s, b->symbols()) { if (s->isNamespace()) return; @@ -768,14 +768,14 @@ bool CheckSymbols::hasVirtualDestructor(Class *klass) const return false; } -bool CheckSymbols::hasVirtualDestructor(LookupScope *binding) const +bool CheckSymbols::hasVirtualDestructor(ClassOrNamespace *binding) const { - QSet<LookupScope *> processed; - QList<LookupScope *> todo; + QSet<ClassOrNamespace *> processed; + QList<ClassOrNamespace *> todo; todo.append(binding); while (!todo.isEmpty()) { - LookupScope *b = todo.takeFirst(); + ClassOrNamespace *b = todo.takeFirst(); if (b && !processed.contains(b)) { processed.insert(b); foreach (Symbol *s, b->symbols()) { @@ -857,7 +857,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast) { if (ast->name) { - LookupScope *binding = checkNestedName(ast); + ClassOrNamespace *binding = checkNestedName(ast); if (binding && ast->unqualified_name) { if (ast->unqualified_name->asDestructorName() != 0) { @@ -886,9 +886,9 @@ bool CheckSymbols::visit(QualifiedNameAST *ast) return false; } -LookupScope *CheckSymbols::checkNestedName(QualifiedNameAST *ast) +ClassOrNamespace *CheckSymbols::checkNestedName(QualifiedNameAST *ast) { - LookupScope *binding = 0; + ClassOrNamespace *binding = 0; if (ast->name) { if (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list) { @@ -954,7 +954,7 @@ bool CheckSymbols::visit(MemInitializerAST *ast) { if (FunctionDefinitionAST *enclosingFunction = enclosingFunctionDefinition()) { if (ast->name && enclosingFunction->symbol) { - if (LookupScope *binding = _context.lookupType(enclosingFunction->symbol)) { + if (ClassOrNamespace *binding = _context.lookupType(enclosingFunction->symbol)) { foreach (Symbol *s, binding->symbols()) { if (Class *klass = s->asClass()) { NameAST *nameAST = ast->name; @@ -1157,7 +1157,7 @@ void CheckSymbols::addUse(const Result &use) _usages.append(use); } -void CheckSymbols::addType(LookupScope *b, NameAST *ast) +void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast) { unsigned startToken; if (!b || !acceptName(ast, &startToken)) @@ -1296,8 +1296,12 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST isConstructor = isConstructorDeclaration(c); Function *funTy = c->type()->asFunctionType(); - if (!funTy) // Template function has an overridden type - funTy = r.type()->asFunctionType(); + if (!funTy) { + //Try to find a template function + if (Template * t = r.type()->asTemplateType()) + if ((c = t->declaration())) + funTy = c->type()->asFunctionType(); + } if (!funTy || funTy->isAmbiguous()) continue; // TODO: add diagnostic messages and color call-operators calls too? diff --git a/src/plugins/cpptools/cppchecksymbols.h b/src/plugins/cpptools/cppchecksymbols.h index 11cde211460..f874c163231 100644 --- a/src/plugins/cpptools/cppchecksymbols.h +++ b/src/plugins/cpptools/cppchecksymbols.h @@ -105,7 +105,7 @@ protected: const QList<Result> &otherUses); bool hasVirtualDestructor(CPlusPlus::Class *klass) const; - bool hasVirtualDestructor(CPlusPlus::LookupScope *binding) const; + bool hasVirtualDestructor(CPlusPlus::ClassOrNamespace *binding) const; bool warning(unsigned line, unsigned column, const QString &text, unsigned length = 0); bool warning(CPlusPlus::AST *ast, const QString &text); @@ -119,13 +119,13 @@ protected: void checkNamespace(CPlusPlus::NameAST *name); void checkName(CPlusPlus::NameAST *ast, CPlusPlus::Scope *scope = 0); - CPlusPlus::LookupScope *checkNestedName(CPlusPlus::QualifiedNameAST *ast); + CPlusPlus::ClassOrNamespace *checkNestedName(CPlusPlus::QualifiedNameAST *ast); void addUse(const Result &use); void addUse(unsigned tokenIndex, Kind kind); void addUse(CPlusPlus::NameAST *name, Kind kind); - void addType(CPlusPlus::LookupScope *b, CPlusPlus::NameAST *ast); + void addType(CPlusPlus::ClassOrNamespace *b, CPlusPlus::NameAST *ast); bool maybeAddTypeOrStatic(const QList<CPlusPlus::LookupItem> &candidates, CPlusPlus::NameAST *ast); diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 02cc06848f6..7deb309f587 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -328,17 +328,16 @@ void CppToolsPlugin::test_completion() actualCompletions.sort(); expectedCompletions.sort(); - QEXPECT_FAIL("template_as_base: typedef not available in derived", - "We can live with that...", Abort); - QEXPECT_FAIL("template_specialization_with_reference", "test of reverted change", Abort); - QEXPECT_FAIL("specialization_multiple_arguments", "test of reverted change", Abort); - QEXPECT_FAIL("specialization_with_default_value", "test of reverted change", Abort); + QEXPECT_FAIL("template_as_base: explicit typedef from base", "QTCREATORBUG-14218", Abort); QEXPECT_FAIL("enum_in_function_in_struct_in_function", "QTCREATORBUG-13757", Abort); QEXPECT_FAIL("enum_in_function_in_struct_in_function_cxx11", "QTCREATORBUG-13757", Abort); QEXPECT_FAIL("enum_in_function_in_struct_in_function_anon", "QTCREATORBUG-13757", Abort); QEXPECT_FAIL("enum_in_class_accessed_in_member_func_cxx11", "QTCREATORBUG-13757", Abort); QEXPECT_FAIL("enum_in_class_accessed_in_member_func_inline_cxx11", "QTCREATORBUG-13757", Abort); - QEXPECT_FAIL("recursive_instantiation_of_template_type", "QTCREATORBUG-14237", Abort); + QEXPECT_FAIL("pointer_indirect_specialization", "QTCREATORBUG-14141", Abort); + QEXPECT_FAIL("pointer_indirect_specialization_typedef", "QTCREATORBUG-14141", Abort); + QEXPECT_FAIL("pointer_indirect_specialization_double_indirection", "QTCREATORBUG-14141", Abort); + QEXPECT_FAIL("pointer_indirect_specialization_double_indirection_with_base", "QTCREATORBUG-14141", Abort); QCOMPARE(actualCompletions, expectedCompletions); } @@ -802,21 +801,6 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("Data") << QLatin1String("dataMember")); - QTest::newRow("explicit_instantiation") << _( - "template<class T>\n" - "struct Foo { T bar; };\n" - "\n" - "template class Foo<int>;\n" - "\n" - "void func()\n" - "{\n" - " Foo<int> foo;\n" - " @\n" - "}\n" - ) << _("foo.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - QTest::newRow("use_global_identifier_as_base_class: derived as global and base as global") << _( "struct Global\n" "{\n" @@ -1327,28 +1311,21 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("Template1")); QTest::newRow("template_specialization_with_pointer") << _( - "template <typename T> struct Temp { T variable; };\n" - "template <typename T> struct Temp<T *> { T *pointer; };\n" - "void func()\n" + "template <typename T>\n" + "struct Template\n" "{\n" - " Temp<int*> templ;\n" - " @\n" - "}" - ) << _("templ.") << (QStringList() - << QLatin1String("Temp") - << QLatin1String("pointer")); - - QTest::newRow("template_specialization_with_reference") << _( - "template <typename T> struct Temp { T variable; };\n" - "template <typename T> struct Temp<T &> { T reference; };\n" - "void func()\n" + " T variable;\n" + "};\n" + "template <typename T>\n" + "struct Template<T *>\n" "{\n" - " Temp<int&> templ;\n" - " @\n" - "}" + " T *pointer;\n" + "};\n" + "Template<int*> templ;\n" + "@\n" ) << _("templ.") << (QStringList() - << QLatin1String("Temp") - << QLatin1String("reference")); + << QLatin1String("Template") + << QLatin1String("pointer")); QTest::newRow("typedef_using_templates1") << _( "namespace NS1\n" @@ -1572,29 +1549,6 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("C") << QLatin1String("m")); - QTest::newRow("type_and_using_declaration: type in nested namespace and using in global") << _( - "namespace Ns {\n" - "namespace Nested {\n" - "struct Foo\n" - "{\n" - " void func();\n" - " int m_bar;\n" - "};\n" - "}\n" - "}\n" - "\n" - "using namespace Ns::Nested;\n" - "\n" - "namespace Ns\n" - "{\n" - "void Foo::func()\n" - "{\n" - " @\n" - "}\n" - "}\n" - ) << _("m_") << (QStringList() - << QLatin1String("m_bar")); - QTest::newRow("instantiate_template_with_anonymous_class") << _( "template <typename T>\n" "struct S\n" @@ -2568,21 +2522,6 @@ void CppToolsPlugin::test_completion_data() ) << _("ar") << (QStringList() << QLatin1String("arg1")); - QTest::newRow("local_typedef_access_in_lambda") << _( - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " typedef Foo F;\n" - " []() {\n" - " F f;\n" - " @\n" - " };\n" - "}\n" - ) << _("f.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _( "struct Foo { int foo; };\n" "template <typename T = Foo>\n" @@ -2689,78 +2628,6 @@ void CppToolsPlugin::test_completion_data() ) << _("s.") << (QStringList() << QLatin1String("S")); - QTest::newRow("partial_specialization") << _( - "struct b {};\n" - "template<class X, class Y> struct s { float f; };\n" - "template<class X> struct s<X, b> { int i; };\n" - "\n" - "void f()\n" - "{\n" - " s<int, b> var;\n" - " @\n" - "}\n" - ) << _("var.") << (QStringList() - << QLatin1String("i") - << QLatin1String("s")); - -// QTest::newRow("partial_specialization_with_pointer") << _( -// "struct b {};\n" -// "struct a : b {};\n" -// "template<class X, class Y> struct s { float f; };\n" -// "template<class X> struct s<X, b*> { int i; };\n" -// "template<class X> struct s<X, a*> { char j; };\n" -// "\n" -// "void f()\n" -// "{\n" -// " s<int, a*> var;\n" -// " @\n" -// "}\n" -// ) << _("var.") << (QStringList() -// << QLatin1String("j") -// << QLatin1String("s")); - - QTest::newRow("partial_specialization_templated_argument") << _( - "template<class T> struct t {};\n" - "\n" - "template<class> struct s { float f; };\n" - "template<class X> struct s<t<X>> { int i; };\n" - "\n" - "void f()\n" - "{\n" - " s<t<char>> var;\n" - " @\n" - "}\n" - ) << _("var.") << (QStringList() - << QLatin1String("i") - << QLatin1String("s")); - - QTest::newRow("specialization_multiple_arguments") << _( - "class false_type {};\n" - "class true_type {};\n" - "template<class T1, class T2> class and_type { false_type f; };\n" - "template<> class and_type<true_type, true_type> { true_type t; };\n" - "void func()\n" - "{\n" - " and_type<true_type, false_type> a;\n" - " @;\n" - "}\n" - ) << _("a.") << (QStringList() - << QLatin1String("f") - << QLatin1String("and_type")); - - QTest::newRow("specialization_with_default_value") << _( - "class Foo {};\n" - "template<class T1 = Foo> class Temp;\n" - "template<> class Temp<Foo> { int var; };\n" - "void func()\n" - "{\n" - " Temp<> t;\n" - " @\n" - "}\n" - ) << _("t.") << (QStringList() - << QLatin1String("var") - << QLatin1String("Temp")); - QTest::newRow("auto_declaration_in_if_condition") << _( "struct Foo { int bar; };\n" "void fun() {\n" @@ -2966,28 +2833,6 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("Foo") << QLatin1String("bar")); - QTest::newRow("instantiation_of_indirect_typedef") << _( - "template<typename _Tp>\n" - "struct Indirect { _Tp t; };\n" - "\n" - "template<typename T>\n" - "struct Temp\n" - "{\n" - " typedef T MyT;\n" - " typedef Indirect<MyT> indirect;\n" - "};\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Temp<Foo>::indirect i;\n" - " @\n" - "}\n" - ) << _("i.t.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar"));; - QTest::newRow("pointer_indirect_specialization_double_indirection_with_base") << _( "template<typename _Tp>\n" "struct Traits { };\n" @@ -3024,337 +2869,6 @@ void CppToolsPlugin::test_completion_data() ) << _("t.p->") << (QStringList() << QLatin1String("Foo") << QLatin1String("bar")); - - QTest::newRow("recursive_instantiation_of_template_type") << _( - "template<typename _Tp>\n" - "struct Temp { typedef _Tp value_type; };\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Temp<Temp<Foo> >::value_type::value_type *p;\n" - " @\n" - "}\n" - ) << _("p->") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("recursive_instantiation_of_template_type_2") << _( - "template<typename _Tp>\n" - "struct Temp { typedef _Tp value_type; };\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Temp<Temp<Foo>::value_type>::value_type *p;\n" - " @\n" - "}\n" - ) << _("p->") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("template_using_instantiation") << _( - "template<typename _Tp>\n" - "using T = _Tp;\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " T<Foo> p;\n" - " @\n" - "}\n" - ) << _("p.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("nested_template_using_instantiation") << _( - "struct Parent {\n" - " template<typename _Tp>\n" - " using T = _Tp;\n" - "};\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Parent::T<Foo> p;\n" - " @;\n" - "}\n" - ) << _("p.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("nested_template_using_instantiation_in_template_class") << _( - "template<typename ParentT>\n" - "struct Parent {\n" - " template<typename _Tp>\n" - " using T = _Tp;\n" - "};\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Parent<Foo>::T<Foo> p;\n" - " @;\n" - "}\n" - ) << _("p.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("recursive_nested_template_using_instantiation") << _( - "struct Foo { int bar; };\n" - "\n" - "struct A { typedef Foo value_type; };\n" - "\n" - "template<typename T>\n" - "struct Traits\n" - "{\n" - " typedef Foo value_type;\n" - "\n" - " template<typename _Tp>\n" - " using U = T;\n" - "};\n" - "\n" - "template<typename T>\n" - "struct Temp\n" - "{\n" - " typedef Traits<T> TraitsT;\n" - " typedef typename T::value_type value_type;\n" - " typedef typename TraitsT::template U<Foo> rebind;\n" - "};\n" - "\n" - "void func()\n" - "{\n" - " typename Temp<typename Temp<A>::rebind>::value_type p;\n" - " @\n" - "}\n" - ) << _("p.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("qualified_name_in_nested_type") << _( - "template<typename _Tp>\n" - "struct Temp {\n" - " struct Nested {\n" - " typedef typename _Tp::Nested2 N;\n" - " };\n" - "};\n" - "\n" - "struct Foo {\n" - " struct Nested2 {\n" - " int bar;\n" - " };\n" - "};\n" - "\n" - "void func()\n" - "{\n" - " Temp<Foo>::Nested::N p;\n" - " @;\n" - "}\n" - ) << _("p.") << (QStringList() - << QLatin1String("Nested2") - << QLatin1String("bar")); - - QTest::newRow("simple_decltype_declaration") << _( - "struct Foo { int bar; };\n" - "Foo foo;\n" - "void fun() {\n" - " decltype(foo) s;\n" - " @\n" - "}\n" - ) << _("s.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("typedefed_decltype_declaration") << _( - "struct Foo { int bar; };\n" - "Foo foo;\n" - "typedef decltype(foo) TypedefedFooWithDecltype;\n" - "void fun() {\n" - " TypedefedFooWithDecltype s;\n" - " @\n" - "}\n" - ) << _("s.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("nested_instantiation_typedefed_decltype_declaration") << _( - "template <typename T>\n" - "struct Temp\n" - "{\n" - " struct Nested\n" - " {\n" - " static T f();\n" - " typedef decltype(f()) type;\n" - " };\n" - "};\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void fun()\n" - "{\n" - " Temp<Foo>::Nested::type s;\n" - " @\n" - "}\n" - ) << _("s.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("typedefed_decltype_of_template_function") << _( - "template<typename T>\n" - "static T f();\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void fun()\n" - "{\n" - " decltype(f<Foo>()) s;\n" - " @\n" - "}\n" - ) << _("s.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("nested_instantiation_typedefed_decltype_declaration_of_template_function") << _( - "template <typename T, typename D = T>\n" - "struct Temp\n" - "{\n" - " struct Nested\n" - " {\n" - " template<typename U> static T* __test(...);\n" - " typedef decltype(__test<D>(0)) type;\n" - " };\n" - "};\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Temp<Foo>::Nested::type s;\n" - " @\n" - "}\n" - ) << _("s.") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); - - QTest::newRow("typedef for templates in namespace") << _( - "namespace N {\n" - "\n" - "struct Data { int x; };\n" - "template <typename T> struct Foo { T member; };\n" - "typedef Foo<Data> Bar;\n" - "\n" - "} // N\n" - "\n" - "\n" - "void f()\n" - "{\n" - " N::Bar o;\n" - " @\n" - "}\n" - ) << _("o.member.") << (QStringList() - << QLatin1String("Data") - << QLatin1String("x")); - - QTest::newRow("std vector") << _( - "namespace std\n" - "{\n" - "template<typename _Tp>\n" - "struct allocator\n" - "{\n" - " typedef _Tp value_type;\n" - "\n" - " template<typename _Tp1>\n" - " struct rebind\n" - " { typedef allocator<_Tp1> other; };\n" - "};\n" - "\n" - "template<typename _Alloc, typename _Tp>\n" - "struct __alloctr_rebind\n" - "{\n" - " typedef typename _Alloc::template rebind<_Tp>::other __type;\n" - "};\n" - "\n" - "template<typename _Alloc>\n" - "struct allocator_traits\n" - "{\n" - " typedef typename _Alloc::value_type value_type;\n" - "\n" - " template<typename _Tp>\n" - " using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;\n" - "};\n" - "\n" - "template<typename _Iterator>\n" - "struct iterator_traits { };\n" - "\n" - "template<typename _Tp>\n" - "struct iterator_traits<_Tp*>\n" - "{\n" - " typedef _Tp* pointer;\n" - "};\n" - "} // namespace std\n" - "\n" - "namespace __gnu_cxx\n" - "{\n" - "template<typename _Alloc>\n" - "struct __alloc_traits\n" - "{\n" - " typedef _Alloc allocator_type;\n" - " typedef std::allocator_traits<_Alloc> _Base_type;\n" - " typedef typename _Alloc::value_type value_type;\n" - "\n" - " static value_type *_S_pointer_helper(...);\n" - " typedef decltype(_S_pointer_helper((_Alloc*)0)) __pointer;\n" - " typedef __pointer pointer;\n" - "\n" - " template<typename _Tp>\n" - " struct rebind\n" - " { typedef typename _Base_type::template rebind_alloc<_Tp> other; };\n" - "};\n" - "\n" - "template<typename _Iterator, typename _Container>\n" - "struct __normal_iterator\n" - "{\n" - " typedef std::iterator_traits<_Iterator> __traits_type;\n" - " typedef typename __traits_type::pointer pointer;\n" - "\n" - " pointer p;\n" - "};\n" - "} // namespace __gnu_cxx\n" - "\n" - "namespace std {\n" - "template<typename _Tp, typename _Alloc>\n" - "struct _Vector_Base\n" - "{\n" - " typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template\n" - " rebind<_Tp>::other _Tp_alloc_type;\n" - " typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer\n" - " pointer;\n" - "};\n" - "\n" - "template<typename _Tp, typename _Alloc = std::allocator<_Tp> >\n" - "struct vector : protected _Vector_Base<_Tp, _Alloc>\n" - "{\n" - " typedef _Vector_Base<_Tp, _Alloc> _Base;\n" - " typedef typename _Base::pointer pointer;\n" - " typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;\n" - "};\n" - "} // namespace std\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::vector<Foo>::iterator it;\n" - " @;\n" - "}\n" - ) << _("it.p->") << (QStringList() - << QLatin1String("Foo") - << QLatin1String("bar")); } void CppToolsPlugin::test_completion_member_access_operator() diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index fa7790a9153..eec2f2e5fe0 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -753,8 +753,8 @@ bool canCompleteClassNameAt2ndOr4thConnectArgument( || eater.eatConnectOpenParenthesisExpressionCommaAmpersandExpressionComma(); } -LookupScope *lookupScopeFromLookupItem(const LookupItem &lookupItem, - const LookupContext &context) +ClassOrNamespace *classOrNamespaceFromLookupItem(const LookupItem &lookupItem, + const LookupContext &context) { const Name *name = 0; @@ -783,7 +783,7 @@ LookupScope *lookupScopeFromLookupItem(const LookupItem &lookupItem, Class *classFromLookupItem(const LookupItem &lookupItem, const LookupContext &context) { - LookupScope *b = lookupScopeFromLookupItem(lookupItem, context); + ClassOrNamespace *b = classOrNamespaceFromLookupItem(lookupItem, context); if (!b) return 0; @@ -796,7 +796,7 @@ Class *classFromLookupItem(const LookupItem &lookupItem, const LookupContext &co const Name *minimalName(Symbol *symbol, Scope *targetScope, const LookupContext &context) { - LookupScope *target = context.lookupType(targetScope); + ClassOrNamespace *target = context.lookupType(targetScope); if (!target) target = context.globalNamespace(); return context.minimalName(symbol, target, context.bindings()->control().data()); @@ -1219,12 +1219,12 @@ bool InternalCppCompletionAssistProcessor::tryObjCCompletion() ty = ty->asPointerType()->elementType().simplified(); if (NamedType *namedTy = ty->asNamedType()) { - LookupScope *binding = lookupContext.lookupType(namedTy->name(), item.scope()); + ClassOrNamespace *binding = lookupContext.lookupType(namedTy->name(), item.scope()); completeObjCMsgSend(binding, false); } } else { if (ObjCClass *clazz = ty->asObjCClassType()) { - LookupScope *binding = lookupContext.lookupType(clazz->name(), item.scope()); + ClassOrNamespace *binding = lookupContext.lookupType(clazz->name(), item.scope()); completeObjCMsgSend(binding, true); } } @@ -1273,7 +1273,7 @@ void InternalCppCompletionAssistProcessor::addCompletionItem(Symbol *symbol, int } } -void InternalCppCompletionAssistProcessor::completeObjCMsgSend(LookupScope *binding, +void InternalCppCompletionAssistProcessor::completeObjCMsgSend(ClassOrNamespace *binding, bool staticClassAccess) { QList<Scope*> memberScopes; @@ -1542,26 +1542,26 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope) return !m_completions.isEmpty(); } - QList<LookupScope *> usingBindings; - LookupScope *currentBinding = 0; + QList<ClassOrNamespace *> usingBindings; + ClassOrNamespace *currentBinding = 0; for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) { if (Block *block = scope->asBlock()) { - if (LookupScope *binding = context.lookupType(scope)) { + if (ClassOrNamespace *binding = context.lookupType(scope)) { for (unsigned i = 0; i < scope->memberCount(); ++i) { Symbol *member = scope->memberAt(i); if (member->isEnum()) { - if (LookupScope *b = binding->findBlock(block)) + if (ClassOrNamespace *b = binding->findBlock(block)) completeNamespace(b); } if (!member->name()) continue; if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) { - if (LookupScope *b = binding->lookupType(u->name())) + if (ClassOrNamespace *b = binding->lookupType(u->name())) usingBindings.append(b); } else if (Class *c = member->asClass()) { if (c->name()->isAnonymousNameId()) { - if (LookupScope *b = binding->findBlock(block)) + if (ClassOrNamespace *b = binding->findBlock(block)) completeClass(b); } } @@ -1588,7 +1588,7 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope) } for (; currentBinding; currentBinding = currentBinding->parent()) { - foreach (LookupScope* u, currentBinding->usings()) + foreach (ClassOrNamespace* u, currentBinding->usings()) usingBindings.append(u); const QList<Symbol *> symbols = currentBinding->symbols(); @@ -1601,7 +1601,7 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope) } } - foreach (LookupScope *b, usingBindings) + foreach (ClassOrNamespace *b, usingBindings) completeNamespace(b); addKeywords(); @@ -1624,7 +1624,7 @@ bool InternalCppCompletionAssistProcessor::completeMember(const QList<LookupItem if (!m_interface->languageFeatures().objCEnabled) replaceDotForArrow = &m_model->m_replaceDotForArrow; - if (LookupScope *binding = + if (ClassOrNamespace *binding = resolveExpression.baseExpression(baseResults, m_model->m_completionOperator, replaceDotForArrow)) { @@ -1648,27 +1648,27 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem> Scope *scope = result.scope(); if (NamedType *namedTy = ty->asNamedType()) { - if (LookupScope *b = context.lookupType(namedTy->name(), scope)) { + if (ClassOrNamespace *b = context.lookupType(namedTy->name(), scope)) { completeClass(b); break; } } else if (Class *classTy = ty->asClassType()) { - if (LookupScope *b = context.lookupType(classTy)) { + if (ClassOrNamespace *b = context.lookupType(classTy)) { completeClass(b); break; } // it can be class defined inside a block if (classTy->enclosingScope()->isBlock()) { - if (LookupScope *b = context.lookupType(classTy->name(), classTy->enclosingScope())) { + if (ClassOrNamespace *b = context.lookupType(classTy->name(), classTy->enclosingScope())) { completeClass(b); break; } } } else if (Namespace *nsTy = ty->asNamespaceType()) { - if (LookupScope *b = context.lookupType(nsTy)) { + if (ClassOrNamespace *b = context.lookupType(nsTy)) { completeNamespace(b); break; } @@ -1676,7 +1676,7 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem> } else if (Template *templ = ty->asTemplateType()) { if (!result.binding()) continue; - if (LookupScope *b = result.binding()->lookupType(templ->name())) { + if (ClassOrNamespace *b = result.binding()->lookupType(templ->name())) { completeClass(b); break; } @@ -1684,16 +1684,16 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem> } else if (Enum *e = ty->asEnumType()) { // it can be class defined inside a block if (e->enclosingScope()->isBlock()) { - if (LookupScope *b = context.lookupType(e)) { + if (ClassOrNamespace *b = context.lookupType(e)) { Block *block = e->enclosingScope()->asBlock(); - if (LookupScope *bb = b->findBlock(block)) { + if (ClassOrNamespace *bb = b->findBlock(block)) { completeNamespace(bb); break; } } } - if (LookupScope *b = context.lookupType(e)) { + if (ClassOrNamespace *b = context.lookupType(e)) { completeNamespace(b); break; } @@ -1704,14 +1704,14 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem> return !m_completions.isEmpty(); } -void InternalCppCompletionAssistProcessor::completeNamespace(LookupScope *b) +void InternalCppCompletionAssistProcessor::completeNamespace(ClassOrNamespace *b) { - QSet<LookupScope *> bindingsVisited; - QList<LookupScope *> bindingsToVisit; + QSet<ClassOrNamespace *> bindingsVisited; + QList<ClassOrNamespace *> bindingsToVisit; bindingsToVisit.append(b); while (!bindingsToVisit.isEmpty()) { - LookupScope *binding = bindingsToVisit.takeFirst(); + ClassOrNamespace *binding = bindingsToVisit.takeFirst(); if (!binding || bindingsVisited.contains(binding)) continue; @@ -1744,14 +1744,14 @@ void InternalCppCompletionAssistProcessor::completeNamespace(LookupScope *b) } } -void InternalCppCompletionAssistProcessor::completeClass(LookupScope *b, bool staticLookup) +void InternalCppCompletionAssistProcessor::completeClass(ClassOrNamespace *b, bool staticLookup) { - QSet<LookupScope *> bindingsVisited; - QList<LookupScope *> bindingsToVisit; + QSet<ClassOrNamespace *> bindingsVisited; + QList<ClassOrNamespace *> bindingsToVisit; bindingsToVisit.append(b); while (!bindingsToVisit.isEmpty()) { - LookupScope *binding = bindingsToVisit.takeFirst(); + ClassOrNamespace *binding = bindingsToVisit.takeFirst(); if (!binding || bindingsVisited.contains(binding)) continue; @@ -1838,16 +1838,16 @@ bool InternalCppCompletionAssistProcessor::completeQtMethod(const QList<LookupIt QSet<QString> signatures; foreach (const LookupItem &lookupItem, results) { - LookupScope *b = lookupScopeFromLookupItem(lookupItem, context); + ClassOrNamespace *b = classOrNamespaceFromLookupItem(lookupItem, context); if (!b) continue; - QList<LookupScope *>todo; - QSet<LookupScope *> processed; + QList<ClassOrNamespace *>todo; + QSet<ClassOrNamespace *> processed; QList<Scope *> scopes; todo.append(b); while (!todo.isEmpty()) { - LookupScope *binding = todo.takeLast(); + ClassOrNamespace *binding = todo.takeLast(); if (!processed.contains(binding)) { processed.insert(binding); @@ -2063,7 +2063,7 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q Scope *scope = result.scope(); if (NamedType *namedTy = ty->asNamedType()) { - if (LookupScope *b = context.lookupType(namedTy->name(), scope)) { + if (ClassOrNamespace *b = context.lookupType(namedTy->name(), scope)) { foreach (const LookupItem &r, b->lookup(functionCallOp)) { Symbol *overload = r.declaration(); FullySpecifiedType overloadTy = overload->type().simplified(); @@ -2145,7 +2145,7 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q SubstitutionEnvironment env; env.setContext(context); env.switchScope(sc); - LookupScope *targetCoN = context.lookupType(sc); + ClassOrNamespace *targetCoN = context.lookupType(sc); if (!targetCoN) targetCoN = context.globalNamespace(); UseMinimalNames q(targetCoN); diff --git a/src/plugins/cpptools/cppcompletionassist.h b/src/plugins/cpptools/cppcompletionassist.h index 01fd44e5b86..30f88090817 100644 --- a/src/plugins/cpptools/cppcompletionassist.h +++ b/src/plugins/cpptools/cppcompletionassist.h @@ -53,7 +53,7 @@ namespace CPlusPlus { class LookupItem; -class LookupScope; +class ClassOrNamespace; class Function; class LookupContext; } // namespace CPlusPlus @@ -121,7 +121,7 @@ private: const QString &expression, int endOfExpression); - void completeObjCMsgSend(CPlusPlus::LookupScope *binding, bool staticClassAccess); + void completeObjCMsgSend(CPlusPlus::ClassOrNamespace *binding, bool staticClassAccess); bool completeInclude(const QTextCursor &cursor); void completeInclude(const QString &realPath, const QStringList &suffixes); void completePreprocessor(); @@ -130,8 +130,8 @@ private: bool toolTipOnly); bool completeMember(const QList<CPlusPlus::LookupItem> &results); bool completeScope(const QList<CPlusPlus::LookupItem> &results); - void completeNamespace(CPlusPlus::LookupScope *binding); - void completeClass(CPlusPlus::LookupScope *b, bool staticLookup = true); + void completeNamespace(CPlusPlus::ClassOrNamespace *binding); + void completeClass(CPlusPlus::ClassOrNamespace *b, bool staticLookup = true); void addClassMembersToCompletion(CPlusPlus::Scope *scope, bool staticLookup); enum CompleteQtMethodMode { CompleteQt4Signals, diff --git a/src/plugins/cpptools/cpptoolsreuse.cpp b/src/plugins/cpptools/cpptoolsreuse.cpp index f3a79429541..c70bdb14e5c 100644 --- a/src/plugins/cpptools/cpptoolsreuse.cpp +++ b/src/plugins/cpptools/cpptoolsreuse.cpp @@ -108,7 +108,7 @@ bool isOwnershipRAIIType(Symbol *symbol, const LookupContext &context) Declaration *declaration = symbol->asDeclaration(); const NamedType *namedType = declaration->type()->asNamedType(); if (namedType) { - LookupScope *clazz = context.lookupType(namedType->name(), + ClassOrNamespace *clazz = context.lookupType(namedType->name(), declaration->enclosingScope()); if (clazz && !clazz->symbols().isEmpty()) { Overview overview; diff --git a/src/plugins/cpptools/symbolfinder.cpp b/src/plugins/cpptools/symbolfinder.cpp index 3bc72c00b50..cc5006e63af 100644 --- a/src/plugins/cpptools/symbolfinder.cpp +++ b/src/plugins/cpptools/symbolfinder.cpp @@ -151,7 +151,7 @@ Function *SymbolFinder::findMatchingDefinition(Symbol *declaration, QList<Function *> viableFunctions; - LookupScope *enclosingType = context.lookupType(declaration); + ClassOrNamespace *enclosingType = context.lookupType(declaration); if (!enclosingType) continue; // nothing to do @@ -214,15 +214,13 @@ Function *SymbolFinder::findMatchingDefinition(Symbol *declaration, return 0; } -Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Snapshot &snapshot, - const LookupContext *context) +Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Snapshot &snapshot) { if (!declaration->identifier()) return 0; QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()); - const bool useLocalContext = !context; foreach (const QString &file, fileIterationOrder(declFile, snapshot)) { Document::Ptr doc = snapshot.document(file); if (!doc) { @@ -234,13 +232,9 @@ Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Sna declaration->identifier()->size())) continue; - QScopedPointer<LookupContext> localContext; - if (useLocalContext) { - localContext.reset(new LookupContext(doc, snapshot)); - context = localContext.data(); - } + LookupContext context(doc, snapshot); - LookupScope *type = context->lookupType(declaration); + ClassOrNamespace *type = context.lookupType(declaration); if (!type) continue; @@ -289,7 +283,7 @@ void SymbolFinder::findMatchingDeclaration(const LookupContext &context, if (!functionName) return; - LookupScope *binding = 0; + ClassOrNamespace *binding = 0; const QualifiedNameId *qName = functionName->asQualifiedNameId(); if (qName) { if (qName->base()) diff --git a/src/plugins/cpptools/symbolfinder.h b/src/plugins/cpptools/symbolfinder.h index 45236eb1ad9..c1d65f7716d 100644 --- a/src/plugins/cpptools/symbolfinder.h +++ b/src/plugins/cpptools/symbolfinder.h @@ -61,8 +61,7 @@ public: bool strict = false); CPlusPlus::Class *findMatchingClassDeclaration(CPlusPlus::Symbol *declaration, - const CPlusPlus::Snapshot &snapshot, - const CPlusPlus::LookupContext *context = 0); + const CPlusPlus::Snapshot &snapshot); void findMatchingDeclaration(const CPlusPlus::LookupContext &context, CPlusPlus::Function *functionType, |
