[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