diff options
3 files changed, 108 insertions, 24 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 1d0814c7940..42f551da2f4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -43,7 +43,10 @@ DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) :      m_length        (0),      m_version       (0),      m_addr_size     (DWARFCompileUnit::GetDefaultAddressSize()), -    m_producer      (eProducerInvalid) +    m_producer      (eProducerInvalid), +    m_producer_version_major (0), +    m_producer_version_minor (0), +    m_producer_version_update (0)  {  } @@ -883,9 +886,22 @@ DWARFCompileUnit::Index (const uint32_t cu_idx,  }  bool +DWARFCompileUnit::Supports_unnamed_objc_bitfields () +{ +    if (GetProducer() == eProducerClang) +    { +        if (GetProducerVersionMajor() >= 425 && GetProducerVersionUpdate() >= 13) +            return true; +        else +            return false; +    } +    return true; // Assume all other compilers didn't have incorrect ObjC bitfield info +} + +bool  DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type ()  { -    if (GetProducer() == eProcucerLLVMGCC) +    if (GetProducer() == eProducerLLVMGCC)          return false;      return true;  } @@ -895,34 +911,81 @@ DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid()  {      // llvm-gcc makes completely invalid decl file attributes and won't ever      // be fixed, so we need to know to ignore these. -    return GetProducer() == eProcucerLLVMGCC; +    return GetProducer() == eProducerLLVMGCC;  } -DWARFCompileUnit::Producer -DWARFCompileUnit::GetProducer () +void +DWARFCompileUnit::ParseProducerInfo ()  { -    if (m_producer == eProducerInvalid) +    m_producer_version_major = UINT32_MAX; +    m_producer_version_minor = UINT32_MAX; +    m_producer_version_update = UINT32_MAX; + +    const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); +    if (die)      { -        const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); -        if (die) + +        const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); +        if (producer_cstr)          { -            const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL); -            if (producer_cstr) +            RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); +            if (llvm_gcc_regex.Execute (producer_cstr))              { -                RegularExpression g_llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$"); -                if (g_llvm_gcc_regex.Execute (producer_cstr)) -                    m_producer = eProcucerLLVMGCC; -                else if (strstr(producer_cstr, "clang")) -                    m_producer = eProducerClang; -                else if (strstr(producer_cstr, "GNU")) -                    m_producer = eProducerGCC; +                m_producer = eProducerLLVMGCC;              } +            else if (strstr(producer_cstr, "clang")) +            { +                RegularExpression clang_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)"); +                if (clang_regex.Execute (producer_cstr, 3)) +                { +                    std::string str; +                    if (clang_regex.GetMatchAtIndex (producer_cstr, 1, str)) +                        m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10); +                    if (clang_regex.GetMatchAtIndex (producer_cstr, 2, str)) +                        m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10); +                    if (clang_regex.GetMatchAtIndex (producer_cstr, 3, str)) +                        m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10); +                } +                m_producer = eProducerClang; +            } +            else if (strstr(producer_cstr, "GNU")) +                m_producer = eProducerGCC;          } -        if (m_producer == eProducerInvalid) -            m_producer = eProcucerOther;      } +    if (m_producer == eProducerInvalid) +        m_producer = eProcucerOther; +} + +DWARFCompileUnit::Producer +DWARFCompileUnit::GetProducer () +{ +    if (m_producer == eProducerInvalid) +        ParseProducerInfo ();      return m_producer;  } +uint32_t +DWARFCompileUnit::GetProducerVersionMajor() +{ +    if (m_producer_version_major == 0) +        ParseProducerInfo (); +    return m_producer_version_major; +} + +uint32_t +DWARFCompileUnit::GetProducerVersionMinor() +{ +    if (m_producer_version_minor == 0) +        ParseProducerInfo (); +    return m_producer_version_minor; +} + +uint32_t +DWARFCompileUnit::GetProducerVersionUpdate() +{ +    if (m_producer_version_update == 0) +        ParseProducerInfo (); +    return m_producer_version_update; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 28591a93ffd..c400497f0b2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -23,7 +23,7 @@ public:          eProducerInvalid = 0,          eProducerClang,          eProducerGCC, -        eProcucerLLVMGCC, +        eProducerLLVMGCC,          eProcucerOther      }; @@ -144,6 +144,9 @@ public:      bool      DW_AT_decl_file_attributes_are_invalid(); +    bool +    Supports_unnamed_objc_bitfields (); +  //    void  //    AddGlobalDIEByIndex (uint32_t die_idx);  // @@ -173,6 +176,14 @@ public:      Producer      GetProducer (); +    uint32_t +    GetProducerVersionMajor(); + +    uint32_t +    GetProducerVersionMinor(); +     +    uint32_t +    GetProducerVersionUpdate();  protected:      SymbolFileDWARF*    m_dwarf2Data; @@ -186,6 +197,12 @@ protected:      uint16_t            m_version;      uint8_t             m_addr_size;      Producer            m_producer; +    uint32_t            m_producer_version_major; +    uint32_t            m_producer_version_minor; +    uint32_t            m_producer_version_update; +     +    void +    ParseProducerInfo ();  private:      DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit);  }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 56ed3d1fee4..e70a225e448 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1768,11 +1768,15 @@ SymbolFileDWARF::ParseChildMembers                                  // Code to detect unnamed bitifields                                  if (bit_size > 0 && member_byte_offset != UINT32_MAX)                                  { -                                    // Objective C has invalid DW_AT_bit_offset values so we can't use them to detect -                                    // unnamed bitfields. Once clang is fixed we will enable unnamed bitfields -                                    // in ObjC classes (<rdar://problem/12636970>) +                                    // Objective C has invalid DW_AT_bit_offset values in older versions +                                    // of clang, so we have to be careful and only detect unnammed bitfields +                                    // if we have a new enough clang. +                                    bool detect_unnamed_bitfields = true; -                                    if (!(class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)) +                                    if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus) +                                        detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields (); +                                     +                                    if (detect_unnamed_bitfields)                                      {                                          // We have a bitfield, we need to watch out for                                          // unnamed bitfields that we need to insert if  | 

