Commit 17cd161a authored by Przemyslaw Gorszkowski's avatar Przemyslaw Gorszkowski Committed by Nikolai Kosjar

C++: fix cloning of templates

Fix instantiation of templates(by cloning original symbols). Assigning of scope
for cloned symbol is taken from the symbol which is used to instantiate.

Task-number: QTCREATORBUG-9098
Change-Id: I066cc8b5f69333fabdaf2d4466b205baf08bd3f1
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent b55961d2
...@@ -105,7 +105,7 @@ Symbol::Symbol(TranslationUnit *translationUnit, unsigned sourceLocation, const ...@@ -105,7 +105,7 @@ Symbol::Symbol(TranslationUnit *translationUnit, unsigned sourceLocation, const
Symbol::Symbol(Clone *clone, Subst *subst, Symbol *original) Symbol::Symbol(Clone *clone, Subst *subst, Symbol *original)
: _name(clone->name(original->_name, subst)), : _name(clone->name(original->_name, subst)),
_scope(original->_scope), _scope(0),
_next(0), _next(0),
_fileId(clone->control()->stringLiteral(original->fileName(), original->fileNameLength())), _fileId(clone->control()->stringLiteral(original->fileName(), original->fileNameLength())),
_sourceLocation(original->_sourceLocation), _sourceLocation(original->_sourceLocation),
...@@ -296,6 +296,11 @@ Block *Symbol::enclosingBlock() const ...@@ -296,6 +296,11 @@ Block *Symbol::enclosingBlock() const
return 0; return 0;
} }
Scope *Symbol::scope() const
{
return _scope;
}
unsigned Symbol::index() const unsigned Symbol::index() const
{ return _index; } { return _index; }
......
...@@ -290,6 +290,7 @@ public: ...@@ -290,6 +290,7 @@ public:
/// Returns the enclosing Block scope. /// Returns the enclosing Block scope.
Block *enclosingBlock() const; Block *enclosingBlock() const;
Scope *scope() const;
void setScope(Scope *enclosingScope); // ### make me private void setScope(Scope *enclosingScope); // ### make me private
void resetScope(); // ### make me private void resetScope(); // ### make me private
void setSourceLocation(unsigned sourceLocation, TranslationUnit *translationUnit); // ### make me private void setSourceLocation(unsigned sourceLocation, TranslationUnit *translationUnit); // ### make me private
......
...@@ -936,6 +936,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac ...@@ -936,6 +936,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
foreach (Symbol *s, reference->symbols()) { foreach (Symbol *s, reference->symbols()) {
Symbol *clone = cloner.symbol(s, &subst); Symbol *clone = cloner.symbol(s, &subst);
clone->setScope(s->scope());
instantiation->_symbols.append(clone); instantiation->_symbols.append(clone);
#ifdef DEBUG_LOOKUP #ifdef DEBUG_LOOKUP
Overview oo;oo.showFunctionSignatures = true; Overview oo;oo.showFunctionSignatures = true;
...@@ -1089,6 +1090,7 @@ void ClassOrNamespace::NestedClassInstantiator::instantiate(ClassOrNamespace *en ...@@ -1089,6 +1090,7 @@ void ClassOrNamespace::NestedClassInstantiator::instantiate(ClassOrNamespace *en
foreach (Symbol *s, nestedClassOrNamespace->_symbols) { foreach (Symbol *s, nestedClassOrNamespace->_symbols) {
Symbol *clone = _cloner.symbol(s, &_subst); Symbol *clone = _cloner.symbol(s, &_subst);
clone->setScope(s->scope());
nestedClassOrNamespaceInstantiation->_symbols.append(clone); nestedClassOrNamespaceInstantiation->_symbols.append(clone);
} }
} }
......
...@@ -1843,3 +1843,42 @@ void CppToolsPlugin::test_completion_namespace_alias_with_many_namespace_declara ...@@ -1843,3 +1843,42 @@ void CppToolsPlugin::test_completion_namespace_alias_with_many_namespace_declara
QVERIFY(completions.contains(QLatin1String("Foo1"))); QVERIFY(completions.contains(QLatin1String("Foo1")));
QVERIFY(completions.contains(QLatin1String("Foo2"))); QVERIFY(completions.contains(QLatin1String("Foo2")));
} }
void CppToolsPlugin::test_completion_QTCREATORBUG9098()
{
TestData data;
data.srcText =
"template <typename T>\n"
"class B\n"
"{\n"
"public:\n"
" C<T> c;\n"
"};\n"
"template <typename T>\n"
"class A\n"
"{\n"
"public:\n"
" B<T> b;\n"
" void fun()\n"
" {\n"
" @\n"
" // padding so we get the scope right\n"
" }\n"
"};\n"
;
setup(&data);
Utils::ChangeSet change;
QString txt = QLatin1String("b.");
change.insert(data.pos, txt);
QTextCursor cursor(data.doc);
change.apply(&cursor);
data.pos += txt.length();
QStringList completions = getCompletions(data);
QCOMPARE(completions.size(), 2);
QVERIFY(completions.contains(QLatin1String("c")));
QVERIFY(completions.contains(QLatin1String("B")));
}
...@@ -123,6 +123,7 @@ private slots: ...@@ -123,6 +123,7 @@ private slots:
void test_completion_typedef_using_templates1(); void test_completion_typedef_using_templates1();
void test_completion_typedef_using_templates2(); void test_completion_typedef_using_templates2();
void test_completion_namespace_alias_with_many_namespace_declarations(); void test_completion_namespace_alias_with_many_namespace_declarations();
void test_completion_QTCREATORBUG9098();
void test_format_pointerdeclaration_in_simpledeclarations(); void test_format_pointerdeclaration_in_simpledeclarations();
void test_format_pointerdeclaration_in_simpledeclarations_data(); void test_format_pointerdeclaration_in_simpledeclarations_data();
......
...@@ -185,6 +185,7 @@ private slots: ...@@ -185,6 +185,7 @@ private slots:
void test_checksymbols_QTCREATORBUG8974_danglingPointer(); void test_checksymbols_QTCREATORBUG8974_danglingPointer();
void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006(); void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006();
void test_checksymbols_templated_functions(); void test_checksymbols_templated_functions();
void test_checksymbols_QTCREATORBUG9098();
}; };
void tst_CheckSymbols::test_checksymbols_TypeUse() void tst_CheckSymbols::test_checksymbols_TypeUse()
...@@ -1415,6 +1416,44 @@ void tst_CheckSymbols::test_checksymbols_templated_functions() ...@@ -1415,6 +1416,44 @@ void tst_CheckSymbols::test_checksymbols_templated_functions()
<< Use(6, 17, 1, SemanticInfo::TypeUse) << Use(6, 17, 1, SemanticInfo::TypeUse)
; ;
}
void tst_CheckSymbols::test_checksymbols_QTCREATORBUG9098()
{
const QByteArray source =
"template <typename T>\n"
"class B\n"
"{\n"
"public:\n"
" C<T> c;\n"
"};\n"
"template <typename T>\n"
"class A\n"
"{\n"
"public:\n"
" B<T> b;\n"
" void fun()\n"
" {\n"
" b.c;\n"
" }\n"
"}\n"
;
const QList<Use> expectedUses = QList<Use>()
<< Use(1, 20, 1, SemanticInfo::TypeUse)
<< Use(2, 7, 1, SemanticInfo::TypeUse)
<< Use(5, 7, 1, SemanticInfo::TypeUse)
<< Use(5, 10, 1, SemanticInfo::FieldUse)
<< Use(7, 20, 1, SemanticInfo::TypeUse)
<< Use(8, 7, 1, SemanticInfo::TypeUse)
<< Use(11, 5, 1, SemanticInfo::TypeUse)
<< Use(11, 7, 1, SemanticInfo::TypeUse)
<< Use(11, 10, 1, SemanticInfo::FieldUse)
<< Use(12, 10, 3, SemanticInfo::FunctionUse)
<< Use(14, 9, 1, SemanticInfo::FieldUse)
<< Use(14, 11, 1, SemanticInfo::FieldUse)
;
TestData::check(source, expectedUses); TestData::check(source, expectedUses);
} }
......
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