[llvm] r305612 - [CodeView] Fix random access of type names.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 19 15:00:06 PDT 2017
Hopefully fixed in r305753.
On Mon, Jun 19, 2017 at 2:04 PM Vitaly Buka <vitalybuka at google.com> wrote:
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5713/steps/check-llvm%20msan/logs/stdio
>
>
> -- Testing: 21046 tests, 32 threads --
> Testing: 0
> FAIL: LLVM-Unit :: DebugInfo/CodeView/DebugInfoCodeViewTests/RandomAccessVisitorTest.CrossChunkName (1141 of 21046)
> ******************** TEST 'LLVM-Unit :: DebugInfo/CodeView/DebugInfoCodeViewTests/RandomAccessVisitorTest.CrossChunkName' FAILED ********************
> Note: Google Test filter = RandomAccessVisitorTest.CrossChunkName
> [==========] Running 1 test from 1 test case.
> [----------] Global test environment set-up.
> [----------] 1 test from RandomAccessVisitorTest
> [ RUN ] RandomAccessVisitorTest.CrossChunkName
> ==15642==WARNING: MemorySanitizer: use-of-uninitialized-value
> #0 0x53d6c4 in llvm::codeview::CodeViewRecordIO::writeEncodedUnsignedInteger(unsigned long const&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp:235:7
> #1 0x53ec58 in llvm::codeview::CodeViewRecordIO::mapEncodedInteger(unsigned long&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp:137:19
> #2 0x5247ad in llvm::codeview::TypeRecordMapping::visitKnownRecord(llvm::codeview::CVRecord<llvm::codeview::TypeLeafKind>&, llvm::codeview::ClassRecord&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp:224:3
> #3 0x4a6379 in visitKnownRecordImpl<llvm::codeview::ClassRecord> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/DebugInfo/CodeView/TypeSerializer.h:116:20
> #4 0x4a6379 in visitKnownRecord /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def:50
> #5 0x4a6379 in llvm::codeview::TypeIndex llvm::codeview::TypeTableBuilder::writeKnownType<llvm::codeview::ClassRecord>(llvm::codeview::ClassRecord&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h:58
> #6 0x4a48b7 in RandomAccessVisitorTest_CrossChunkName_Test::TestBody() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp:366:33
> #7 0x5bd5c6 in HandleExceptionsInMethodIfSupported<testing::Test, void> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2458:12
> #8 0x5bd5c6 in testing::Test::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2474
> #9 0x5bfc30 in testing::TestInfo::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2656:11
> #10 0x5c14cf in testing::TestCase::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2774:28
> #11 0x5defd9 in testing::internal::UnitTestImpl::RunAllTests() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:4649:43
> #12 0x5ddef8 in HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:2458:12
> #13 0x5ddef8 in testing::UnitTest::Run() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/src/gtest.cc:4257
> #14 0x5a4c7b in RUN_ALL_TESTS /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/googletest/include/gtest/gtest.h:2233:46
> #15 0x5a4c7b in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/utils/unittest/UnitTestMain/TestMain.cpp:51
> #16 0x7f264ca5982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
> #17 0x428c68 in _start (/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_msan/unittests/DebugInfo/CodeView/DebugInfoCodeViewTests+0x428c68)
>
> SUMMARY: MemorySanitizer: use-of-uninitialized-value /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp:235:7 in llvm::codeview::CodeViewRecordIO::writeEncodedUnsignedInteger(unsigned long const&)
> Exiting
>
> ********************
> Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
> Testing Time: 169.44s
> ********************
> Failing Tests (1):
> LLVM-Unit :: DebugInfo/CodeView/DebugInfoCodeViewTests/RandomAccessVisitorTest.CrossChunkName
>
>
> On Fri, Jun 16, 2017 at 4:42 PM, Zachary Turner via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: zturner
>> Date: Fri Jun 16 18:42:44 2017
>> New Revision: 305612
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=305612&view=rev
>> Log:
>> [CodeView] Fix random access of type names.
>>
>> Suppose we had a type index offsets array with a boundary at type index
>> N. Then you request the name of the type with index N+1, and that name
>> requires the name of index N-1 (think a parameter list, for example). We
>> didn't handle this, and we would print something like (<unknown UDT>,
>> <unknown UDT>).
>>
>> The fix for this is not entirely trivial, and speaks to a larger
>> problem. I think we need to kill TypeDatabase, or at the very least kill
>> TypeDatabaseVisitor. We need a thing that doesn't do any caching
>> whatsoever, just given a type index it can compute the type name "the
>> slow way". The reason for the bug is that we don't have anything like
>> that. Everything goes through the type database, and if we've visited a
>> record, then we're "done". It doesn't know how to do the expensive thing
>> of re-visiting dependent records if they've not yet been visited.
>>
>> What I've done here is more or less copied the code (albeit greatly
>> simplified) from TypeDatabaseVisitor, but wrapped it in an interface
>> that just returns a std::string. The logic of caching the name is now in
>> LazyRandomTypeCollection. Eventually I'd like to move the record
>> database here as well and the visited record bitfield here as well, at
>> which point we can actually just delete TypeDatabase. I don't see any
>> reason for it if a "sequential" collection is just a special case of a
>> random access collection with an empty partial offsets array.
>>
>> Differential Revision: https://reviews.llvm.org/D34297
>>
>> Added:
>> llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h
>> llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp
>> Modified:
>> llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
>> llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
>> llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
>> llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
>>
>> Modified:
>> llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h?rev=305612&r1=305611&r2=305612&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
>> (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
>> Fri Jun 16 18:42:44 2017
>> @@ -76,6 +76,11 @@ private:
>> Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
>> Error visitOneRecord(TypeIndex TI, uint32_t Offset, CVType &Record);
>>
>> + BumpPtrAllocator Allocator;
>> + StringSaver NameStorage;
>> +
>> + SmallVector<StringRef, 10> TypeNames;
>> +
>> /// Visited records get automatically added to the type database.
>> TypeDatabase Database;
>>
>>
>> Added: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h?rev=305612&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h (added)
>> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h Fri Jun 16
>> 18:42:44 2017
>> @@ -0,0 +1,22 @@
>> +//===- TypeName.h --------------------------------------------- *- C++
>> --*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
>> +#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
>> +
>> +#include "llvm/DebugInfo/CodeView/TypeCollection.h"
>> +#include "llvm/DebugInfo/CodeView/TypeIndex.h"
>> +
>> +namespace llvm {
>> +namespace codeview {
>> +std::string computeTypeName(TypeCollection &Types, TypeIndex Index);
>> +}
>> +} // namespace llvm
>> +
>> +#endif
>>
>> Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=305612&r1=305611&r2=305612&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Fri Jun 16 18:42:44
>> 2017
>> @@ -29,6 +29,7 @@ add_llvm_library(LLVMDebugInfoCodeView
>> TypeDumpVisitor.cpp
>> TypeIndex.cpp
>> TypeIndexDiscovery.cpp
>> + TypeName.cpp
>> TypeRecordMapping.cpp
>> TypeSerializer.cpp
>> TypeStreamMerger.cpp
>>
>> Modified: llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp?rev=305612&r1=305611&r2=305612&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
>> (original)
>> +++ llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp Fri
>> Jun 16 18:42:44 2017
>> @@ -12,6 +12,7 @@
>> #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
>> #include "llvm/DebugInfo/CodeView/CodeViewError.h"
>> #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
>> +#include "llvm/DebugInfo/CodeView/TypeName.h"
>> #include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
>> #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
>>
>> @@ -31,8 +32,8 @@ LazyRandomTypeCollection::LazyRandomType
>> LazyRandomTypeCollection::LazyRandomTypeCollection(
>> const CVTypeArray &Types, uint32_t RecordCountHint,
>> PartialOffsetArray PartialOffsets)
>> - : Database(RecordCountHint), Types(Types), DatabaseVisitor(Database),
>> - PartialOffsets(PartialOffsets) {
>> + : NameStorage(Allocator), Database(RecordCountHint), Types(Types),
>> + DatabaseVisitor(Database), PartialOffsets(PartialOffsets) {
>> KnownOffsets.resize(Database.capacity());
>> }
>>
>> @@ -71,15 +72,18 @@ CVType LazyRandomTypeCollection::getType
>> }
>>
>> StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
>> - if (!Index.isSimple()) {
>> - // Try to make sure the type exists. Even if it doesn't though, it
>> may be
>> - // because we're dumping a symbol stream with no corresponding type
>> stream
>> - // present, in which case we still want to be able to print <unknown
>> UDT>
>> - // for the type names.
>> - consumeError(ensureTypeExists(Index));
>> - }
>> + if (Index.isNoneType() || Index.isSimple())
>> + return TypeIndex::simpleTypeName(Index);
>>
>> - return Database.getTypeName(Index);
>> + uint32_t I = Index.toArrayIndex();
>> + if (I >= TypeNames.size())
>> + TypeNames.resize(I + 1);
>> +
>> + if (TypeNames[I].data() == nullptr) {
>> + StringRef Result = NameStorage.save(computeTypeName(*this, Index));
>> + TypeNames[I] = Result;
>> + }
>> + return TypeNames[I];
>> }
>>
>> bool LazyRandomTypeCollection::contains(TypeIndex Index) {
>>
>> Added: llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp?rev=305612&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp (added)
>> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp Fri Jun 16 18:42:44
>> 2017
>> @@ -0,0 +1,243 @@
>> +//===- TypeName.cpp ------------------------------------------- *- C++
>> --*-===//
>> +//
>> +// The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include "llvm/DebugInfo/CodeView/TypeName.h"
>> +
>> +#include "llvm/ADT/SmallString.h"
>> +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
>> +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
>> +#include "llvm/Support/FormatVariadic.h"
>> +
>> +using namespace llvm;
>> +using namespace llvm::codeview;
>> +
>> +namespace {
>> +class TypeNameComputer : public TypeVisitorCallbacks {
>> + /// The type collection. Used to calculate names of nested types.
>> + TypeCollection &Types;
>> + TypeIndex CurrentTypeIndex = TypeIndex::None();
>> +
>> + /// Name of the current type. Only valid before visitTypeEnd.
>> + SmallString<256> Name;
>> +
>> +public:
>> + explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
>> +
>> + StringRef name() const { return Name; }
>> +
>> + /// Paired begin/end actions for all types. Receives all record data,
>> + /// including the fixed-length record prefix.
>> + Error visitTypeBegin(CVType &Record) override;
>> + Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
>> + Error visitTypeEnd(CVType &Record) override;
>> +
>> +#define TYPE_RECORD(EnumName, EnumVal, Name)
>> \
>> + Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
>> +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
>> +#define MEMBER_RECORD(EnumName, EnumVal, Name)
>> +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
>> +};
>> +} // namespace
>> +
>> +Error TypeNameComputer::visitTypeBegin(CVType &Record) {
>> + llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
>> + // Reset Name to the empty string. If the visitor sets it, we know it.
>> + Name = "";
>> + CurrentTypeIndex = Index;
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return
>> Error::success(); }
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR,
>> + FieldListRecord &FieldList) {
>> + Name = "<field list>";
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
>> + StringIdRecord &String) {
>> + Name = String.getString();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord
>> &Args) {
>> + auto Indices = Args.getIndices();
>> + uint32_t Size = Indices.size();
>> + Name = "(";
>> + for (uint32_t I = 0; I < Size; ++I) {
>> + assert(Indices[I] < CurrentTypeIndex);
>> +
>> + Name.append(Types.getTypeName(Indices[I]));
>> + if (I + 1 != Size)
>> + Name.append(", ");
>> + }
>> + Name.push_back(')');
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR,
>> + StringListRecord &Strings) {
>> + auto Indices = Strings.getIndices();
>> + uint32_t Size = Indices.size();
>> + Name = "\"";
>> + for (uint32_t I = 0; I < Size; ++I) {
>> + Name.append(Types.getTypeName(Indices[I]));
>> + if (I + 1 != Size)
>> + Name.append("\" \"");
>> + }
>> + Name.push_back('\"');
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord
>> &Class) {
>> + Name = Class.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord
>> &Union) {
>> + Name = Union.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
>> + Name = Enum.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
>> + Name = AT.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord
>> &VFT) {
>> + Name = VFT.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord
>> &Id) {
>> + Name = Id.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord
>> &Proc) {
>> + StringRef Ret = Types.getTypeName(Proc.getReturnType());
>> + StringRef Params = Types.getTypeName(Proc.getArgumentList());
>> + Name = formatv("{0} {1}", Ret, Params).sstr<256>();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR,
>> + MemberFunctionRecord &MF) {
>> + StringRef Ret = Types.getTypeName(MF.getReturnType());
>> + StringRef Class = Types.getTypeName(MF.getClassType());
>> + StringRef Params = Types.getTypeName(MF.getArgumentList());
>> + Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord
>> &Func) {
>> + Name = Func.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record
>> &TS) {
>> + Name = TS.getName();
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord
>> &Ptr) {
>> +
>> + if (Ptr.isPointerToMember()) {
>> + const MemberPointerInfo &MI = Ptr.getMemberInfo();
>> +
>> + StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
>> + StringRef Class = Types.getTypeName(MI.getContainingType());
>> + Name = formatv("{0} {1}::*", Pointee, Class);
>> + } else {
>> + if (Ptr.isConst())
>> + Name.append("const ");
>> + if (Ptr.isVolatile())
>> + Name.append("volatile ");
>> + if (Ptr.isUnaligned())
>> + Name.append("__unaligned ");
>> +
>> + Name.append(Types.getTypeName(Ptr.getReferentType()));
>> +
>> + if (Ptr.getMode() == PointerMode::LValueReference)
>> + Name.append("&");
>> + else if (Ptr.getMode() == PointerMode::RValueReference)
>> + Name.append("&&");
>> + else if (Ptr.getMode() == PointerMode::Pointer)
>> + Name.append("*");
>> + }
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord
>> &Mod) {
>> + uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
>> +
>> + SmallString<256> TypeName;
>> + if (Mods & uint16_t(ModifierOptions::Const))
>> + Name.append("const ");
>> + if (Mods & uint16_t(ModifierOptions::Volatile))
>> + Name.append("volatile ");
>> + if (Mods & uint16_t(ModifierOptions::Unaligned))
>> + Name.append("__unaligned ");
>> + Name.append(Types.getTypeName(Mod.getModifiedType()));
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR,
>> + VFTableShapeRecord &Shape) {
>> + Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(
>> + CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR,
>> + UdtSourceLineRecord
>> &SourceLine) {
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord
>> &BF) {
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR,
>> + MethodOverloadListRecord
>> &Overloads) {
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord
>> &BI) {
>> + return Error::success();
>> +}
>> +
>> +Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
>> + return Error::success();
>> +}
>> +
>> +std::string llvm::codeview::computeTypeName(TypeCollection &Types,
>> + TypeIndex Index) {
>> + TypeNameComputer Computer(Types);
>> + CVType Record = Types.getType(Index);
>> + if (auto EC = visitTypeRecord(Record, Index, Computer)) {
>> + consumeError(std::move(EC));
>> + return "<unknown UDT>";
>> + }
>> + return Computer.name();
>> +}
>>
>> Modified:
>> llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp?rev=305612&r1=305611&r2=305612&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
>> (original)
>> +++ llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
>> Fri Jun 16 18:42:44 2017
>> @@ -351,3 +351,54 @@ TEST_F(RandomAccessVisitorTest, InnerChu
>> for (auto &I : enumerate(IndicesToVisit))
>> EXPECT_TRUE(ValidateVisitedRecord(I.index(), I.value()));
>> }
>> +
>> +TEST_F(RandomAccessVisitorTest, CrossChunkName) {
>> + TypeTableBuilder Builder(GlobalState->Allocator);
>> +
>> + // TypeIndex 0
>> + ClassRecord Class(TypeRecordKind::Class);
>> + Class.Name = "FooClass";
>> + Class.Options = ClassOptions::None;
>> + Class.MemberCount = 0;
>> + Class.DerivationList = TypeIndex::fromArrayIndex(0);
>> + Class.FieldList = TypeIndex::fromArrayIndex(0);
>> + Class.VTableShape = TypeIndex::fromArrayIndex(0);
>> + TypeIndex IndexZero = Builder.writeKnownType(Class);
>> +
>> + // TypeIndex 1 refers to type index 0.
>> + ModifierRecord Modifier(TypeRecordKind::Modifier);
>> + Modifier.ModifiedType = TypeIndex::fromArrayIndex(0);
>> + Modifier.Modifiers = ModifierOptions::Const;
>> + TypeIndex IndexOne = Builder.writeKnownType(Modifier);
>> +
>> + // set up a type stream that refers to the above two serialized
>> records.
>> + std::vector<CVType> TypeArray;
>> + TypeArray.push_back(
>> + CVType(static_cast<TypeLeafKind>(Class.Kind),
>> Builder.records()[0]));
>> + TypeArray.push_back(
>> + CVType(static_cast<TypeLeafKind>(Modifier.Kind),
>> Builder.records()[1]));
>> + BinaryItemStream<CVType> ItemStream(llvm::support::little);
>> + ItemStream.setItems(TypeArray);
>> + VarStreamArray<CVType> TypeStream(ItemStream);
>> +
>> + // Figure out the byte offset of the second item.
>> + auto ItemOneIter = TypeStream.begin();
>> + ++ItemOneIter;
>> +
>> + // Set up a partial offsets buffer that contains the first and second
>> items
>> + // in separate chunks.
>> + std::vector<TypeIndexOffset> TIO;
>> + TIO.push_back({IndexZero, ulittle32_t(0u)});
>> + TIO.push_back({IndexOne, ulittle32_t(ItemOneIter.offset())});
>> + ArrayRef<uint8_t> Buffer(reinterpret_cast<const uint8_t *>(TIO.data()),
>> + TIO.size() * sizeof(TypeIndexOffset));
>> +
>> + BinaryStreamReader Reader(Buffer, llvm::support::little);
>> + FixedStreamArray<TypeIndexOffset> PartialOffsets;
>> + ASSERT_THAT_ERROR(Reader.readArray(PartialOffsets, 2), Succeeded());
>> +
>> + LazyRandomTypeCollection Types(TypeStream, 2, PartialOffsets);
>> +
>> + StringRef Name = Types.getTypeName(IndexOne);
>> + EXPECT_EQ("const FooClass", Name);
>> +}
>> \ No newline at end of file
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170619/4bdee7b9/attachment.html>
More information about the llvm-commits
mailing list