aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@digia.com>2013-06-11 09:22:18 +0200
committerNikolai Kosjar <nikolai.kosjar@digia.com>2013-06-25 11:04:17 +0200
commit8aa8f225369603e1e9ea019ca043715b08a61e82 (patch)
tree494c3fe911e133e17a73d448f3964df725f079fd
parent1477729aa0590a6f5041164f56d8c7e8e8249d2e (diff)
C++: Handle recursive auto declarations
Remember auto declarations we have already looked up and stop if we try it again. Task-number: QTCREATORBUG-9503 Change-Id: I989b11609c98bf197ce916d79c9d452294355053 Reviewed-by: Przemyslaw Gorszkowski <pgorszkowski@gmail.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com> (cherry picked from commit 8f1b6656677344e9ca4b6798ddd900725c478b16)
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp15
-rw-r--r--src/libs/cplusplus/ResolveExpression.h5
-rw-r--r--src/libs/cplusplus/TypeOfExpression.cpp8
-rw-r--r--src/libs/cplusplus/TypeOfExpression.h9
-rw-r--r--src/plugins/cpptools/cppcompletion_test.cpp53
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.h2
6 files changed, 82 insertions, 10 deletions
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index b547c22d68..32dcbeb4e6 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -75,11 +75,13 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
/////////////////////////////////////////////////////////////////////
// ResolveExpression
/////////////////////////////////////////////////////////////////////
-ResolveExpression::ResolveExpression(const LookupContext &context)
+ResolveExpression::ResolveExpression(const LookupContext &context,
+ const QSet<const Declaration *> &autoDeclarationsBeingResolved)
: ASTVisitor(context.expressionDocument()->translationUnit()),
_scope(0),
_context(context),
bind(context.expressionDocument()->translationUnit()),
+ _autoDeclarationsBeingResolved(autoDeclarationsBeingResolved),
_reference(false)
{ }
@@ -519,6 +521,10 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (!decl)
continue;
+ // Stop on recursive auto declarations
+ if (_autoDeclarationsBeingResolved.contains(decl))
+ continue;
+
const StringLiteral *initializationString = decl->getInitializer();
if (initializationString == 0)
continue;
@@ -533,7 +539,8 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
TypeOfExpression exprTyper;
Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
- exprTyper.init(doc, _context.snapshot(), _context.bindings());
+ exprTyper.init(doc, _context.snapshot(), _context.bindings(),
+ QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
Document::Ptr exprDoc =
documentForExpression(exprTyper.preprocessedExpression(initializer));
@@ -543,8 +550,8 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (deduceAuto._block)
continue;
- const QList<LookupItem> &typeItems =
- exprTyper(extractExpressionAST(exprDoc), exprDoc, decl->enclosingScope());
+ const QList<LookupItem> &typeItems = exprTyper(extractExpressionAST(exprDoc), exprDoc,
+ decl->enclosingScope());
if (typeItems.empty())
continue;
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index e6ce50dde4..922d1b6bf0 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -42,7 +42,9 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor
{
public:
- ResolveExpression(const LookupContext &context);
+ ResolveExpression(const LookupContext &context,
+ const QSet<const Declaration *> &autoDeclarationsBeingResolved
+ = QSet<const Declaration *>());
virtual ~ResolveExpression();
QList<LookupItem> operator()(ExpressionAST *ast, Scope *scope);
@@ -125,6 +127,7 @@ private:
const LookupContext& _context;
Bind bind;
QList<LookupItem> _results;
+ QSet<const Declaration *> _autoDeclarationsBeingResolved;
bool _reference;
};
diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp
index ac813fa873..7025c474c1 100644
--- a/src/libs/cplusplus/TypeOfExpression.cpp
+++ b/src/libs/cplusplus/TypeOfExpression.cpp
@@ -58,7 +58,8 @@ void TypeOfExpression::reset()
}
void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot,
- QSharedPointer<CreateBindings> bindings)
+ QSharedPointer<CreateBindings> bindings,
+ const QSet<const Declaration *> &autoDeclarationsBeingResolved)
{
m_thisDocument = thisDocument;
m_snapshot = snapshot;
@@ -67,6 +68,7 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
m_lookupContext = LookupContext();
m_bindings = bindings;
m_environment.clear();
+ m_autoDeclarationsBeingResolved = autoDeclarationsBeingResolved;
}
QList<LookupItem> TypeOfExpression::operator()(const QByteArray &utf8code,
@@ -111,7 +113,7 @@ QList<LookupItem> TypeOfExpression::operator()(ExpressionAST *expression,
m_lookupContext.setBindings(m_bindings);
m_lookupContext.setExpandTemplates(m_expandTemplates);
- ResolveExpression resolve(m_lookupContext);
+ ResolveExpression resolve(m_lookupContext, m_autoDeclarationsBeingResolved);
const QList<LookupItem> items = resolve(m_ast, scope);
if (! m_bindings)
@@ -133,7 +135,7 @@ QList<LookupItem> TypeOfExpression::reference(ExpressionAST *expression,
m_lookupContext.setBindings(m_bindings);
m_lookupContext.setExpandTemplates(m_expandTemplates);
- ResolveExpression resolve(m_lookupContext);
+ ResolveExpression resolve(m_lookupContext, m_autoDeclarationsBeingResolved);
const QList<LookupItem> items = resolve.reference(m_ast, scope);
if (! m_bindings)
diff --git a/src/libs/cplusplus/TypeOfExpression.h b/src/libs/cplusplus/TypeOfExpression.h
index adeb1d9644..a6743e3989 100644
--- a/src/libs/cplusplus/TypeOfExpression.h
+++ b/src/libs/cplusplus/TypeOfExpression.h
@@ -58,8 +58,11 @@ public:
* Also clears the lookup context, so can be used to make sure references
* to the documents previously used are removed.
*/
- void init(Document::Ptr thisDocument, const Snapshot &snapshot,
- QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>());
+ void init(Document::Ptr thisDocument,
+ const Snapshot &snapshot,
+ QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>(),
+ const QSet<const Declaration *> &autoDeclarationsBeingResolved
+ = QSet<const Declaration *>());
void reset();
@@ -151,6 +154,8 @@ private:
// Keep the expression documents and thus all the symbols and
// their types alive until they are not needed any more.
QList<Document::Ptr> m_documents;
+
+ QSet<const Declaration *> m_autoDeclarationsBeingResolved;
};
ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc);
diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp
index 11e380092b..44f9178cdb 100644
--- a/src/plugins/cpptools/cppcompletion_test.cpp
+++ b/src/plugins/cpptools/cppcompletion_test.cpp
@@ -1832,3 +1832,56 @@ void CppToolsPlugin::test_completion_crash_cloning_template_class_QTCREATORBUG93
QVERIFY(completions.contains(QLatin1String("Templ")));
QVERIFY(completions.contains(QLatin1String("f")));
}
+
+void CppToolsPlugin::test_completion_recursive_auto_declarations1_QTCREATORBUG9503()
+{
+ TestData data;
+ data.srcText =
+ "void f()\n"
+ "{\n"
+ " auto object2 = object1;\n"
+ " auto object1 = object2;\n"
+ " @;\n"
+ " // padding so we get the scope right\n"
+ "}\n"
+ ;
+ setup(&data);
+
+ Utils::ChangeSet change;
+ QString txt = QLatin1String("object1.");
+ change.insert(data.pos, txt);
+ QTextCursor cursor(data.doc);
+ change.apply(&cursor);
+ data.pos += txt.length();
+
+ QStringList completions = getCompletions(data);
+
+ QCOMPARE(completions.size(), 0);
+}
+
+void CppToolsPlugin::test_completion_recursive_auto_declarations2_QTCREATORBUG9503()
+{
+ TestData data;
+ data.srcText =
+ "void f()\n"
+ "{\n"
+ " auto object3 = object1;\n"
+ " auto object2 = object3;\n"
+ " auto object1 = object2;\n"
+ " @;\n"
+ " // padding so we get the scope right\n"
+ "}\n"
+ ;
+ setup(&data);
+
+ Utils::ChangeSet change;
+ QString txt = QLatin1String("object1.");
+ change.insert(data.pos, txt);
+ QTextCursor cursor(data.doc);
+ change.apply(&cursor);
+ data.pos += txt.length();
+
+ QStringList completions = getCompletions(data);
+
+ QCOMPARE(completions.size(), 0);
+}
diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h
index bf9c9b67a5..0b3998c9e6 100644
--- a/src/plugins/cpptools/cpptoolsplugin.h
+++ b/src/plugins/cpptools/cpptoolsplugin.h
@@ -128,6 +128,8 @@ private slots:
void test_completion_typedef_using_templates2();
void test_completion_namespace_alias_with_many_namespace_declarations();
void test_completion_crash_cloning_template_class_QTCREATORBUG9329();
+ void test_completion_recursive_auto_declarations1_QTCREATORBUG9503();
+ void test_completion_recursive_auto_declarations2_QTCREATORBUG9503();
void test_format_pointerdeclaration_in_simpledeclarations();
void test_format_pointerdeclaration_in_simpledeclarations_data();