aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
authorEike Ziller <[email protected]>2017-01-11 09:29:37 +0100
committerEike Ziller <[email protected]>2017-01-11 09:29:37 +0100
commitb1f1ccb32ec31a1c4598e9fd22b23c1548a73299 (patch)
treeca92d55857a1552cd926ca858b351a905608ed34 /src/libs/cplusplus
parentfa84524c0c9b93210e4151cf772375696d0080c6 (diff)
parenta8230eb6c1a45489f33ffa86498e5ea3452496e1 (diff)
Merge remote-tracking branch 'origin/4.2'
Conflicts: src/plugins/android/androidbuildapkstep.cpp src/plugins/genericprojectmanager/genericproject.cpp Change-Id: I3484b668f9323ed0c05de99f8dfed07c9e65ab98
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/CppDocument.cpp28
-rw-r--r--src/libs/cplusplus/CppDocument.h1
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp31
3 files changed, 54 insertions, 6 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 80476dd8b1e..93f3654e4fb 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -286,8 +286,10 @@ Document::~Document()
{
delete _translationUnit;
_translationUnit = 0;
- delete _control->diagnosticClient();
- delete _control;
+ if (_control) {
+ delete _control->diagnosticClient();
+ delete _control;
+ }
_control = 0;
}
@@ -296,6 +298,25 @@ Control *Document::control() const
return _control;
}
+Control *Document::swapControl(Control *newControl)
+{
+ if (newControl) {
+ const StringLiteral *fileId = newControl->stringLiteral(_translationUnit->fileId()->chars(),
+ _translationUnit->fileId()->size());
+ const auto newTranslationUnit = new TranslationUnit(newControl, fileId);
+ newTranslationUnit->setLanguageFeatures(_translationUnit->languageFeatures());
+ delete _translationUnit;
+ _translationUnit = newTranslationUnit;
+ } else {
+ delete _translationUnit;
+ _translationUnit = 0;
+ }
+
+ Control *oldControl = _control;
+ _control = newControl;
+ return oldControl;
+}
+
unsigned Document::revision() const
{
return _revision;
@@ -696,7 +717,8 @@ void Document::releaseSourceAndAST()
if (!_keepSourceAndASTCount.deref()) {
_source.clear();
_translationUnit->release();
- _control->squeeze();
+ if (_control)
+ _control->squeeze();
}
}
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index bac2fb2a472..006f17aba68 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -78,6 +78,7 @@ public:
unsigned bytesOffset, unsigned utf16charsOffset);
Control *control() const;
+ Control *swapControl(Control *newControl);
TranslationUnit *translationUnit() const;
bool skipFunctionBody() const;
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 2f55c1564f2..69ce4f4cb4e 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -688,6 +688,31 @@ public:
bool _block;
};
+class ExpressionDocumentHelper
+{
+public:
+ // Set up an expression document with an external Control
+ ExpressionDocumentHelper(const QByteArray &utf8code, Control *control)
+ : document(Document::create(QLatin1String("<completion>")))
+ {
+ Control *oldControl = document->swapControl(control);
+ delete oldControl->diagnosticClient();
+ delete oldControl;
+ document->setUtf8Source(utf8code);
+ document->parse(Document::ParseExpression);
+ document->check();
+ }
+
+ // Ensure that the external Control is not deleted
+ ~ExpressionDocumentHelper()
+ {
+ document->swapControl(nullptr);
+ }
+
+public:
+ Document::Ptr document;
+};
+
} // namespace anonymous
bool ResolveExpression::visit(SimpleNameAST *ast)
@@ -730,9 +755,9 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
exprTyper.init(doc, _context.snapshot(), _context.bindings(),
QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
- Document::Ptr exprDoc =
- documentForExpression(exprTyper.preprocessedExpression(initializer));
- exprDoc->check();
+ const ExpressionDocumentHelper exprHelper(exprTyper.preprocessedExpression(initializer),
+ _context.bindings()->control().data());
+ const Document::Ptr exprDoc = exprHelper.document;
DeduceAutoCheck deduceAuto(ast->name->identifier(), exprDoc->translationUnit());
if (deduceAuto._block)