Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[sonar] Replace switch with numerous cases by a data structure (map or arrray).
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Thu, 17 Dec 2020 17:46:22 +0000 (18:46 +0100)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Thu, 17 Dec 2020 21:50:05 +0000 (22:50 +0100)
src/mc/inspect/mc_dwarf.cpp

index 83444e4..aeff911 100644 (file)
@@ -22,6 +22,7 @@
 #include <cstdlib>
 #include <fcntl.h>
 #include <memory>
+#include <unordered_map>
 #include <utility>
 
 #include <boost/range/algorithm.hpp>
@@ -124,52 +125,32 @@ enum class FormClass {
 
 static TagClass classify_tag(int tag)
 {
-  switch (tag) {
-    case DW_TAG_array_type:
-    case DW_TAG_class_type:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_typedef:
-    case DW_TAG_pointer_type:
-    case DW_TAG_reference_type:
-    case DW_TAG_rvalue_reference_type:
-    case DW_TAG_string_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_subroutine_type:
-    case DW_TAG_union_type:
-    case DW_TAG_ptr_to_member_type:
-    case DW_TAG_set_type:
-    case DW_TAG_subrange_type:
-    case DW_TAG_base_type:
-    case DW_TAG_const_type:
-    case DW_TAG_file_type:
-    case DW_TAG_packed_type:
-    case DW_TAG_volatile_type:
-    case DW_TAG_restrict_type:
-    case DW_TAG_interface_type:
-    case DW_TAG_unspecified_type:
-    case DW_TAG_shared_type:
-      return TagClass::Type;
-
-    case DW_TAG_subprogram:
-      return TagClass::Subprogram;
-
-    case DW_TAG_variable:
-    case DW_TAG_formal_parameter:
-      return TagClass::Variable;
-
-    case DW_TAG_lexical_block:
-    case DW_TAG_try_block:
-    case DW_TAG_catch_block:
-    case DW_TAG_inlined_subroutine:
-    case DW_TAG_with_stmt:
-      return TagClass::Scope;
-
-    case DW_TAG_namespace:
-      return TagClass::Namespace;
-
-    default:
-      return TagClass::Unknown;
-  }
+  static const std::unordered_map<int, TagClass> map = {
+      {DW_TAG_array_type, TagClass::Type},            {DW_TAG_class_type, TagClass::Type},
+      {DW_TAG_enumeration_type, TagClass::Type},      {DW_TAG_typedef, TagClass::Type},
+      {DW_TAG_pointer_type, TagClass::Type},          {DW_TAG_reference_type, TagClass::Type},
+      {DW_TAG_rvalue_reference_type, TagClass::Type}, {DW_TAG_string_type, TagClass::Type},
+      {DW_TAG_structure_type, TagClass::Type},        {DW_TAG_subroutine_type, TagClass::Type},
+      {DW_TAG_union_type, TagClass::Type},            {DW_TAG_ptr_to_member_type, TagClass::Type},
+      {DW_TAG_set_type, TagClass::Type},              {DW_TAG_subrange_type, TagClass::Type},
+      {DW_TAG_base_type, TagClass::Type},             {DW_TAG_const_type, TagClass::Type},
+      {DW_TAG_file_type, TagClass::Type},             {DW_TAG_packed_type, TagClass::Type},
+      {DW_TAG_volatile_type, TagClass::Type},         {DW_TAG_restrict_type, TagClass::Type},
+      {DW_TAG_interface_type, TagClass::Type},        {DW_TAG_unspecified_type, TagClass::Type},
+      {DW_TAG_shared_type, TagClass::Type},
+
+      {DW_TAG_subprogram, TagClass::Subprogram},
+
+      {DW_TAG_variable, TagClass::Variable},          {DW_TAG_formal_parameter, TagClass::Variable},
+
+      {DW_TAG_lexical_block, TagClass::Scope},        {DW_TAG_try_block, TagClass::Scope},
+      {DW_TAG_catch_block, TagClass::Scope},          {DW_TAG_inlined_subroutine, TagClass::Scope},
+      {DW_TAG_with_stmt, TagClass::Scope},
+
+      {DW_TAG_namespace, TagClass::Namespace}};
+
+  auto res = map.find(tag);
+  return res != map.end() ? res->second : TagClass::Unknown;
 }
 
 /** @brief Find the DWARF data class for a given DWARF data form
@@ -181,41 +162,32 @@ static TagClass classify_tag(int tag)
  * */
 static FormClass classify_form(int form)
 {
-  switch (form) {
-    case DW_FORM_addr:
-      return FormClass::Address;
-    case DW_FORM_block2:
-    case DW_FORM_block4:
-    case DW_FORM_block:
-    case DW_FORM_block1:
-      return FormClass::Block;
-    case DW_FORM_data1:
-    case DW_FORM_data2:
-    case DW_FORM_data4:
-    case DW_FORM_data8:
-    case DW_FORM_udata:
-    case DW_FORM_sdata:
-      return FormClass::Constant;
-    case DW_FORM_string:
-    case DW_FORM_strp:
-      return FormClass::String;
-    case DW_FORM_ref_addr:
-    case DW_FORM_ref1:
-    case DW_FORM_ref2:
-    case DW_FORM_ref4:
-    case DW_FORM_ref8:
-    case DW_FORM_ref_udata:
-      return FormClass::Reference;
-    case DW_FORM_flag:
-    case DW_FORM_flag_present:
-      return FormClass::Flag;
-    case DW_FORM_exprloc:
-      return FormClass::ExprLoc;
+  static const std::unordered_map<int, FormClass> map = {
+      {DW_FORM_addr, FormClass::Address},
+
+      {DW_FORM_block2, FormClass::Block},       {DW_FORM_block4, FormClass::Block},
+      {DW_FORM_block, FormClass::Block},        {DW_FORM_block1, FormClass::Block},
+
+      {DW_FORM_data1, FormClass::Constant},     {DW_FORM_data2, FormClass::Constant},
+      {DW_FORM_data4, FormClass::Constant},     {DW_FORM_data8, FormClass::Constant},
+      {DW_FORM_udata, FormClass::Constant},     {DW_FORM_sdata, FormClass::Constant},
+
+      {DW_FORM_string, FormClass::String},      {DW_FORM_strp, FormClass::String},
+
+      {DW_FORM_ref_addr, FormClass::Reference}, {DW_FORM_ref1, FormClass::Reference},
+      {DW_FORM_ref2, FormClass::Reference},     {DW_FORM_ref4, FormClass::Reference},
+      {DW_FORM_ref8, FormClass::Reference},     {DW_FORM_ref_udata, FormClass::Reference},
+
+      {DW_FORM_flag, FormClass::Flag},          {DW_FORM_flag_present, FormClass::Flag},
+
+      {DW_FORM_exprloc, FormClass::ExprLoc}
+
       // TODO sec offset
       // TODO indirect
-    default:
-      return FormClass::Unknown;
-  }
+  };
+
+  auto res = map.find(form);
+  return res != map.end() ? res->second : FormClass::Unknown;
 }
 
 /** @brief Get the name of the tag of a given DIE
@@ -323,33 +295,18 @@ static bool MC_dwarf_attr_flag(Dwarf_Die* die, int attribute, bool integrate)
  * */
 static uint64_t MC_dwarf_default_lower_bound(int lang)
 {
-  switch (lang) {
-    case DW_LANG_C:
-    case DW_LANG_C89:
-    case DW_LANG_C99:
-    case DW_LANG_C_plus_plus:
-    case DW_LANG_D:
-    case DW_LANG_Java:
-    case DW_LANG_ObjC:
-    case DW_LANG_ObjC_plus_plus:
-    case DW_LANG_Python:
-    case DW_LANG_UPC:
-      return 0;
-    case DW_LANG_Ada83:
-    case DW_LANG_Ada95:
-    case DW_LANG_Fortran77:
-    case DW_LANG_Fortran90:
-    case DW_LANG_Fortran95:
-    case DW_LANG_Modula2:
-    case DW_LANG_Pascal83:
-    case DW_LANG_PL1:
-    case DW_LANG_Cobol74:
-    case DW_LANG_Cobol85:
-      return 1;
-    default:
-      xbt_die("No default DW_TAG_lower_bound for language %i and none given", lang);
-      return 0;
-  }
+  const std::unordered_map<int, unsigned> map = {
+      {DW_LANG_C, 0},         {DW_LANG_C89, 0},     {DW_LANG_C99, 0},       {DW_LANG_C_plus_plus, 0},
+      {DW_LANG_D, 0},         {DW_LANG_Java, 0},    {DW_LANG_ObjC, 0},      {DW_LANG_ObjC_plus_plus, 0},
+      {DW_LANG_Python, 0},    {DW_LANG_UPC, 0},
+
+      {DW_LANG_Ada83, 1},     {DW_LANG_Ada95, 1},   {DW_LANG_Fortran77, 1}, {DW_LANG_Fortran90, 1},
+      {DW_LANG_Fortran95, 1}, {DW_LANG_Modula2, 1}, {DW_LANG_Pascal83, 1},  {DW_LANG_PL1, 1},
+      {DW_LANG_Cobol74, 1},   {DW_LANG_Cobol85, 1}};
+
+  auto res = map.find(lang);
+  xbt_assert(res != map.end(), "No default DW_TAG_lower_bound for language %i and none given", lang);
+  return res->second;
 }
 
 /** @brief Finds the number of elements in a DW_TAG_subrange_type or DW_TAG_enumeration_type DIE
@@ -1249,58 +1206,14 @@ int dwarf_register_to_libunwind(int dwarf_register)
 #elif defined(__i386__)
   // Couldn't find the authoritative source of information for this.
   // This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517.
-  switch (dwarf_register) {
-    case 0:
-      return UNW_X86_EAX;
-    case 1:
-      return UNW_X86_ECX;
-    case 2:
-      return UNW_X86_EDX;
-    case 3:
-      return UNW_X86_EBX;
-    case 4:
-      return UNW_X86_ESP;
-    case 5:
-      return UNW_X86_EBP;
-    case 6:
-      return UNW_X86_ESI;
-    case 7:
-      return UNW_X86_EDI;
-    case 8:
-      return UNW_X86_EIP;
-    case 9:
-      return UNW_X86_EFLAGS;
-    case 10:
-      return UNW_X86_CS;
-    case 11:
-      return UNW_X86_SS;
-    case 12:
-      return UNW_X86_DS;
-    case 13:
-      return UNW_X86_ES;
-    case 14:
-      return UNW_X86_FS;
-    case 15:
-      return UNW_X86_GS;
-    case 16:
-      return UNW_X86_ST0;
-    case 17:
-      return UNW_X86_ST1;
-    case 18:
-      return UNW_X86_ST2;
-    case 19:
-      return UNW_X86_ST3;
-    case 20:
-      return UNW_X86_ST4;
-    case 21:
-      return UNW_X86_ST5;
-    case 22:
-      return UNW_X86_ST6;
-    case 23:
-      return UNW_X86_ST7;
-    default:
-      xbt_die("Bad/unknown register number.");
-  }
+  constexpr std::array<int, 24> regs{
+      {/*  0 */ UNW_X86_EAX, /*  1 */ UNW_X86_ECX,    /*  2 */ UNW_X86_EDX, /*  3 */ UNW_X86_EBX,
+       /*  4 */ UNW_X86_ESP, /*  5 */ UNW_X86_EBP,    /*  6 */ UNW_X86_ESI, /*  7 */ UNW_X86_EDI,
+       /*  8 */ UNW_X86_EIP, /*  9 */ UNW_X86_EFLAGS, /* 10 */ UNW_X86_CS,  /* 11 */ UNW_X86_SS,
+       /* 12 */ UNW_X86_DS,  /* 13 */ UNW_X86_ES,     /* 14 */ UNW_X86_FS,  /* 15 */ UNW_X86_GS,
+       /* 16 */ UNW_X86_ST0, /* 17 */ UNW_X86_ST1,    /* 18 */ UNW_X86_ST2, /* 19 */ UNW_X86_ST3,
+       /* 20 */ UNW_X86_ST4, /* 21 */ UNW_X86_ST5,    /* 22 */ UNW_X86_ST6, /* 23 */ UNW_X86_ST7}};
+  return regs.at(dwarf_register);
 #else
 #error This architecture is not supported yet for DWARF expression evaluation.
 #endif