summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2015-09-04 11:54:58 +0200
committerEike Ziller <eike.ziller@theqtcompany.com>2015-09-10 12:00:01 +0000
commit915f68deac95bf17bd97d1a2644264afb0b86f0b (patch)
treeaa0a3afbc2720d91a6d8b712e80f784a0f2b375b
parenta2bd8e11f6c9196f968fc1944952077416921307 (diff)
downloadqt-creator-915f68deac95bf17bd97d1a2644264afb0b86f0b.tar.gz
C++: Revert problematic template specialization changes
This mainly reverts commit 81721f678122bc66213b5f2a5fbf36c43e5e1a35 C++: Fix resolving of recursive typedef commit 2070431d8ca867acfb4391c275cd82caff4d711a C++: Fix resolving of partial specialization and some bits of other changes due to dependencies. It also reverts commit e0594fc9b906a32f5c8ac70265490cf86044676f C++: Fix expensive lookup for boost which attempted to solve the upcoming problems. Task-number: QTCREATORBUG-14741 Task-number: QTCREATORBUG-14889 Task-number: QTCREATORBUG-14962 Change-Id: I3f9e1f97199e5199b71da394fc27051c7709bd1f Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
-rw-r--r--src/libs/cplusplus/LookupContext.cpp131
-rw-r--r--src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp1
-rw-r--r--src/plugins/cpptools/cppcompletion_test.cpp5
-rw-r--r--tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp2
4 files changed, 57 insertions, 82 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index ef4a766fd7..0364b59c72 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -570,7 +570,7 @@ private:
LookupScopePrivate *nestedType(const Name *name, LookupScopePrivate *origin);
- LookupScopePrivate *findSpecialization(const Template *baseTemplate, const TemplateNameId *templId,
+ LookupScopePrivate *findSpecialization(const TemplateNameId *templId,
const TemplateNameIdTable &specializations,
LookupScopePrivate *origin);
@@ -1001,11 +1001,13 @@ LookupScope *LookupScopePrivate::lookupType_helper(
}
if (const QualifiedNameId *qName = name->asQualifiedNameId()) {
+
+ ProcessedSet innerProcessed;
if (! qName->base())
- return globalNamespace()->d->lookupType_helper(qName->name(), processed, true, origin);
+ return globalNamespace()->d->lookupType_helper(qName->name(), &innerProcessed, true, origin);
if (LookupScope *binding = lookupType_helper(qName->base(), processed, true, origin))
- return binding->d->lookupType_helper(qName->name(), processed, false, origin);
+ return binding->d->lookupType_helper(qName->name(), &innerProcessed, false, origin);
return 0;
@@ -1017,7 +1019,7 @@ LookupScope *LookupScopePrivate::lookupType_helper(
foreach (Symbol *s, _symbols) {
if (Class *klass = s->asClass()) {
- if (klass->name() && klass->name()->match(name))
+ if (klass->identifier() && klass->identifier()->match(name->identifier()))
return q;
}
}
@@ -1051,29 +1053,9 @@ LookupScope *LookupScopePrivate::lookupType_helper(
return 0;
}
-static const NamedType *dereference(const FullySpecifiedType &type)
+static LookupScopePrivate *findSpecializationWithMatchingTemplateArgument(
+ const Name *argumentName, LookupScopePrivate *reference)
{
- FullySpecifiedType ty = type;
- forever {
- if (PointerType *pointer = ty->asPointerType())
- ty = pointer->elementType();
- else if (ReferenceType *reference = ty->asReferenceType())
- ty = reference->elementType();
- else if (ArrayType *array = ty->asArrayType())
- ty = array->elementType();
- else if (const NamedType *namedType = ty->asNamedType())
- return namedType;
- else
- break;
- }
- return 0;
-}
-
-static bool findTemplateArgument(const NamedType *namedType, LookupScopePrivate *reference)
-{
- if (!namedType)
- return false;
- const Name *argumentName = namedType->name();
foreach (Symbol *s, reference->_symbols) {
if (Class *clazz = s->asClass()) {
if (Template *templateSpecialization = clazz->enclosingTemplate()) {
@@ -1084,67 +1066,67 @@ static bool findTemplateArgument(const NamedType *namedType, LookupScopePrivate
= templateSpecialization->templateParameterAt(i)->asTypenameArgument()) {
if (const Name *name = tParam->name()) {
if (compareName(name, argumentName))
- return true;
+ return reference;
}
}
}
}
}
}
- return false;
-}
-
-static bool matchTypes(const FullySpecifiedType &instantiation,
- const FullySpecifiedType &specialization)
-{
- if (specialization.match(instantiation))
- return true;
- if (const NamedType *specName = specialization->asNamedType()) {
- if (const NamedType *initName = instantiation->asNamedType()) {
- if (specName->name()->identifier()->match(initName->name()->identifier()))
- return true;
- }
- }
- return false;
+ return 0;
}
LookupScopePrivate *LookupScopePrivate::findSpecialization(
- const Template *baseTemplate,
const TemplateNameId *templId,
const TemplateNameIdTable &specializations,
LookupScopePrivate *origin)
{
- Clone cloner(_factory->control().data());
for (TemplateNameIdTable::const_iterator cit = specializations.begin();
cit != specializations.end(); ++cit) {
const TemplateNameId *specializationNameId = cit->first;
const unsigned specializationTemplateArgumentCount
= specializationNameId->templateArgumentCount();
- Subst subst(_factory->control().data());
- bool match = true;
- for (unsigned i = 0; i < specializationTemplateArgumentCount && match; ++i) {
+ const unsigned initializationTemplateArgumentCount = templId->templateArgumentCount();
+ // for now it works only when we have the same number of arguments in specialization
+ // and initialization(in future it should be more clever)
+ if (specializationTemplateArgumentCount != initializationTemplateArgumentCount)
+ continue;
+ for (unsigned i = 0; i < initializationTemplateArgumentCount; ++i) {
const FullySpecifiedType &specializationTemplateArgument
= specializationNameId->templateArgumentAt(i);
- FullySpecifiedType initializationTemplateArgument =
- _factory->resolveTemplateArgument(cloner, subst, origin ? origin->q : 0,
- baseTemplate, templId, i);
+ FullySpecifiedType initializationTemplateArgument = templId->templateArgumentAt(i);
+ TypeResolver typeResolver(*_factory);
+ Scope *scope = 0;
+ typeResolver.resolve(&initializationTemplateArgument, &scope, origin ? origin->q : 0);
+ PointerType *specPointer = specializationTemplateArgument.type()->asPointerType();
// specialization and initialization argument have to be a pointer
// additionally type of pointer argument of specialization has to be namedType
- if (findTemplateArgument(dereference(specializationTemplateArgument), cit->second)) {
- if (specializationTemplateArgument->isPointerType())
- match = initializationTemplateArgument->isPointerType();
- else if (specializationTemplateArgument->isReferenceType())
- match = initializationTemplateArgument->isReferenceType();
- else if (specializationTemplateArgument->isArrayType())
- match = initializationTemplateArgument->isArrayType();
- // Do not try exact match (typename T != class T {};)
- } else {
- // Real type specialization
- match = matchTypes(initializationTemplateArgument, specializationTemplateArgument);
+ if (specPointer && initializationTemplateArgument.type()->isPointerType()
+ && specPointer->elementType().type()->isNamedType()) {
+ return cit->second;
+ }
+
+ ArrayType *specArray = specializationTemplateArgument.type()->asArrayType();
+ if (specArray && initializationTemplateArgument.type()->isArrayType()) {
+ if (const NamedType *argumentNamedType
+ = specArray->elementType().type()->asNamedType()) {
+ if (const Name *argumentName = argumentNamedType->name()) {
+ if (LookupScopePrivate *reference
+ = findSpecializationWithMatchingTemplateArgument(
+ argumentName, cit->second)) {
+ return reference;
+ }
+ }
+ }
+ }
+
+ if (const NamedType *specName = specializationTemplateArgument->asNamedType()) {
+ if (const NamedType *initName = initializationTemplateArgument->asNamedType()) {
+ if (specName->name()->identifier() == initName->name()->identifier())
+ return cit->second;
+ }
}
}
- if (match)
- return cit->second;
}
return 0;
@@ -1245,23 +1227,12 @@ LookupScopePrivate *LookupScopePrivate::nestedType(const Name *name, LookupScope
// we found full specialization
reference = cit->second;
} else {
- Template *baseTemplate = 0;
- foreach (Symbol *s, reference->_symbols) {
- if (Class *clazz = s->asClass())
- baseTemplate = clazz->enclosingTemplate();
- else if (ForwardClassDeclaration *forward = s->asForwardClassDeclaration())
- baseTemplate = forward->enclosingTemplate();
- if (baseTemplate)
- break;
- }
- if (baseTemplate) {
- if (LookupScopePrivate *specialization =
- findSpecialization(baseTemplate, templId, specializations, origin)) {
- reference = specialization;
- if (Q_UNLIKELY(debug)) {
- Overview oo;
- qDebug() << "picked specialization" << oo(specialization->_name);
- }
+ if (LookupScopePrivate *specialization =
+ findSpecialization(templId, specializations, origin)) {
+ reference = specialization;
+ if (Q_UNLIKELY(debug)) {
+ Overview oo;
+ qDebug() << "picked specialization" << oo(specialization->_name);
}
}
}
diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
index 6f98752d46..956b02b5d9 100644
--- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
+++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
@@ -369,7 +369,6 @@ F2TestCase::F2TestCase(CppEditorAction action,
QEXPECT_FAIL("globalVarFromEnum", "Contributor works on a fix.", Abort);
QEXPECT_FAIL("matchFunctionSignature_Follow_5", "foo(int) resolved as CallAST", Abort);
- QEXPECT_FAIL("qualifiedNames", "Regression since e0594fc9b906a32f5c8ac70265490cf86044676f", Abort);
QCOMPARE(currentTextEditor->currentLine(), expectedLine);
QCOMPARE(currentTextEditor->currentColumn() - 1, expectedColumn);
diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp
index 15a1a43de9..8dbb838c99 100644
--- a/src/plugins/cpptools/cppcompletion_test.cpp
+++ b/src/plugins/cpptools/cppcompletion_test.cpp
@@ -328,11 +328,16 @@ void CppToolsPlugin::test_completion()
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("partial_specialization_with_pointer", "test of reverted change", 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);
QCOMPARE(actualCompletions, expectedCompletions);
}
diff --git a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
index b343b99357..57c9f33823 100644
--- a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
+++ b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
@@ -1213,7 +1213,7 @@ void tst_CheckSymbols::findField()
BaseTestCase tc(source);
Use use = tc.findUse(line, column);
- QEXPECT_FAIL("std vector", "Regression since e0594fc9b906a32f5c8ac70265490cf86044676f", Abort);
+ QEXPECT_FAIL("recursive_instantiation_of_template_type", "QTCREATORBUG-14237", Abort);
QVERIFY(use.isValid());
QVERIFY(use.kind == Highlighting::FieldUse);
}