diff --git a/src/libs/cplusplus/Icons.cpp b/src/libs/cplusplus/Icons.cpp index 3b3e3e1fb0b5378cc70efefd4bdfb8c089698413..db57e05e5944963eeb177ef5ace4a2bdb2dcc1e2 100644 --- a/src/libs/cplusplus/Icons.cpp +++ b/src/libs/cplusplus/Icons.cpp @@ -124,6 +124,8 @@ Icons::IconType Icons::iconTypeForSymbol(const Symbol *symbol) return FuncPublicIconType; } else if (symbol->isNamespace()) { return NamespaceIconType; + } else if (symbol->isTypenameArgument()) { + return ClassIconType; } else if (symbol->isUsingNamespaceDirective() || symbol->isUsingDeclaration()) { // TODO: Might be nice to have a different icons for these things diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 5096262a3c13cdb4047be35b9cabe9a1f036357a..657b6397aaefade35fbdece5beffc38867df70fa 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -1185,6 +1185,64 @@ void CppToolsPlugin::test_completion_cyclic_inheritance_data() << code << completions; } +void CppToolsPlugin::test_completion_template_function() +{ + QFETCH(QByteArray, code); + QFETCH(QStringList, expectedCompletions); + + TestData data; + data.srcText = code; + setup(&data); + + QStringList actualCompletions = getCompletions(data); + actualCompletions.sort(); + expectedCompletions.sort(); + + QString errorPattern(QLatin1String("Completion not found: %1")); + foreach (const QString &completion, expectedCompletions) { + QByteArray errorMessage = errorPattern.arg(completion).toUtf8(); + QVERIFY2(actualCompletions.contains(completion), errorMessage.data()); + } +} + +void CppToolsPlugin::test_completion_template_function_data() +{ + QTest::addColumn<QByteArray>("code"); + QTest::addColumn<QStringList>("expectedCompletions"); + + QByteArray code; + QStringList completions; + + code = "\n" + "template <class tclass, typename tname, int tint>\n" + "tname Hello(const tclass &e)\n" + "{\n" + " tname e2 = e;\n" + " @\n" + "}"; + + completions.append(QLatin1String("tclass")); + completions.append(QLatin1String("tname")); + completions.append(QLatin1String("tint")); + QTest::newRow("case: template parameters in template function body") + << code << completions; + + completions.clear(); + + code = "\n" + "template <class tclass, typename tname, int tint>\n" + "tname Hello(const tclass &e, @)\n" + "{\n" + " tname e2 = e;\n" + "}"; + + completions.append(QLatin1String("tclass")); + completions.append(QLatin1String("tname")); + completions.append(QLatin1String("tint")); + QTest::newRow("case: template parameters in template function parameters list") + << code << completions; +} + void CppToolsPlugin::test_completion_enclosing_template_class() { test_completion(); diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 6511b775458985887550608257f79404adff56e6..8f90aefb997bc00c6f82edd4a0c61beffed067d8 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -1354,8 +1354,11 @@ void CppCompletionAssistProcessor::globalCompletion(CPlusPlus::Scope *currentSco for (unsigned i = 0, argc = fun->argumentCount(); i < argc; ++i) { addCompletionItem(fun->argumentAt(i), FunctionArgumentsOrder); } - break; - } else { + } else if (scope->isTemplate()) { + Template *templ = scope->asTemplate(); + for (unsigned i = 0, argc = templ->templateParameterCount(); i < argc; ++i) { + addCompletionItem(templ->templateParameterAt(i), FunctionArgumentsOrder); + } break; } } diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 96d79de4377b305f726a4e65ec3f238a89eca80c..179fa41762383a234eeec2b04a9439e82099a525 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -104,6 +104,8 @@ private slots: void test_completion_base_class_has_name_the_same_as_derived_data(); void test_completion_cyclic_inheritance(); void test_completion_cyclic_inheritance_data(); + void test_completion_template_function(); + void test_completion_template_function_data(); void test_completion_enclosing_template_class(); void test_completion_enclosing_template_class_data(); void test_completion_instantiate_nested_class_when_enclosing_is_template();