@@ -613,50 +613,53 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
613613}
614614
615615void DWARFFormValue::dumpString (raw_ostream &OS) const {
616- Optional<const char *> DbgStr = getAsCString ();
617- if (DbgStr.hasValue ()) {
616+ if (auto DbgStr = dwarf::toString (*this )) {
618617 auto COS = WithColor (OS, HighlightColor::String);
619618 COS.get () << ' "' ;
620- COS.get ().write_escaped (DbgStr. getValue () );
619+ COS.get ().write_escaped (* DbgStr);
621620 COS.get () << ' "' ;
622621 }
623622}
624623
625- Optional <const char *> DWARFFormValue::getAsCString () const {
624+ Expected <const char *> DWARFFormValue::getAsCString () const {
626625 if (!isFormClass (FC_String))
627- return None;
626+ return make_error<StringError>(" Invalid form for string attribute" ,
627+ inconvertibleErrorCode ());
628628 if (Form == DW_FORM_string)
629629 return Value.cstr ;
630630 // FIXME: Add support for DW_FORM_GNU_strp_alt
631631 if (Form == DW_FORM_GNU_strp_alt || C == nullptr )
632- return None;
632+ return make_error<StringError>(" Unsupported form for string attribute" ,
633+ inconvertibleErrorCode ());
633634 uint64_t Offset = Value.uval ;
634- if (Form == DW_FORM_line_strp) {
635- // .debug_line_str is tracked in the Context.
636- if (const char *Str = C->getLineStringExtractor ().getCStr (&Offset))
637- return Str;
638- return None;
639- }
635+ Optional<uint32_t > Index;
640636 if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
641637 Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
642638 Form == DW_FORM_strx4) {
643639 if (!U)
644- return None;
645- Optional<uint64_t > StrOffset = U->getStringOffsetSectionItem (Offset);
640+ return make_error<StringError>(" API limitation - string extraction not "
641+ " available without a DWARFUnit" ,
642+ inconvertibleErrorCode ());
643+ Expected<uint64_t > StrOffset = U->getStringOffsetSectionItem (Offset);
644+ Index = Offset;
646645 if (!StrOffset)
647- return None ;
646+ return StrOffset. takeError () ;
648647 Offset = *StrOffset;
649648 }
650649 // Prefer the Unit's string extractor, because for .dwo it will point to
651650 // .debug_str.dwo, while the Context's extractor always uses .debug_str.
652- if (U) {
653- if (const char *Str = U->getStringExtractor ().getCStr (&Offset))
654- return Str;
655- return None;
656- }
657- if (const char *Str = C->getStringExtractor ().getCStr (&Offset))
651+ DataExtractor StrData = Form == DW_FORM_line_strp
652+ ? C->getLineStringExtractor ()
653+ : U ? U->getStringExtractor ()
654+ : C->getStringExtractor ();
655+ if (const char *Str = StrData.getCStr (&Offset))
658656 return Str;
659- return None;
657+ std::string Msg = FormEncodingString (Form).str ();
658+ if (Index)
659+ Msg += (" uses index " + Twine (*Index) + " , but the referenced string" ).str ();
660+ Msg += (" offset " + Twine (Offset) + " is beyond .debug_str bounds" ).str ();
661+ return make_error<StringError>(Msg,
662+ inconvertibleErrorCode ());
660663}
661664
662665Optional<uint64_t > DWARFFormValue::getAsAddress () const {
0 commit comments