[lldb][FormatEntity][NFC] Move function argument parsing code into separate functions
authorMichael Buch <michaelbuch12@gmail.com>
Wed, 26 Oct 2022 16:13:00 +0000 (17:13 +0100)
committerMichael Buch <michaelbuch12@gmail.com>
Mon, 31 Oct 2022 12:25:18 +0000 (12:25 +0000)
Hopefully makes the code more readable and allows
us to re-use argument pretty-printing code from
the `CPlusPlusLanguage` plugin in a follow-up commit.

Differential Revision: https://reviews.llvm.org/D136934

lldb/include/lldb/Core/FormatEntity.h
lldb/source/Core/FormatEntity.cpp

index cd9019d..a4972be 100644 (file)
@@ -241,6 +241,17 @@ public:
                              llvm::StringRef elements,
                              llvm::StringRef element_format);
 
+  /// For each variable in 'args' this function writes the variable
+  /// name and it's pretty-printed value representation to 'out_stream'
+  /// in following format:
+  ///
+  /// \verbatim
+  /// name_1=repr_1, name_2=repr_2 ...
+  /// \endverbatim
+  static void PrettyPrintFunctionArguments(Stream &out_stream,
+                                           VariableList const &args,
+                                           ExecutionContextScope *exe_scope);
+
 protected:
   static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
                               uint32_t depth);
index 3b0b569..c5cad95 100644 (file)
@@ -1039,6 +1039,71 @@ static inline bool IsToken(const char *var_name_begin, const char *var) {
   return (::strncmp(var_name_begin, var, strlen(var)) == 0);
 }
 
+/// Parses the basename out of a demangled function name
+/// that may include function arguments. Supports
+/// template functions.
+///
+/// Returns pointers to the opening and closing parenthesis of
+/// `full_name`. Can return nullptr for either parenthesis if
+/// none is exists.
+static std::pair<char const *, char const *>
+ParseBaseName(char const *full_name) {
+  const char *open_paren = strchr(full_name, '(');
+  const char *close_paren = nullptr;
+  const char *generic = strchr(full_name, '<');
+  // if before the arguments list begins there is a template sign
+  // then scan to the end of the generic args before you try to find
+  // the arguments list
+  if (generic && open_paren && generic < open_paren) {
+    int generic_depth = 1;
+    ++generic;
+    for (; *generic && generic_depth > 0; generic++) {
+      if (*generic == '<')
+        generic_depth++;
+      if (*generic == '>')
+        generic_depth--;
+    }
+    if (*generic)
+      open_paren = strchr(generic, '(');
+    else
+      open_paren = nullptr;
+  }
+
+  if (open_paren) {
+    if (IsToken(open_paren, "(anonymous namespace)")) {
+      open_paren = strchr(open_paren + strlen("(anonymous namespace)"), '(');
+      if (open_paren)
+        close_paren = strchr(open_paren, ')');
+    } else
+      close_paren = strchr(open_paren, ')');
+  }
+
+  return {open_paren, close_paren};
+}
+
+/// Writes out the function name in 'full_name' to 'out_stream'
+/// but replaces each argument type with the variable name
+/// and the corresponding pretty-printed value
+static void PrettyPrintFunctionNameWithArgs(Stream &out_stream,
+                                            char const *full_name,
+                                            ExecutionContextScope *exe_scope,
+                                            VariableList const &args) {
+  auto [open_paren, close_paren] = ParseBaseName(full_name);
+  if (open_paren)
+    out_stream.Write(full_name, open_paren - full_name + 1);
+  else {
+    out_stream.PutCString(full_name);
+    out_stream.PutChar('(');
+  }
+
+  FormatEntity::PrettyPrintFunctionArguments(out_stream, args, exe_scope);
+
+  if (close_paren)
+    out_stream.PutCString(close_paren);
+  else
+    out_stream.PutChar(')');
+}
+
 bool FormatEntity::FormatStringRef(const llvm::StringRef &format_str, Stream &s,
                                    const SymbolContext *sc,
                                    const ExecutionContext *exe_ctx,
@@ -1645,100 +1710,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
             variable_list_sp->AppendVariablesWithScope(
                 eValueTypeVariableArgument, args);
           if (args.GetSize() > 0) {
-            const char *open_paren = strchr(cstr, '(');
-            const char *close_paren = nullptr;
-            const char *generic = strchr(cstr, '<');
-            // if before the arguments list begins there is a template sign
-            // then scan to the end of the generic args before you try to find
-            // the arguments list
-            if (generic && open_paren && generic < open_paren) {
-              int generic_depth = 1;
-              ++generic;
-              for (; *generic && generic_depth > 0; generic++) {
-                if (*generic == '<')
-                  generic_depth++;
-                if (*generic == '>')
-                  generic_depth--;
-              }
-              if (*generic)
-                open_paren = strchr(generic, '(');
-              else
-                open_paren = nullptr;
-            }
-            if (open_paren) {
-              if (IsToken(open_paren, "(anonymous namespace)")) {
-                open_paren =
-                    strchr(open_paren + strlen("(anonymous namespace)"), '(');
-                if (open_paren)
-                  close_paren = strchr(open_paren, ')');
-              } else
-                close_paren = strchr(open_paren, ')');
-            }
-
-            if (open_paren)
-              s.Write(cstr, open_paren - cstr + 1);
-            else {
-              s.PutCString(cstr);
-              s.PutChar('(');
-            }
-            const size_t num_args = args.GetSize();
-            for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
-              std::string buffer;
-
-              VariableSP var_sp(args.GetVariableAtIndex(arg_idx));
-              ValueObjectSP var_value_sp(
-                  ValueObjectVariable::Create(exe_scope, var_sp));
-              StreamString ss;
-              llvm::StringRef var_representation;
-              const char *var_name = var_value_sp->GetName().GetCString();
-              if (var_value_sp->GetCompilerType().IsValid()) {
-                if (exe_scope && exe_scope->CalculateTarget())
-                  var_value_sp =
-                      var_value_sp->GetQualifiedRepresentationIfAvailable(
-                          exe_scope->CalculateTarget()
-                              ->TargetProperties::GetPreferDynamicValue(),
-                          exe_scope->CalculateTarget()
-                              ->TargetProperties::GetEnableSyntheticValue());
-                if (var_value_sp->GetCompilerType().IsAggregateType() &&
-                    DataVisualization::ShouldPrintAsOneLiner(*var_value_sp)) {
-                  static StringSummaryFormat format(
-                      TypeSummaryImpl::Flags()
-                          .SetHideItemNames(false)
-                          .SetShowMembersOneLiner(true),
-                      "");
-                  format.FormatObject(var_value_sp.get(), buffer,
-                                      TypeSummaryOptions());
-                  var_representation = buffer;
-                } else
-                  var_value_sp->DumpPrintableRepresentation(
-                      ss,
-                      ValueObject::ValueObjectRepresentationStyle::
-                          eValueObjectRepresentationStyleSummary,
-                      eFormatDefault,
-                      ValueObject::PrintableRepresentationSpecialCases::eAllow,
-                      false);
-              }
-
-              if (!ss.GetString().empty())
-                var_representation = ss.GetString();
-              if (arg_idx > 0)
-                s.PutCString(", ");
-              if (var_value_sp->GetError().Success()) {
-                if (!var_representation.empty())
-                  s.Printf("%s=%s", var_name, var_representation.str().c_str());
-                else
-                  s.Printf("%s=%s at %s", var_name,
-                           var_value_sp->GetTypeName().GetCString(),
-                           var_value_sp->GetLocationAsCString());
-              } else
-                s.Printf("%s=<unavailable>", var_name);
-            }
-
-            if (close_paren)
-              s.PutCString(close_paren);
-            else
-              s.PutChar(')');
-
+            PrettyPrintFunctionNameWithArgs(s, cstr, exe_scope, args);
           } else {
             s.PutCString(cstr);
           }
@@ -2447,3 +2419,55 @@ void FormatEntity::AutoComplete(CompletionRequest &request) {
     request.AddCompletions(new_matches);
   }
 }
+
+void FormatEntity::PrettyPrintFunctionArguments(
+    Stream &out_stream, VariableList const &args,
+    ExecutionContextScope *exe_scope) {
+  const size_t num_args = args.GetSize();
+  for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
+    std::string buffer;
+
+    VariableSP var_sp(args.GetVariableAtIndex(arg_idx));
+    ValueObjectSP var_value_sp(ValueObjectVariable::Create(exe_scope, var_sp));
+    StreamString ss;
+    llvm::StringRef var_representation;
+    const char *var_name = var_value_sp->GetName().GetCString();
+    if (var_value_sp->GetCompilerType().IsValid()) {
+      if (exe_scope && exe_scope->CalculateTarget())
+        var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
+            exe_scope->CalculateTarget()
+                ->TargetProperties::GetPreferDynamicValue(),
+            exe_scope->CalculateTarget()
+                ->TargetProperties::GetEnableSyntheticValue());
+      if (var_value_sp->GetCompilerType().IsAggregateType() &&
+          DataVisualization::ShouldPrintAsOneLiner(*var_value_sp)) {
+        static StringSummaryFormat format(TypeSummaryImpl::Flags()
+                                              .SetHideItemNames(false)
+                                              .SetShowMembersOneLiner(true),
+                                          "");
+        format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
+        var_representation = buffer;
+      } else
+        var_value_sp->DumpPrintableRepresentation(
+            ss,
+            ValueObject::ValueObjectRepresentationStyle::
+                eValueObjectRepresentationStyleSummary,
+            eFormatDefault,
+            ValueObject::PrintableRepresentationSpecialCases::eAllow, false);
+    }
+
+    if (!ss.GetString().empty())
+      var_representation = ss.GetString();
+    if (arg_idx > 0)
+      out_stream.PutCString(", ");
+    if (var_value_sp->GetError().Success()) {
+      if (!var_representation.empty())
+        out_stream.Printf("%s=%s", var_name, var_representation.str().c_str());
+      else
+        out_stream.Printf("%s=%s at %s", var_name,
+                          var_value_sp->GetTypeName().GetCString(),
+                          var_value_sp->GetLocationAsCString());
+    } else
+      out_stream.Printf("%s=<unavailable>", var_name);
+  }
+}