teemperor created this revision.
teemperor added reviewers: jingham, JDevlieghere.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

It's possible to have a dollar character in an identifier with Clang. We use 
that in LLDB to
namespace our own variables, but apparently this trick breaks our variable 
filter we use to
only load used variables. This patch adds dollar to the list of allowed 
characters we can have
in a variable. Also moves this check to its own function to make things more 
readable and
to fix the compiler warning that we implicitly convert char to unsigned char.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D64194

Files:
  
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/Makefile
  
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/TestDollarInVariable.py
  
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/main.c
  lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp


Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -164,12 +164,19 @@
   }
 }
 
+/// Returns true iff the character is part of an identifier according to LLDB.
+static bool IsLLDBIdentifier(char c) {
+  // We allow all characters Clang allows by default and '$' in identifiers.
+  return clang::isIdentifierBody(static_cast<unsigned char>(c),
+                                 /*allow dollar character*/ true);
+}
+
 /// 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); }) ==
+  assert(var.find_if([](char c) { return !IsLLDBIdentifier(c); }) ==
              llvm::StringRef::npos &&
          "variable contains non-identifier chars?");
 
@@ -182,10 +189,9 @@
     // 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()]);
+        start != 0 && IsLLDBIdentifier(body[start - 1]);
+    bool has_characters_after = start + var.size() < body.size() &&
+                                IsLLDBIdentifier(body[start + var.size()]);
 
     // Our token just contained the variable name as a substring. Continue
     // searching the rest of the expression.
Index: 
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/main.c
===================================================================
--- /dev/null
+++ 
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/main.c
@@ -0,0 +1,6 @@
+// Make sure we correctly handle $ in variable names.
+
+int main() {
+  int $foo = 42;
+  return 0; //%self.expect("expr $foo", substrs=['(int) $0 = 42'])
+}
Index: 
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/TestDollarInVariable.py
===================================================================
--- /dev/null
+++ 
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/TestDollarInVariable.py
@@ -0,0 +1,5 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), None)
+
Index: 
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/Makefile
===================================================================
--- /dev/null
+++ 
lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../make
+C_SOURCES := main.c
+include $(LEVEL)/Makefile.rules


Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -164,12 +164,19 @@
   }
 }
 
+/// Returns true iff the character is part of an identifier according to LLDB.
+static bool IsLLDBIdentifier(char c) {
+  // We allow all characters Clang allows by default and '$' in identifiers.
+  return clang::isIdentifierBody(static_cast<unsigned char>(c),
+                                 /*allow dollar character*/ true);
+}
+
 /// 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); }) ==
+  assert(var.find_if([](char c) { return !IsLLDBIdentifier(c); }) ==
              llvm::StringRef::npos &&
          "variable contains non-identifier chars?");
 
@@ -182,10 +189,9 @@
     // 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()]);
+        start != 0 && IsLLDBIdentifier(body[start - 1]);
+    bool has_characters_after = start + var.size() < body.size() &&
+                                IsLLDBIdentifier(body[start + var.size()]);
 
     // Our token just contained the variable name as a substring. Continue
     // searching the rest of the expression.
Index: lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/main.c
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/main.c
@@ -0,0 +1,6 @@
+// Make sure we correctly handle $ in variable names.
+
+int main() {
+  int $foo = 42;
+  return 0; //%self.expect("expr $foo", substrs=['(int) $0 = 42'])
+}
Index: lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/TestDollarInVariable.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/TestDollarInVariable.py
@@ -0,0 +1,5 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), None)
+
Index: lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/expression_command/dollar-in-variable/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../make
+C_SOURCES := main.c
+include $(LEVEL)/Makefile.rules
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to