Add descriptions to completed expressions
Summary:
Completing inside the expression command now uses the new description API
to also provide additional information to the user. For now this information
are the types of variables/fields and the signatures of completed function calls.
Reviewers: #lldb, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: JDevlieghere, lldb-commits
Differential Revision: https://reviews.llvm.org/D52103
llvm-svn: 342385
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index b905b9a..ccdff21 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -14,6 +14,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
@@ -564,6 +565,9 @@
std::string m_expr;
unsigned m_position = 0;
CompletionRequest &m_request;
+ /// The printing policy we use when printing declarations for our completion
+ /// descriptions.
+ clang::PrintingPolicy m_desc_policy;
/// Returns true if the given character can be used in an identifier.
/// This also returns true for numbers because for completion we usually
@@ -638,10 +642,22 @@
/// @param[out] position
/// The character position of the user cursor in the `expr` parameter.
///
- CodeComplete(CompletionRequest &request, std::string expr, unsigned position)
+ CodeComplete(CompletionRequest &request, clang::LangOptions ops,
+ std::string expr, unsigned position)
: CodeCompleteConsumer(CodeCompleteOptions(), false),
m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
- m_position(position), m_request(request) {}
+ m_position(position), m_request(request), m_desc_policy(ops) {
+
+ // Ensure that the printing policy is producing a description that is as
+ // short as possible.
+ m_desc_policy.SuppressScope = true;
+ m_desc_policy.SuppressTagKeyword = true;
+ m_desc_policy.FullyQualifiedName = false;
+ m_desc_policy.TerseOutput = true;
+ m_desc_policy.IncludeNewlines = false;
+ m_desc_policy.UseVoidForZeroParams = false;
+ m_desc_policy.Bool = true;
+ }
/// Deregisters and destroys this code-completion consumer.
virtual ~CodeComplete() {}
@@ -692,6 +708,7 @@
CodeCompletionResult &R = Results[I];
std::string ToInsert;
+ std::string Description;
// Handle the different completion kinds that come from the Sema.
switch (R.Kind) {
case CodeCompletionResult::RK_Declaration: {
@@ -705,10 +722,16 @@
ToInsert += "()";
else
ToInsert += "(";
- }
- // If we try to complete a namespace, then we can directly append
- // the '::'.
- if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
+ raw_string_ostream OS(Description);
+ F->print(OS, m_desc_policy, false);
+ OS.flush();
+ } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
+ Description = V->getType().getAsString(m_desc_policy);
+ } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
+ Description = F->getType().getAsString(m_desc_policy);
+ } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
+ // If we try to complete a namespace, then we can directly append
+ // the '::'.
if (!N->isAnonymousNamespace())
ToInsert += "::";
}
@@ -735,7 +758,7 @@
// with the kind of result the lldb API expects.
std::string CompletionSuggestion =
mergeCompletion(m_expr, m_position, ToInsert);
- m_request.AddCompletion(CompletionSuggestion);
+ m_request.AddCompletion(CompletionSuggestion, Description);
}
}
}
@@ -773,7 +796,8 @@
// the LLVMUserExpression which exposes the right API. This should never fail
// as we always have a ClangUserExpression whenever we call this.
LLVMUserExpression &llvm_expr = *static_cast<LLVMUserExpression *>(&m_expr);
- CodeComplete CC(request, llvm_expr.GetUserText(), typed_pos);
+ CodeComplete CC(request, m_compiler->getLangOpts(), llvm_expr.GetUserText(),
+ typed_pos);
// We don't need a code generator for parsing.
m_code_generator.reset();
// Start parsing the expression with our custom code completion consumer.