Index: include/llvm/DebugInfo/DWARF/DWARFDie.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDie.h +++ include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -10,6 +10,7 @@ #ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H #define LLVM_LIB_DEBUGINFO_DWARFDIE_H +#include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" namespace llvm { @@ -132,8 +133,7 @@ /// \returns the NULL terminated C string value owned by the DWARF section /// that contains the string or FailValue if the attribute doesn't exist or /// if the attribute's form isn't a form that describes an string. - const char *getAttributeValueAsString(dwarf::Attribute Attr, - const char *FailValue) const; + Optional getAttributeValueAsString(dwarf::Attribute Attr) const; /// Extract the specified attribute from this DIE as an address. /// Index: lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDie.cpp +++ lib/DebugInfo/DWARF/DWARFDie.cpp @@ -143,13 +143,12 @@ return false; } -const char *DWARFDie::getAttributeValueAsString(dwarf::Attribute Attr, - const char *FailValue) const { +Optional +DWARFDie::getAttributeValueAsString(dwarf::Attribute Attr) const { DWARFFormValue FormValue; if (!getAttributeValue(Attr, FormValue)) - return FailValue; - Optional Result = FormValue.getAsCString(); - return Result.hasValue() ? Result.getValue() : FailValue; + return Optional(); + return FormValue.getAsCString(); } uint64_t DWARFDie::getAttributeValueAsAddress(dwarf::Attribute Attr, @@ -286,24 +285,24 @@ DWARFDie::getName(DINameKind Kind) const { if (!isValid() || Kind == DINameKind::None) return nullptr; - const char *name = nullptr; + Optional name; // Try to get mangled name only if it was asked for. if (Kind == DINameKind::LinkageName) { - if ((name = getAttributeValueAsString(DW_AT_MIPS_linkage_name, nullptr))) - return name; - if ((name = getAttributeValueAsString(DW_AT_linkage_name, nullptr))) - return name; + if ((name = getAttributeValueAsString(DW_AT_MIPS_linkage_name))) + return *name; + if ((name = getAttributeValueAsString(DW_AT_linkage_name))) + return *name; } - if ((name = getAttributeValueAsString(DW_AT_name, nullptr))) - return name; + if ((name = getAttributeValueAsString(DW_AT_name))) + return *name; // Try to get name from specification DIE. DWARFDie SpecDie = getAttributeValueAsReferencedDie(DW_AT_specification); if (SpecDie && (name = SpecDie.getName(Kind))) - return name; + return *name; // Try to get name from abstract origin DIE. DWARFDie AbsDie = getAttributeValueAsReferencedDie(DW_AT_abstract_origin); if (AbsDie && (name = AbsDie.getName(Kind))) - return name; + return *name; return nullptr; } Index: lib/DebugInfo/DWARF/DWARFUnit.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFUnit.cpp +++ lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -151,7 +151,13 @@ } const char *DWARFUnit::getCompilationDir() { - return getUnitDIE().getAttributeValueAsString(DW_AT_comp_dir, nullptr); + auto UnitDie = getUnitDIE(); + if (!UnitDie) + return nullptr; + auto CompDir = UnitDie.getAttributeValueAsString(DW_AT_comp_dir); + if (CompDir) + return *CompDir; + return nullptr; } uint64_t DWARFUnit::getDWOId() { @@ -293,17 +299,15 @@ DWARFDie UnitDie = getUnitDIE(); if (!UnitDie) return false; - const char *DWOFileName = - UnitDie.getAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); + auto DWOFileName = UnitDie.getAttributeValueAsString(DW_AT_GNU_dwo_name); if (!DWOFileName) return false; - const char *CompilationDir = - UnitDie.getAttributeValueAsString(DW_AT_comp_dir, nullptr); SmallString<16> AbsolutePath; - if (sys::path::is_relative(DWOFileName) && CompilationDir != nullptr) { - sys::path::append(AbsolutePath, CompilationDir); + if (sys::path::is_relative(*DWOFileName)) { + if (auto CompilationDir = UnitDie.getAttributeValueAsString(DW_AT_comp_dir)) + sys::path::append(AbsolutePath, *CompilationDir); } - sys::path::append(AbsolutePath, DWOFileName); + sys::path::append(AbsolutePath, *DWOFileName); DWO = llvm::make_unique(AbsolutePath); DWARFUnit *DWOCU = DWO->getUnit(); // Verify that compile unit in .dwo file is valid. Index: tools/dsymutil/DwarfLinker.cpp =================================================================== --- tools/dsymutil/DwarfLinker.cpp +++ tools/dsymutil/DwarfLinker.cpp @@ -1776,10 +1776,9 @@ // definitions match)." // // We treat non-C++ modules like namespaces for this reason. - if (DIE.getTag() == dwarf::DW_TAG_module && ParentIdx == 0 && - DIE.getAttributeValueAsString(dwarf::DW_AT_name, - "") != CU.getClangModuleName()) { - InImportedModule = true; + if (DIE.getTag() == dwarf::DW_TAG_module && ParentIdx == 0) { + if (auto Name = DIE.getAttributeValueAsString(dwarf::DW_AT_name)) + InImportedModule = *Name != CU.getClangModuleName(); } Info.ParentIdx = ParentIdx; @@ -3218,39 +3217,38 @@ bool DwarfLinker::registerModuleReference( const DWARFDie &CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap, unsigned Indent) { - std::string PCMfile = - CUDie.getAttributeValueAsString(dwarf::DW_AT_dwo_name, ""); - if (PCMfile.empty()) - PCMfile = - CUDie.getAttributeValueAsString(dwarf::DW_AT_GNU_dwo_name, ""); - if (PCMfile.empty()) + auto PCMfile = CUDie.getAttributeValueAsString(dwarf::DW_AT_dwo_name); + if (!PCMfile) + PCMfile = CUDie.getAttributeValueAsString(dwarf::DW_AT_GNU_dwo_name); + if (!PCMfile) return false; // Clang module DWARF skeleton CUs abuse this for the path to the module. - std::string PCMpath = - CUDie.getAttributeValueAsString(dwarf::DW_AT_comp_dir, ""); + std::string PCMpath; + if (auto CompDir = CUDie.getAttributeValueAsString(dwarf::DW_AT_comp_dir)) + PCMpath = *CompDir; + uint64_t DwoId = getDwoId(CUDie, Unit); - std::string Name = - CUDie.getAttributeValueAsString(dwarf::DW_AT_name, ""); - if (Name.empty()) { - reportWarning("Anonymous module skeleton CU for " + PCMfile); + auto Name = CUDie.getAttributeValueAsString(dwarf::DW_AT_name); + if (!Name) { + reportWarning(Twine("Anonymous module skeleton CU for ") + *PCMfile); return true; } if (Options.Verbose) { outs().indent(Indent); - outs() << "Found clang module reference " << PCMfile; + outs() << "Found clang module reference " << *PCMfile; } - auto Cached = ClangModules.find(PCMfile); + auto Cached = ClangModules.find(*PCMfile); if (Cached != ClangModules.end()) { // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is // fixed in clang, only warn about DWO_id mismatches in verbose mode. // ASTFileSignatures will change randomly when a module is rebuilt. if (Options.Verbose && (Cached->second != DwoId)) reportWarning(Twine("hash mismatch: this object file was built against a " - "different version of the module ") + PCMfile); + "different version of the module ") + *PCMfile); if (Options.Verbose) outs() << " [cached].\n"; return true; @@ -3260,8 +3258,8 @@ // Cyclic dependencies are disallowed by Clang, but we still // shouldn't run into an infinite loop, so mark it as processed now. - ClangModules.insert({PCMfile, DwoId}); - loadClangModule(PCMfile, PCMpath, Name, DwoId, ModuleMap, Indent + 2); + ClangModules.insert({*PCMfile, DwoId}); + loadClangModule(*PCMfile, PCMpath, *Name, DwoId, ModuleMap, Indent + 2); return true; } Index: unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp =================================================================== --- unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -278,15 +278,14 @@ //---------------------------------------------------------------------- // Test string forms //---------------------------------------------------------------------- - const char *ExtractedStringValue = - DieDG.getAttributeValueAsString(Attr_DW_FORM_string, nullptr); - EXPECT_TRUE(ExtractedStringValue != nullptr); - EXPECT_TRUE(strcmp(StringValue, ExtractedStringValue) == 0); + auto ExtractedStringValue = + DieDG.getAttributeValueAsString(Attr_DW_FORM_string); + EXPECT_TRUE((bool)ExtractedStringValue); + EXPECT_TRUE(strcmp(StringValue, *ExtractedStringValue) == 0); - const char *ExtractedStrpValue = - DieDG.getAttributeValueAsString(Attr_DW_FORM_strp, nullptr); - EXPECT_TRUE(ExtractedStrpValue != nullptr); - EXPECT_TRUE(strcmp(StrpValue, ExtractedStrpValue) == 0); + auto ExtractedStrpValue = DieDG.getAttributeValueAsString(Attr_DW_FORM_strp); + EXPECT_TRUE((bool)ExtractedStrpValue); + EXPECT_TRUE(strcmp(StrpValue, *ExtractedStrpValue) == 0); //---------------------------------------------------------------------- // Test reference forms