diff options
author | Reid Kleckner <rnk@google.com> | 2016-05-05 00:34:33 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-05-05 00:34:33 +0000 |
commit | 4a14bcac416917ab45d58ab55049a4c25db16970 (patch) | |
tree | 00abeb1d48784dd3a8e18a2dc3f6f76a3009fbae /llvm/tools/llvm-readobj/COFFDumper.cpp | |
parent | 1ccc219125c16761c3e38f5e8d416386db3b11d4 (diff) | |
download | bcm5719-llvm-4a14bcac416917ab45d58ab55049a4c25db16970.tar.gz bcm5719-llvm-4a14bcac416917ab45d58ab55049a4c25db16970.zip |
[codeview] Move dumper into lib/DebugInfo/CodeView
So that we can call it from llvm-pdbdump.
llvm-svn: 268580
Diffstat (limited to 'llvm/tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 819 |
1 files changed, 8 insertions, 811 deletions
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 8e6d2276e0d..ebb52aa2acd 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -22,11 +22,10 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/TypeDumper.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeStream.h" @@ -54,65 +53,11 @@ using namespace llvm::Win64EH; namespace { -class CVTypeDumper : public CVTypeVisitor<CVTypeDumper> { -public: - CVTypeDumper(ScopedPrinter &W) : W(W) {} - - StringRef getTypeName(TypeIndex TI); - void printTypeIndex(StringRef FieldName, TypeIndex TI); - - void dump(ArrayRef<uint8_t> Data); - - /// CVTypeVisitor overrides. -#define TYPE_RECORD(ClassName, LeafEnum) \ - void visit##ClassName(TypeLeafKind LeafType, const ClassName *Record, \ - ArrayRef<uint8_t> LeafData); -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) -#define MEMBER_RECORD(ClassName, LeafEnum) \ - void visit##ClassName(TypeLeafKind LeafType, const ClassName *Record, \ - ArrayRef<uint8_t> &FieldData); -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" - - /// Method overload lists are a special case. - void visitMethodList(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData); - - void visitUnknownMember(TypeLeafKind Leaf); - - void visitTypeBegin(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData); - void visitTypeEnd(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData); - -private: - void printMemberAttributes(MemberAttributes Attrs); - - /// Reinterpret a byte array as an array of characters. Does not interpret as - /// a C string, as StringRef has several helpers (split) that make that easy. - static StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData) { - return StringRef(reinterpret_cast<const char *>(LeafData.data()), - LeafData.size()); - } - - static StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData) { - return getBytesAsCharacters(LeafData).split('\0').first; - } - - ScopedPrinter &W; - - /// Name of the current type. Only valid before visitTypeEnd. - StringRef Name; - - /// All user defined type records in .debug$T live in here. Type indices - /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to - /// index into this vector. - SmallVector<StringRef, 10> CVUDTNames; - - StringSet<> TypeNames; -}; - class COFFDumper : public ObjDumper { public: COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer) - : ObjDumper(Writer), Obj(Obj), CVTD(Writer) {} + : ObjDumper(Writer), Obj(Obj), + CVTD(Writer, opts::CodeViewSubsectionBytes) {} void printFileHeaders() override; void printSections() override; @@ -194,8 +139,7 @@ private: CVTypeDumper CVTD; }; -} // namespace - +} // end namespace namespace llvm { @@ -653,178 +597,6 @@ static const EnumEntry<uint16_t> FrameCookieKinds[] = { LLVM_READOBJ_ENUM_ENT(FrameCookieSym, XorR13), }; -static const EnumEntry<uint16_t> ClassOptionNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Packed), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Nested), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, ForwardReference), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Scoped), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasUniqueName), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Sealed), - LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Intrinsic), -}; - -static const EnumEntry<uint8_t> MemberAccessNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, None), - LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, Private), - LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, Protected), - LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, Public), -}; - -static const EnumEntry<uint16_t> MethodOptionNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, Pseudo), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, NoInherit), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, NoConstruct), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, Sealed), -}; - -static const EnumEntry<uint16_t> MemberKindNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Vanilla), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Virtual), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Static), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Friend), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, PureVirtual), - LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual), -}; - -/// The names here all end in "*". If the simple type is a pointer type, we -/// return the whole name. Otherwise we lop off the last character in our -/// StringRef. -static const EnumEntry<SimpleTypeKind> SimpleTypeNames[] = { - {"void*", SimpleTypeKind::Void}, - {"<not translated>*", SimpleTypeKind::NotTranslated}, - {"HRESULT*", SimpleTypeKind::HResult}, - {"signed char*", SimpleTypeKind::SignedCharacter}, - {"unsigned char*", SimpleTypeKind::UnsignedCharacter}, - {"char*", SimpleTypeKind::NarrowCharacter}, - {"wchar_t*", SimpleTypeKind::WideCharacter}, - {"char16_t*", SimpleTypeKind::Character16}, - {"char32_t*", SimpleTypeKind::Character32}, - {"__int8*", SimpleTypeKind::SByte}, - {"unsigned __int8*", SimpleTypeKind::Byte}, - {"short*", SimpleTypeKind::Int16Short}, - {"unsigned short*", SimpleTypeKind::UInt16Short}, - {"__int16*", SimpleTypeKind::Int16}, - {"unsigned __int16*", SimpleTypeKind::UInt16}, - {"long*", SimpleTypeKind::Int32Long}, - {"unsigned long*", SimpleTypeKind::UInt32Long}, - {"int*", SimpleTypeKind::Int32}, - {"unsigned*", SimpleTypeKind::UInt32}, - {"__int64*", SimpleTypeKind::Int64Quad}, - {"unsigned __int64*", SimpleTypeKind::UInt64Quad}, - {"__int64*", SimpleTypeKind::Int64}, - {"unsigned __int64*", SimpleTypeKind::UInt64}, - {"__int128*", SimpleTypeKind::Int128}, - {"unsigned __int128*", SimpleTypeKind::UInt128}, - {"__half*", SimpleTypeKind::Float16}, - {"float*", SimpleTypeKind::Float32}, - {"float*", SimpleTypeKind::Float32PartialPrecision}, - {"__float48*", SimpleTypeKind::Float48}, - {"double*", SimpleTypeKind::Float64}, - {"long double*", SimpleTypeKind::Float80}, - {"__float128*", SimpleTypeKind::Float128}, - {"_Complex float*", SimpleTypeKind::Complex32}, - {"_Complex double*", SimpleTypeKind::Complex64}, - {"_Complex long double*", SimpleTypeKind::Complex80}, - {"_Complex __float128*", SimpleTypeKind::Complex128}, - {"bool*", SimpleTypeKind::Boolean8}, - {"__bool16*", SimpleTypeKind::Boolean16}, - {"__bool32*", SimpleTypeKind::Boolean32}, - {"__bool64*", SimpleTypeKind::Boolean64}, -}; - -static const EnumEntry<TypeLeafKind> LeafTypeNames[] = { -#define LEAF_TYPE(name, val) LLVM_READOBJ_ENUM_ENT(TypeLeafKind, name), -#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" -}; - -static const EnumEntry<uint8_t> PtrKindNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Near16), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Far16), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Huge16), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSegment), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnValue), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnAddress), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnType), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSelf), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Near32), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Far32), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Near64), -}; - -static const EnumEntry<uint8_t> PtrModeNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, Pointer), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, LValueReference), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, PointerToDataMember), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, RValueReference), -}; - -static const EnumEntry<uint16_t> PtrMemberRepNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, - SingleInheritanceData), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, - MultipleInheritanceData), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, - VirtualInheritanceData), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, - SingleInheritanceFunction), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, - MultipleInheritanceFunction), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, - VirtualInheritanceFunction), - LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction), -}; - -static const EnumEntry<uint16_t> TypeModifierNames[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(ModifierOptions, Const), - LLVM_READOBJ_ENUM_CLASS_ENT(ModifierOptions, Volatile), - LLVM_READOBJ_ENUM_CLASS_ENT(ModifierOptions, Unaligned), -}; - -static const EnumEntry<uint8_t> CallingConventions[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearC), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarC), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearPascal), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarPascal), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearFast), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarFast), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearStdCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarStdCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearSysCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarSysCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, ThisCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, MipsCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, Generic), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, AlphaCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, PpcCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, SHCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, ArmCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, AM33Call), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, TriCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, SH5Call), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, M32RCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, ClrCall), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, Inline), - LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearVector), -}; - -static const EnumEntry<uint8_t> FunctionOptionEnum[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt), - LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, Constructor), - LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases), -}; - static const EnumEntry<uint8_t> FileChecksumKindNames[] = { LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, None), LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, MD5), @@ -1214,92 +986,6 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, } } -static std::error_code decodeNumerictLeaf(ArrayRef<uint8_t> &Data, - APSInt &Num) { - // Used to avoid overload ambiguity on APInt construtor. - bool FalseVal = false; - if (Data.size() < 2) - return object_error::parse_failed; - uint16_t Short = *reinterpret_cast<const ulittle16_t *>(Data.data()); - Data = Data.drop_front(2); - if (Short < LF_NUMERIC) { - Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false), - /*isUnsigned=*/true); - return std::error_code(); - } - switch (Short) { - case LF_CHAR: - Num = APSInt(APInt(/*numBits=*/8, - *reinterpret_cast<const int8_t *>(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(1); - return std::error_code(); - case LF_SHORT: - Num = APSInt(APInt(/*numBits=*/16, - *reinterpret_cast<const little16_t *>(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(2); - return std::error_code(); - case LF_USHORT: - Num = APSInt(APInt(/*numBits=*/16, - *reinterpret_cast<const ulittle16_t *>(Data.data()), - /*isSigned=*/false), - /*isUnsigned=*/true); - Data = Data.drop_front(2); - return std::error_code(); - case LF_LONG: - Num = APSInt(APInt(/*numBits=*/32, - *reinterpret_cast<const little32_t *>(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(4); - return std::error_code(); - case LF_ULONG: - Num = APSInt(APInt(/*numBits=*/32, - *reinterpret_cast<const ulittle32_t *>(Data.data()), - /*isSigned=*/FalseVal), - /*isUnsigned=*/true); - Data = Data.drop_front(4); - return std::error_code(); - case LF_QUADWORD: - Num = APSInt(APInt(/*numBits=*/64, - *reinterpret_cast<const little64_t *>(Data.data()), - /*isSigned=*/true), - /*isUnsigned=*/false); - Data = Data.drop_front(8); - return std::error_code(); - case LF_UQUADWORD: - Num = APSInt(APInt(/*numBits=*/64, - *reinterpret_cast<const ulittle64_t *>(Data.data()), - /*isSigned=*/false), - /*isUnsigned=*/true); - Data = Data.drop_front(8); - return std::error_code(); - } - return object_error::parse_failed; -} - -static std::error_code decodeNumerictLeaf(StringRef &Data, APSInt &Num) { - ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()), - Data.size()); - auto EC = decodeNumerictLeaf(Bytes, Num); - Data = StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size()); - return EC; -} - -/// Decode an unsigned integer numeric leaf value. -std::error_code decodeUIntLeaf(ArrayRef<uint8_t> &Data, uint64_t &Num) { - APSInt N; - if (std::error_code err = decodeNumerictLeaf(Data, N)) - return err; - if (N.isSigned() || !N.isIntN(64)) - return object_error::parse_failed; - Num = N.getLimitedValue(); - return std::error_code(); -} - void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, const SectionRef &Section, StringRef SectionContents) { @@ -1814,7 +1500,8 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, error(consumeObject(SymData, Constant)); printTypeIndex("Type", Constant->Type); APSInt Value; - error(decodeNumerictLeaf(SymData, Value)); + if (!decodeNumericLeaf(SymData, Value)) + error(object_error::parse_failed); W.printNumber("Value", Value); StringRef Name = SymData.split('\0').first; W.printString("Name", Name); @@ -1889,43 +1576,6 @@ void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { } } -StringRef CVTypeDumper::getTypeName(TypeIndex TI) { - if (TI.isNoType()) - return "<no type>"; - - if (TI.isSimple()) { - // This is a simple type. - for (const auto &SimpleTypeName : SimpleTypeNames) { - if (SimpleTypeName.Value == TI.getSimpleKind()) { - if (TI.getSimpleMode() == SimpleTypeMode::Direct) - return SimpleTypeName.Name.drop_back(1); - // Otherwise, this is a pointer type. We gloss over the distinction - // between near, far, 64, 32, etc, and just give a pointer type. - return SimpleTypeName.Name; - } - } - return "<unknown simple type>"; - } - - // User-defined type. - StringRef UDTName; - unsigned UDTIndex = TI.getIndex() - 0x1000; - if (UDTIndex < CVUDTNames.size()) - return CVUDTNames[UDTIndex]; - - return "<unknown UDT>"; -} - -void CVTypeDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) { - StringRef TypeName; - if (!TI.isNoType()) - TypeName = getTypeName(TI); - if (!TypeName.empty()) - W.printHex(FieldName, TypeName, TI.getIndex()); - else - W.printHex(FieldName, TI.getIndex()); -} - void COFFDumper::printLocalVariableAddrRange( const LocalVariableAddrRange &Range, const coff_section *Sec, StringRef SectionContents) { @@ -1970,17 +1620,6 @@ void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) { W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset); } -static StringRef getLeafTypeName(TypeLeafKind LT) { - switch (LT) { -#define KNOWN_TYPE(LeafName, Value, ClassName) \ - case LeafName: return #ClassName; -#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" - default: - break; - } - return "UnknownLeaf"; -} - void COFFDumper::printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section) { ListScope D(W, "CodeViewTypes"); @@ -1999,454 +1638,12 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName, ArrayRef<uint8_t> BinaryData(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()); - CVTD.dump(BinaryData); -} - -void CVTypeDumper::dump(ArrayRef<uint8_t> Data) { - visitTypeStream(Data); - if (hadError()) + if (!CVTD.dump(BinaryData)) { + W.flush(); error(object_error::parse_failed); -} - -void CVTypeDumper::visitTypeBegin(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData) { - // Reset Name to the empty string. If the visitor sets it, we know it. - Name = ""; - - W.startLine() << getLeafTypeName(Leaf) << " {\n"; - W.indent(); - unsigned NextTypeIndex = 0x1000 + CVUDTNames.size(); - W.printEnum("TypeLeafKind", unsigned(Leaf), makeArrayRef(LeafTypeNames)); - W.printHex("TypeIndex", NextTypeIndex); - W.flush(); -} - -void CVTypeDumper::visitTypeEnd(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData) { - // Always record some name for every type, even if Name is empty, since - // CVUDTNames is indexed by TypeIndex. - CVUDTNames.push_back(Name); - - if (opts::CodeViewSubsectionBytes) - W.printBinaryBlock("LeafData", getBytesAsCharacters(LeafData)); - - W.unindent(); - W.startLine() << "}\n"; - W.flush(); -} - -void CVTypeDumper::visitStringId(TypeLeafKind Leaf, const StringId *String, - ArrayRef<uint8_t> LeafData) { - W.printHex("Id", String->id.getIndex()); - StringRef StringData = getBytesAsCString(LeafData); - W.printString("StringData", StringData); - // Put this in CVUDTNames so it gets printed with LF_UDT_SRC_LINE. - Name = StringData; -} - -void CVTypeDumper::visitArgList(TypeLeafKind Leaf, const ArgList *Args, - ArrayRef<uint8_t> LeafData) { - W.printNumber("NumArgs", Args->NumArgs); - ListScope Arguments(W, "Arguments"); - SmallString<256> TypeName("("); - for (uint32_t ArgI = 0; ArgI != Args->NumArgs; ++ArgI) { - const TypeIndex *Type; - if (!consumeObject(LeafData, Type)) - return; - printTypeIndex("ArgType", *Type); - StringRef ArgTypeName = getTypeName(*Type); - TypeName.append(ArgTypeName); - if (ArgI + 1 != Args->NumArgs) - TypeName.append(", "); - } - TypeName.push_back(')'); - Name = TypeNames.insert(TypeName).first->getKey(); -} - -void CVTypeDumper::visitClassType(TypeLeafKind Leaf, const ClassType *Class, - ArrayRef<uint8_t> LeafData) { - W.printNumber("MemberCount", Class->MemberCount); - uint16_t Props = Class->Properties; - W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames)); - printTypeIndex("FieldList", Class->FieldList); - printTypeIndex("DerivedFrom", Class->DerivedFrom); - printTypeIndex("VShape", Class->VShape); - uint64_t SizeOf; - error(decodeUIntLeaf(LeafData, SizeOf)); - W.printNumber("SizeOf", SizeOf); - StringRef LeafChars = getBytesAsCharacters(LeafData); - StringRef LinkageName; - std::tie(Name, LinkageName) = LeafChars.split('\0'); - W.printString("Name", Name); - if (Props & uint16_t(ClassOptions::HasUniqueName)) { - LinkageName = LinkageName.split('\0').first; - if (LinkageName.empty()) - return error(object_error::parse_failed); - W.printString("LinkageName", LinkageName); - } -} - -void CVTypeDumper::visitUnionType(TypeLeafKind Leaf, const UnionType *Union, - ArrayRef<uint8_t> LeafData) { - W.printNumber("MemberCount", Union->MemberCount); - uint16_t Props = Union->Properties; - W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames)); - printTypeIndex("FieldList", Union->FieldList); - uint64_t SizeOf; - error(decodeUIntLeaf(LeafData, SizeOf)); - W.printNumber("SizeOf", SizeOf); - StringRef LeafChars = getBytesAsCharacters(LeafData); - StringRef LinkageName; - std::tie(Name, LinkageName) = LeafChars.split('\0'); - W.printString("Name", Name); - if (Props & uint16_t(ClassOptions::HasUniqueName)) { - LinkageName = LinkageName.split('\0').first; - if (LinkageName.empty()) - return error(object_error::parse_failed); - W.printString("LinkageName", LinkageName); } } -void CVTypeDumper::visitEnumType(TypeLeafKind Leaf, const EnumType *Enum, - ArrayRef<uint8_t> LeafData) { - W.printNumber("NumEnumerators", Enum->NumEnumerators); - W.printFlags("Properties", uint16_t(Enum->Properties), - makeArrayRef(ClassOptionNames)); - printTypeIndex("UnderlyingType", Enum->UnderlyingType); - printTypeIndex("FieldListType", Enum->FieldListType); - Name = getBytesAsCString(LeafData); - W.printString("Name", Name); -} - -void CVTypeDumper::visitArrayType(TypeLeafKind Leaf, const ArrayType *AT, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("ElementType", AT->ElementType); - printTypeIndex("IndexType", AT->IndexType); - uint64_t SizeOf; - error(decodeUIntLeaf(LeafData, SizeOf)); - W.printNumber("SizeOf", SizeOf); - Name = getBytesAsCString(LeafData); - W.printString("Name", Name); -} - -void CVTypeDumper::visitVFTableType(TypeLeafKind Leaf, const VFTableType *VFT, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("CompleteClass", VFT->CompleteClass); - printTypeIndex("OverriddenVFTable", VFT->OverriddenVFTable); - W.printHex("VFPtrOffset", VFT->VFPtrOffset); - StringRef NamesData = getBytesAsCharacters(LeafData.slice(0, VFT->NamesLen)); - std::tie(Name, NamesData) = NamesData.split('\0'); - W.printString("VFTableName", Name); - while (!NamesData.empty()) { - StringRef MethodName; - std::tie(MethodName, NamesData) = NamesData.split('\0'); - W.printString("MethodName", MethodName); - } -} - -void CVTypeDumper::visitMemberFuncId(TypeLeafKind Leaf, const MemberFuncId *Id, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("ClassType", Id->ClassType); - printTypeIndex("FunctionType", Id->FunctionType); - Name = getBytesAsCString(LeafData); - W.printString("Name", Name); -} - -void CVTypeDumper::visitProcedureType(TypeLeafKind Leaf, - const ProcedureType *Proc, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("ReturnType", Proc->ReturnType); - W.printEnum("CallingConvention", uint8_t(Proc->CallConv), - makeArrayRef(CallingConventions)); - W.printFlags("FunctionOptions", uint8_t(Proc->Options), - makeArrayRef(FunctionOptionEnum)); - W.printNumber("NumParameters", Proc->NumParameters); - printTypeIndex("ArgListType", Proc->ArgListType); - - StringRef ReturnTypeName = getTypeName(Proc->ReturnType); - StringRef ArgListTypeName = getTypeName(Proc->ArgListType); - SmallString<256> TypeName(ReturnTypeName); - TypeName.push_back(' '); - TypeName.append(ArgListTypeName); - Name = TypeNames.insert(TypeName).first->getKey(); -} - -void CVTypeDumper::visitMemberFunctionType(TypeLeafKind Leaf, - const MemberFunctionType *MemberFunc, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("ReturnType", MemberFunc->ReturnType); - printTypeIndex("ClassType", MemberFunc->ClassType); - printTypeIndex("ThisType", MemberFunc->ThisType); - W.printEnum("CallingConvention", uint8_t(MemberFunc->CallConv), - makeArrayRef(CallingConventions)); - W.printFlags("FunctionOptions", uint8_t(MemberFunc->Options), - makeArrayRef(FunctionOptionEnum)); - W.printNumber("NumParameters", MemberFunc->NumParameters); - printTypeIndex("ArgListType", MemberFunc->ArgListType); - W.printNumber("ThisAdjustment", MemberFunc->ThisAdjustment); - - StringRef ReturnTypeName = getTypeName(MemberFunc->ReturnType); - StringRef ClassTypeName = getTypeName(MemberFunc->ClassType); - StringRef ArgListTypeName = getTypeName(MemberFunc->ArgListType); - SmallString<256> TypeName(ReturnTypeName); - TypeName.push_back(' '); - TypeName.append(ClassTypeName); - TypeName.append("::"); - TypeName.append(ArgListTypeName); - Name = TypeNames.insert(TypeName).first->getKey(); -} - -void CVTypeDumper::visitMethodList(TypeLeafKind Leaf, - ArrayRef<uint8_t> LeafData) { - while (!LeafData.empty()) { - const MethodListEntry *Method; - if (!consumeObject(LeafData, Method)) - return; - ListScope S(W, "Method"); - printMemberAttributes(Method->Attrs); - printTypeIndex("Type", Method->Type); - if (Method->isIntroducedVirtual()) { - const little32_t *VFTOffsetPtr; - if (!consumeObject(LeafData, VFTOffsetPtr)) - return; - W.printHex("VFTableOffset", *VFTOffsetPtr); - } - } -} - -void CVTypeDumper::visitFuncId(TypeLeafKind Leaf, const FuncId *Func, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("ParentScope", Func->ParentScope); - printTypeIndex("FunctionType", Func->FunctionType); - Name = getBytesAsCString(LeafData); - W.printString("Name", Name); -} - -void CVTypeDumper::visitTypeServer2(TypeLeafKind Leaf, - const TypeServer2 *TypeServer, - ArrayRef<uint8_t> LeafData) { - W.printBinary("Signature", StringRef(TypeServer->Signature, 16)); - W.printNumber("Age", TypeServer->Age); - Name = getBytesAsCString(LeafData); - W.printString("Name", Name); -} - -void CVTypeDumper::visitPointerType(TypeLeafKind Leaf, const PointerType *Ptr, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("PointeeType", Ptr->PointeeType); - W.printHex("PointerAttributes", Ptr->Attrs); - W.printEnum("PtrType", unsigned(Ptr->getPtrKind()), - makeArrayRef(PtrKindNames)); - W.printEnum("PtrMode", unsigned(Ptr->getPtrMode()), - makeArrayRef(PtrModeNames)); - W.printNumber("IsFlat", Ptr->isFlat()); - W.printNumber("IsConst", Ptr->isConst()); - W.printNumber("IsVolatile", Ptr->isVolatile()); - W.printNumber("IsUnaligned", Ptr->isUnaligned()); - - if (Ptr->isPointerToMember()) { - const PointerToMemberTail *PMT; - if (!consumeObject(LeafData, PMT)) - return; - printTypeIndex("ClassType", PMT->ClassType); - W.printEnum("Representation", PMT->Representation, - makeArrayRef(PtrMemberRepNames)); - - StringRef PointeeName = getTypeName(Ptr->PointeeType); - StringRef ClassName = getTypeName(PMT->ClassType); - SmallString<256> TypeName(PointeeName); - TypeName.push_back(' '); - TypeName.append(ClassName); - TypeName.append("::*"); - Name = TypeNames.insert(TypeName).first->getKey(); - } else { - W.printBinaryBlock("TailData", getBytesAsCharacters(LeafData)); - - SmallString<256> TypeName; - if (Ptr->isConst()) - TypeName.append("const "); - if (Ptr->isVolatile()) - TypeName.append("volatile "); - if (Ptr->isUnaligned()) - TypeName.append("__unaligned "); - - TypeName.append(getTypeName(Ptr->PointeeType)); - - if (Ptr->getPtrMode() == PointerMode::LValueReference) - TypeName.append("&"); - else if (Ptr->getPtrMode() == PointerMode::RValueReference) - TypeName.append("&&"); - else if (Ptr->getPtrMode() == PointerMode::Pointer) - TypeName.append("*"); - - Name = TypeNames.insert(TypeName).first->getKey(); - } -} - -void CVTypeDumper::visitTypeModifier(TypeLeafKind Leaf, const TypeModifier *Mod, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("ModifiedType", Mod->ModifiedType); - W.printFlags("Modifiers", Mod->Modifiers, makeArrayRef(TypeModifierNames)); - - StringRef ModifiedName = getTypeName(Mod->ModifiedType); - SmallString<256> TypeName; - if (Mod->Modifiers & uint16_t(ModifierOptions::Const)) - TypeName.append("const "); - if (Mod->Modifiers & uint16_t(ModifierOptions::Volatile)) - TypeName.append("volatile "); - if (Mod->Modifiers & uint16_t(ModifierOptions::Unaligned)) - TypeName.append("__unaligned "); - TypeName.append(ModifiedName); - Name = TypeNames.insert(TypeName).first->getKey(); -} - -void CVTypeDumper::visitVTableShape(TypeLeafKind Leaf, const VTableShape *Shape, - ArrayRef<uint8_t> LeafData) { - unsigned VFEntryCount = Shape->VFEntryCount; - W.printNumber("VFEntryCount", VFEntryCount); - // We could print out whether the methods are near or far, but in practice - // today everything is CV_VTS_near32, so it's just noise. -} - -void CVTypeDumper::visitUDTSrcLine(TypeLeafKind Leaf, const UDTSrcLine *Line, - ArrayRef<uint8_t> LeafData) { - printTypeIndex("UDT", Line->UDT); - printTypeIndex("SourceFile", Line->SourceFile); - W.printNumber("LineNumber", Line->LineNumber); -} - -void CVTypeDumper::visitBuildInfo(TypeLeafKind Leaf, const BuildInfo *Args, - ArrayRef<uint8_t> LeafData) { - W.printNumber("NumArgs", Args->NumArgs); - - ListScope Arguments(W, "Arguments"); - for (uint32_t ArgI = 0; ArgI != Args->NumArgs; ++ArgI) { - const TypeIndex *Type; - if (!consumeObject(LeafData, Type)) - return; - printTypeIndex("ArgType", *Type); - } -} - -void CVTypeDumper::printMemberAttributes(MemberAttributes Attrs) { - W.printEnum("AccessSpecifier", uint8_t(Attrs.getAccess()), - makeArrayRef(MemberAccessNames)); - auto MK = Attrs.getMethodKind(); - // Data members will be vanilla. Don't try to print a method kind for them. - if (MK != MethodKind::Vanilla) - W.printEnum("MethodKind", unsigned(MK), makeArrayRef(MemberKindNames)); - if (Attrs.getFlags() != MethodOptions::None) { - W.printFlags("MethodOptions", unsigned(Attrs.getFlags()), - makeArrayRef(MethodOptionNames)); - } -} - -void CVTypeDumper::visitUnknownMember(TypeLeafKind Leaf) { - W.printHex("UnknownMember", unsigned(Leaf)); -} - -void CVTypeDumper::visitNestedType(TypeLeafKind Leaf, const NestedType *Nested, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "NestedType"); - printTypeIndex("Type", Nested->Type); - StringRef Name = getBytesAsCString(FieldData); - FieldData = FieldData.drop_front(Name.size() + 1); - W.printString("Name", Name); -} - -void CVTypeDumper::visitOneMethod(TypeLeafKind Leaf, const OneMethod *Method, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "OneMethod"); - printMemberAttributes(Method->Attrs); - printTypeIndex("Type", Method->Type); - // If virtual, then read the vftable offset. - if (Method->isIntroducedVirtual()) { - const little32_t *VFTOffsetPtr; - if (!consumeObject(FieldData, VFTOffsetPtr)) - return; - W.printHex("VFTableOffset", *VFTOffsetPtr); - } - StringRef Name = getBytesAsCString(FieldData); - FieldData = FieldData.drop_front(Name.size() + 1); - W.printString("Name", Name); -} - -void CVTypeDumper::visitOverloadedMethod(TypeLeafKind Leaf, - const OverloadedMethod *Method, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "OverloadedMethod"); - W.printHex("MethodCount", Method->MethodCount); - W.printHex("MethodListIndex", Method->MethList.getIndex()); - StringRef Name = getBytesAsCString(FieldData); - FieldData = FieldData.drop_front(Name.size() + 1); - W.printString("Name", Name); -} - -void CVTypeDumper::visitDataMember(TypeLeafKind Leaf, const DataMember *Field, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "DataMember"); - printMemberAttributes(Field->Attrs); - printTypeIndex("Type", Field->Type); - uint64_t FieldOffset; - error(decodeUIntLeaf(FieldData, FieldOffset)); - W.printHex("FieldOffset", FieldOffset); - StringRef Name = getBytesAsCString(FieldData); - FieldData = FieldData.drop_front(Name.size() + 1); - W.printString("Name", Name); -} - -void CVTypeDumper::visitStaticDataMember(TypeLeafKind Leaf, - const StaticDataMember *Field, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "StaticDataMember"); - printMemberAttributes(Field->Attrs); - printTypeIndex("Type", Field->Type); - StringRef Name = getBytesAsCString(FieldData); - FieldData = FieldData.drop_front(Name.size() + 1); - W.printString("Name", Name); -} - -void CVTypeDumper::visitVirtualFunctionPointer( - TypeLeafKind Leaf, const VirtualFunctionPointer *VFTable, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "VirtualFunctionPointer"); - printTypeIndex("Type", VFTable->Type); -} - -void CVTypeDumper::visitEnumerator(TypeLeafKind Leaf, const Enumerator *Enum, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "Enumerator"); - printMemberAttributes(Enum->Attrs); - APSInt EnumValue; - error(decodeNumerictLeaf(FieldData, EnumValue)); - W.printNumber("EnumValue", EnumValue); - StringRef Name = getBytesAsCString(FieldData); - FieldData = FieldData.drop_front(Name.size() + 1); - W.printString("Name", Name); -} - -void CVTypeDumper::visitBaseClass(TypeLeafKind Leaf, const BaseClass *Base, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "BaseClass"); - printMemberAttributes(Base->Attrs); - printTypeIndex("BaseType", Base->BaseType); - uint64_t BaseOffset; - error(decodeUIntLeaf(FieldData, BaseOffset)); - W.printHex("BaseOffset", BaseOffset); -} - -void CVTypeDumper::visitVirtualBaseClass(TypeLeafKind Leaf, - const VirtualBaseClass *Base, - ArrayRef<uint8_t> &FieldData) { - DictScope S(W, "VirtualBaseClass"); - printMemberAttributes(Base->Attrs); - printTypeIndex("BaseType", Base->BaseType); - printTypeIndex("VBPtrType", Base->VBPtrType); - uint64_t VBPtrOffset, VBTableIndex; - error(decodeUIntLeaf(FieldData, VBPtrOffset)); - error(decodeUIntLeaf(FieldData, VBTableIndex)); - W.printHex("VBPtrOffset", VBPtrOffset); - W.printHex("VBTableIndex", VBTableIndex); -} - void COFFDumper::printSections() { ListScope SectionsD(W, "Sections"); int SectionNumber = 0; |