alvinhochun updated this revision to Diff 438734.
alvinhochun added a comment.

Added test and improved setting description as suggested.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127234/new/

https://reviews.llvm.org/D127234

Files:
  lldb/include/lldb/Interpreter/OptionValueDictionary.h
  lldb/source/Interpreter/OptionValueDictionary.cpp
  lldb/source/Interpreter/Property.cpp
  lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
  lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td
  lldb/test/Shell/ObjectFile/PECOFF/settings-abi.yaml

Index: lldb/test/Shell/ObjectFile/PECOFF/settings-abi.yaml
===================================================================
--- lldb/test/Shell/ObjectFile/PECOFF/settings-abi.yaml
+++ lldb/test/Shell/ObjectFile/PECOFF/settings-abi.yaml
@@ -1,4 +1,8 @@
 # RUN: yaml2obj %s -o %t
+# RUN: yaml2obj %s -o %t.debug
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %s -o %t.dir/UPPER_CASE
+# RUN: yaml2obj %s -o %t.dir/UPPER_CASE.debug
 
 ## Default ABI is msvc:
 # RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
@@ -10,6 +14,57 @@
 # RUN:   -f %t -o "image list --triple --basename" -o exit | \
 # RUN:   FileCheck -DABI=gnu -DFILENAME=%basename_t.tmp %s
 
+## Default ABI is msvc, module override is gnu:
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi %basename_t.tmp=gnu" \
+# RUN:   -f %t -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=gnu -DFILENAME=%basename_t.tmp %s
+
+## Default ABI is gnu, module override is msvc:
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi gnu" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi %basename_t.tmp=msvc" \
+# RUN:   -f %t -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=msvc -DFILENAME=%basename_t.tmp %s
+
+## Default ABI is msvc, module override is gnu (with .debug suffix):
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi %basename_t.tmp=gnu" \
+# RUN:   -f %t.debug -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=gnu -DFILENAME=%basename_t.tmp.debug %s
+
+## Default ABI is gnu, module override is msvc (with .debug suffix):
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi gnu" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi %basename_t.tmp=msvc" \
+# RUN:   -f %t.debug -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=msvc -DFILENAME=%basename_t.tmp.debug %s
+
+## Check that case-sensitive match is chosen before lower-case:
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi upper_case=msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi UPPER_CASE=gnu" \
+# RUN:   -f %t.dir/UPPER_CASE -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=gnu -DFILENAME=UPPER_CASE %s
+
+## Check that lower-case match with .debug suffix is chosen before case-sensitive match without .debug suffix:
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi UPPER_CASE=msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi upper_case.debug=gnu" \
+# RUN:   -f %t.dir/UPPER_CASE.debug -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=gnu -DFILENAME=UPPER_CASE.debug %s
+
+## Check that case-sensitive match without .debug suffix is chosen before lower-case match without .debug suffix:
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi upper_case.debug=msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi UPPER_CASE.debug=gnu" \
+# RUN:   -f %t.dir/UPPER_CASE.debug -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=gnu -DFILENAME=UPPER_CASE.debug %s
+
+## Check that lower-case match without .debug suffix works:
+# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
+# RUN:   -O "settings append plugin.object-file.pe-coff.module-abi upper_case.debug=gnu" \
+# RUN:   -f %t.dir/UPPER_CASE.debug -o "image list --triple --basename" -o exit | \
+# RUN:   FileCheck -DABI=gnu -DFILENAME=UPPER_CASE.debug %s
+
 # CHECK-LABEL: image list --triple --basename
 # CHECK-NEXT: x86_64-pc-windows-[[ABI]] [[FILENAME]]
 
Index: lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td
===================================================================
--- lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td
+++ lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td
@@ -6,4 +6,9 @@
     DefaultEnumValue<"llvm::Triple::UnknownEnvironment">,
     EnumValues<"OptionEnumValues(g_abi_enums)">,
     Desc<"ABI to use when loading a PE/COFF module. This configures the C++ ABI used, which affects things like the handling of class layout. Accepted values are: `msvc` for the MSVC ABI, `gnu` for the MinGW / Itanium ABI, and `default` to follow the default target if it is a Windows triple or use the MSVC ABI by default.">;
+  def ModuleABIMap: Property<"module-abi", "Dictionary">,
+    Global,
+    ElementType<"Enum">,
+    EnumValues<"OptionEnumValues(g_abi_enums)">,
+    Desc<"A mapping of ABI override to use for specific modules. The module name is matched by its file name with extension. These versions are checked in sequence: exact, lowercase, exact with '.debug' suffix stripped, lowercase with '.debug' suffix stripped. Accepted values are: `msvc` for the MSVC ABI, `gnu` for the MinGW / Itanium ABI, and `default` to follow the default target if it is a Windows triple or use the MSVC ABI by default.">;
 }
Index: lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Process.h"
@@ -91,6 +92,11 @@
         m_collection_sp->GetPropertyAtIndexAsEnumeration(
             nullptr, ePropertyABI, llvm::Triple::UnknownEnvironment);
   }
+
+  OptionValueDictionary *ModuleABIMap() const {
+    return m_collection_sp->GetPropertyAtIndexAsOptionValueDictionary(
+        nullptr, ePropertyModuleABIMap);
+  }
 };
 
 static PluginProperties &GetGlobalPluginProperties() {
@@ -283,7 +289,41 @@
     return llvm::Triple::MSVC;
   }();
 
-  llvm::Triple::EnvironmentType env = GetGlobalPluginProperties().ABI();
+  // Check for a module-specific override.
+  OptionValueSP module_env_option;
+  const auto *map = GetGlobalPluginProperties().ModuleABIMap();
+  if (map->GetNumValues() > 0) {
+    // Step 1: Try with the exact file name.
+    auto name = file.GetLastPathComponent();
+    module_env_option = map->GetValueForKey(name);
+    if (!module_env_option) {
+      // Step 2: Try with the file name in lowercase.
+      auto name_lower = name.GetStringRef().lower();
+      module_env_option =
+          map->GetValueForKey(ConstString(llvm::StringRef(name_lower)));
+    }
+    if (!module_env_option) {
+      // Step 3: Try with the file name with ".debug" suffix stripped.
+      auto name_stripped = name.GetStringRef();
+      if (name_stripped.consume_back_insensitive(".debug")) {
+        module_env_option = map->GetValueForKey(ConstString(name_stripped));
+        if (!module_env_option) {
+          // Step 4: Try with the file name in lowercase with ".debug" suffix
+          // stripped.
+          auto name_lower = name_stripped.lower();
+          module_env_option =
+              map->GetValueForKey(ConstString(llvm::StringRef(name_lower)));
+        }
+      }
+    }
+  }
+  llvm::Triple::EnvironmentType env;
+  if (module_env_option)
+    env =
+        (llvm::Triple::EnvironmentType)module_env_option->GetEnumerationValue();
+  else
+    env = GetGlobalPluginProperties().ABI();
+
   if (env == llvm::Triple::UnknownEnvironment)
     env = default_env;
 
Index: lldb/source/Interpreter/Property.cpp
===================================================================
--- lldb/source/Interpreter/Property.cpp
+++ lldb/source/Interpreter/Property.cpp
@@ -68,9 +68,10 @@
   }
   case OptionValue::eTypeDictionary:
     // "definition.default_uint_value" is always a OptionValue::Type
-    m_value_sp =
-        std::make_shared<OptionValueDictionary>(OptionValue::ConvertTypeToMask(
-            (OptionValue::Type)definition.default_uint_value));
+    m_value_sp = std::make_shared<OptionValueDictionary>(
+        OptionValue::ConvertTypeToMask(
+            (OptionValue::Type)definition.default_uint_value),
+        definition.enum_values);
     break;
 
   case OptionValue::eTypeEnum:
Index: lldb/source/Interpreter/OptionValueDictionary.cpp
===================================================================
--- lldb/source/Interpreter/OptionValueDictionary.cpp
+++ lldb/source/Interpreter/OptionValueDictionary.cpp
@@ -8,11 +8,12 @@
 
 #include "lldb/Interpreter/OptionValueDictionary.h"
 
-#include "llvm/ADT/StringRef.h"
 #include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Interpreter/OptionValueEnumeration.h"
 #include "lldb/Interpreter/OptionValueString.h"
 #include "lldb/Utility/Args.h"
 #include "lldb/Utility/State.h"
+#include "llvm/ADT/StringRef.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -161,16 +162,26 @@
         return error;
       }
 
-      lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask(
-          value.str().c_str(), m_type_mask, error));
-      if (value_sp) {
+      if (m_type_mask == 1u << eTypeEnum) {
+        auto enum_value =
+            std::make_shared<OptionValueEnumeration>(m_enum_values, 0);
+        error = enum_value->SetValueFromString(value);
         if (error.Fail())
           return error;
         m_value_was_set = true;
-        SetValueForKey(ConstString(key), value_sp, true);
+        SetValueForKey(ConstString(key), enum_value, true);
       } else {
-        error.SetErrorString("dictionaries that can contain multiple types "
-                             "must subclass OptionValueArray");
+        lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask(
+            value.str().c_str(), m_type_mask, error));
+        if (value_sp) {
+          if (error.Fail())
+            return error;
+          m_value_was_set = true;
+          SetValueForKey(ConstString(key), value_sp, true);
+        } else {
+          error.SetErrorString("dictionaries that can contain multiple types "
+                               "must subclass OptionValueArray");
+        }
       }
     }
     break;
Index: lldb/include/lldb/Interpreter/OptionValueDictionary.h
===================================================================
--- lldb/include/lldb/Interpreter/OptionValueDictionary.h
+++ lldb/include/lldb/Interpreter/OptionValueDictionary.h
@@ -12,6 +12,7 @@
 #include <map>
 
 #include "lldb/Interpreter/OptionValue.h"
+#include "lldb/lldb-private-types.h"
 
 namespace lldb_private {
 
@@ -19,8 +20,10 @@
     : public Cloneable<OptionValueDictionary, OptionValue> {
 public:
   OptionValueDictionary(uint32_t type_mask = UINT32_MAX,
+                        OptionEnumValues enum_values = OptionEnumValues(),
                         bool raw_value_dump = true)
-      : m_type_mask(type_mask), m_raw_value_dump(raw_value_dump) {}
+      : m_type_mask(type_mask), m_enum_values(enum_values),
+        m_raw_value_dump(raw_value_dump) {}
 
   ~OptionValueDictionary() override = default;
 
@@ -75,6 +78,7 @@
 protected:
   typedef std::map<ConstString, lldb::OptionValueSP> collection;
   uint32_t m_type_mask;
+  OptionEnumValues m_enum_values;
   collection m_values;
   bool m_raw_value_dump;
 };
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to