[llvm] r305612 - [CodeView] Fix random access of type names.
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 19 14:03:45 PDT 2017
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/6af4c085/attachment-0001.html>
More information about the llvm-commits
mailing list