summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp')
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp55
1 files changed, 48 insertions, 7 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index 2fc690e3d5b..0bc664c93f8 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -8,6 +8,9 @@
#include "ClangExpressionSourceCode.h"
+#include "clang/Basic/CharInfo.h"
+#include "llvm/ADT/StringRef.h"
+
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Symbol/Block.h"
@@ -161,8 +164,43 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit,
}
}
+/// Checks if the expression body contains the given variable as a token.
+/// \param body The expression body.
+/// \param var The variable token we are looking for.
+/// \return True iff the expression body containes the variable as a token.
+static bool ExprBodyContainsVar(llvm::StringRef body, llvm::StringRef var) {
+ assert(var.find_if([](char c) { return !clang::isIdentifierBody(c); }) ==
+ llvm::StringRef::npos &&
+ "variable contains non-identifier chars?");
+
+ size_t start = 0;
+ // Iterate over all occurences of the variable string in our expression.
+ while ((start = body.find(var, start)) != llvm::StringRef::npos) {
+ // We found our variable name in the expression. Check that the token
+ // that contains our needle is equal to our variable and not just contains
+ // the character sequence by accident.
+ // Prevents situations where we for example inlcude the variable 'FOO' in an
+ // expression like 'FOObar + 1'.
+ bool has_characters_before =
+ start != 0 && clang::isIdentifierBody(body[start - 1]);
+ bool has_characters_after =
+ start + var.size() < body.size() &&
+ clang::isIdentifierBody(body[start + var.size()]);
+
+ // Our token just contained the variable name as a substring. Continue
+ // searching the rest of the expression.
+ if (has_characters_before || has_characters_after) {
+ ++start;
+ continue;
+ }
+ return true;
+ }
+ return false;
+}
+
static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
- StreamString &stream) {
+ StreamString &stream,
+ const std::string &expr) {
for (size_t i = 0; i < var_list_sp->GetSize(); i++) {
lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i);
@@ -170,15 +208,17 @@ static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp,
if (!var_name || var_name == "this" || var_name == ".block_descriptor")
continue;
+ if (!expr.empty() && !ExprBodyContainsVar(expr, var_name.GetStringRef()))
+ continue;
+
stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
}
}
-bool ClangExpressionSourceCode::GetText(std::string &text,
- lldb::LanguageType wrapping_language,
- bool static_method,
- ExecutionContext &exe_ctx, bool add_locals,
- llvm::ArrayRef<std::string> modules) const {
+bool ClangExpressionSourceCode::GetText(
+ std::string &text, lldb::LanguageType wrapping_language, bool static_method,
+ ExecutionContext &exe_ctx, bool add_locals, bool force_add_all_locals,
+ llvm::ArrayRef<std::string> modules) const {
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
@@ -256,7 +296,8 @@ bool ClangExpressionSourceCode::GetText(std::string &text,
if (target->GetInjectLocalVariables(&exe_ctx)) {
lldb::VariableListSP var_list_sp =
frame->GetInScopeVariableList(false, true);
- AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
+ AddLocalVariableDecls(var_list_sp, lldb_local_var_decls,
+ force_add_all_locals ? "" : m_body);
}
}
}
OpenPOWER on IntegriCloud