[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