summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2020-05-18 17:40:19 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2020-05-26 08:50:58 +0000
commit949bb0e67bbf6e7d8208dad9876382ef8ce5eb59 (patch)
treeb850c89d83d3cffaba326dda7426b180b88212da
parent227904d4a691b99789f1dc43f9b31d857279c896 (diff)
downloadqt-creator-949bb0e67bbf6e7d8208dad9876382ef8ce5eb59.tar.gz
ClangCodeModel: Show value in tool tips, if possible
When hovering over a constant expression, it's probably helpful to show that value to the user. Requires clang 11 to fully work. For now, it only shows the value for variable initializations. Fixes: QTCREATORBUG-23967 Change-Id: I6b844231bac50993c2fa2fa82c552ad9cef590df Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
-rw-r--r--src/libs/clangsupport/tooltipinfo.h6
-rw-r--r--src/plugins/clangcodemodel/clangbackendreceiver.cpp2
-rw-r--r--src/plugins/clangcodemodel/clanghoverhandler.cpp16
-rw-r--r--src/plugins/cpptools/baseeditordocumentprocessor.h3
-rw-r--r--src/tools/clangbackend/source/clangtooltipinfocollector.cpp23
-rw-r--r--tests/unit/unittest/clangtooltipinfo-test.cpp9
-rw-r--r--tests/unit/unittest/data/tooltipinfo.cpp3
7 files changed, 61 insertions, 1 deletions
diff --git a/src/libs/clangsupport/tooltipinfo.h b/src/libs/clangsupport/tooltipinfo.h
index b8f828a52e..f50c93a53e 100644
--- a/src/libs/clangsupport/tooltipinfo.h
+++ b/src/libs/clangsupport/tooltipinfo.h
@@ -28,6 +28,8 @@
#include <utf8string.h>
#include <utf8stringvector.h>
+#include <QVariant>
+
namespace ClangBackEnd {
class ToolTipInfo
@@ -54,6 +56,7 @@ public:
out << message.qdocIdCandidates;
out << message.qdocMark;
out << static_cast<quint8>(message.qdocCategory);
+ out << message.value;
out << message.sizeInBytes;
return out;
@@ -68,6 +71,7 @@ public:
in >> message.qdocIdCandidates;
in >> message.qdocMark;
in >> qdocCategory;
+ in >> message.value;
in >> message.sizeInBytes;
message.qdocCategory = static_cast<QdocCategory>(qdocCategory);
@@ -82,6 +86,7 @@ public:
&& first.qdocIdCandidates == second.qdocIdCandidates
&& first.qdocMark == second.qdocMark
&& first.qdocCategory == second.qdocCategory
+ && first.value == second.value
&& first.sizeInBytes == second.sizeInBytes;
}
@@ -92,6 +97,7 @@ public:
Utf8StringVector qdocIdCandidates;
Utf8String qdocMark;
QdocCategory qdocCategory = Unknown;
+ QVariant value;
// For class definition and for class fields.
Utf8String sizeInBytes;
diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp
index 181737d61b..47d624a147 100644
--- a/src/plugins/clangcodemodel/clangbackendreceiver.cpp
+++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp
@@ -339,7 +339,7 @@ static CppTools::ToolTipInfo toToolTipInfo(const ToolTipMessage &message)
info.qDocIdCandidates = toStringList(backendInfo.qdocIdCandidates);
info.qDocMark = backendInfo.qdocMark;
info.qDocCategory = toHelpItemCategory(backendInfo.qdocCategory);
-
+ info.value = backendInfo.value;
info.sizeInBytes = backendInfo.sizeInBytes;
return info;
diff --git a/src/plugins/clangcodemodel/clanghoverhandler.cpp b/src/plugins/clangcodemodel/clanghoverhandler.cpp
index ddd2940522..ff106ed16e 100644
--- a/src/plugins/clangcodemodel/clanghoverhandler.cpp
+++ b/src/plugins/clangcodemodel/clanghoverhandler.cpp
@@ -181,6 +181,22 @@ void ClangHoverHandler::processToolTipInfo(const CppTools::ToolTipInfo &info)
if (!info.sizeInBytes.isEmpty())
text.append("\n\n" + tr("%1 bytes").arg(info.sizeInBytes));
+ if (info.value.isValid()) {
+ text.append("\n\n" + tr("Value: "));
+ switch (info.value.type()) {
+ case static_cast<QVariant::Type>(QMetaType::LongLong):
+ text.append(QString::number(info.value.toLongLong()));
+ break;
+ case static_cast<QVariant::Type>(QMetaType::ULongLong):
+ text.append(QString::number(info.value.toULongLong()));
+ break;
+ case static_cast<QVariant::Type>(QMetaType::Double):
+ text.append(QString::number(info.value.toDouble()));
+ break;
+ default:
+ QTC_CHECK(false);
+ }
+ }
setToolTip(text);
m_reportPriority(priority());
diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h
index cf08f7b5c4..88a91158d5 100644
--- a/src/plugins/cpptools/baseeditordocumentprocessor.h
+++ b/src/plugins/cpptools/baseeditordocumentprocessor.h
@@ -41,6 +41,8 @@
#include <QTextEdit>
+#include <QVariant>
+
#include <functional>
namespace TextEditor {
@@ -57,6 +59,7 @@ struct CPPTOOLS_EXPORT ToolTipInfo {
QStringList qDocIdCandidates;
QString qDocMark;
Core::HelpItem::Category qDocCategory;
+ QVariant value;
QString sizeInBytes;
};
diff --git a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp
index 36281674f7..a4ab626a8a 100644
--- a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp
+++ b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp
@@ -149,6 +149,28 @@ Utf8String sizeInBytes(const Cursor &cursor)
return Utf8String();
}
+QVariant value(const Cursor &cursor)
+{
+ if (!clang_isDeclaration(cursor.cx().kind) && !clang_isExpression(cursor.cx().kind))
+ return {};
+ const CXEvalResult evalResult = clang_Cursor_Evaluate(cursor.cx());
+ QVariant v;
+ switch (clang_EvalResult_getKind(evalResult)) {
+ case CXEval_Int:
+ v = clang_EvalResult_isUnsignedInt(evalResult)
+ ? QVariant::fromValue(clang_EvalResult_getAsUnsigned(evalResult))
+ : QVariant::fromValue(clang_EvalResult_getAsLongLong(evalResult));
+ break;
+ case CXEval_Float:
+ v = QVariant::fromValue(clang_EvalResult_getAsDouble(evalResult));
+ break;
+ default:
+ break;
+ }
+ clang_EvalResult_dispose(evalResult);
+ return v;
+}
+
Cursor referencedCursor(const Cursor &cursor)
{
// Query the referenced cursor directly instead of first testing with cursor.isReference().
@@ -503,6 +525,7 @@ ToolTipInfo ToolTipInfoCollector::collect(uint line, uint column) const
ToolTipInfo info;
info.text = text(cursor, referenced);
info.briefComment = referenced.briefComment();
+ info.value = value(cursor);
{
ToolTipInfo qDocToolTipInfo = qDocInfo(referenced);
diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp
index fb630e2aa3..26b6596cc5 100644
--- a/tests/unit/unittest/clangtooltipinfo-test.cpp
+++ b/tests/unit/unittest/clangtooltipinfo-test.cpp
@@ -385,6 +385,15 @@ TEST_F(ToolTipInfo, SizeForUnion)
ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("1"));
}
+TEST_F(ToolTipInfo, constexprValue)
+{
+ // CLANG-UPGRADE-CHECK: Adapt the values below
+ ASSERT_THAT(tooltip(204, 12).value.toInt(), 4);
+ ASSERT_THAT(tooltip(204, 27).value.toInt(), 4); // 3 in clang 11
+ ASSERT_THAT(tooltip(204, 30).value.toInt(), 4);
+ ASSERT_THAT(tooltip(204, 32).value.toInt(), 4); // 1 in clang 11
+}
+
TEST_F(ToolTipInfo, Namespace)
{
::ToolTipInfo expected(Utf8StringLiteral("X"));
diff --git a/tests/unit/unittest/data/tooltipinfo.cpp b/tests/unit/unittest/data/tooltipinfo.cpp
index bfad1fdd0f..6844a823cc 100644
--- a/tests/unit/unittest/data/tooltipinfo.cpp
+++ b/tests/unit/unittest/data/tooltipinfo.cpp
@@ -199,3 +199,6 @@ Nuu **pointers(Nuu **p1)
{
return p1;
}
+
+static constexpr int calcValue() { return 1 + 2; }
+const auto val = calcValue() + sizeof(char);