<div dir="ltr"><pre><span class="gmail-stdout"><font color="#000000" face="Courier New, courier, monotype, monospace" size="3"><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5713/steps/check-llvm%20msan/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5713/steps/check-llvm%20msan/logs/stdio</a><br></font></span></pre><pre><span class="gmail-stdout"><font color="#000000" face="Courier New, courier, monotype, monospace" size="3"><br></font></span></pre><pre style="font-family:"Courier New",courier,monotype,monospace;color:rgb(0,0,0);font-size:medium"><span class="gmail-stdout">-- 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</span></pre></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 16, 2017 at 4:42 PM, Zachary Turner via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br>
Date: Fri Jun 16 18:42:44 2017<br>
New Revision: 305612<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=305612&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=305612&view=rev</a><br>
Log:<br>
[CodeView] Fix random access of type names.<br>
<br>
Suppose we had a type index offsets array with a boundary at type index<br>
N. Then you request the name of the type with index N+1, and that name<br>
requires the name of index N-1 (think a parameter list, for example). We<br>
didn't handle this, and we would print something like (<unknown UDT>,<br>
<unknown UDT>).<br>
<br>
The fix for this is not entirely trivial, and speaks to a larger<br>
problem. I think we need to kill TypeDatabase, or at the very least kill<br>
TypeDatabaseVisitor. We need a thing that doesn't do any caching<br>
whatsoever, just given a type index it can compute the type name "the<br>
slow way". The reason for the bug is that we don't have anything like<br>
that. Everything goes through the type database, and if we've visited a<br>
record, then we're "done". It doesn't know how to do the expensive thing<br>
of re-visiting dependent records if they've not yet been visited.<br>
<br>
What I've done here is more or less copied the code (albeit greatly<br>
simplified) from TypeDatabaseVisitor, but wrapped it in an interface<br>
that just returns a std::string. The logic of caching the name is now in<br>
LazyRandomTypeCollection. Eventually I'd like to move the record<br>
database here as well and the visited record bitfield here as well, at<br>
which point we can actually just delete TypeDatabase. I don't see any<br>
reason for it if a "sequential" collection is just a special case of a<br>
random access collection with an empty partial offsets array.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D34297" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D34297</a><br>
<br>
Added:<br>
llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/TypeName.h<br>
llvm/trunk/lib/DebugInfo/<wbr>CodeView/TypeName.cpp<br>
Modified:<br>
llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/<wbr>LazyRandomTypeCollection.h<br>
llvm/trunk/lib/DebugInfo/<wbr>CodeView/CMakeLists.txt<br>
llvm/trunk/lib/DebugInfo/<wbr>CodeView/<wbr>LazyRandomTypeCollection.cpp<br>
llvm/trunk/unittests/<wbr>DebugInfo/CodeView/<wbr>RandomAccessVisitorTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/<wbr>LazyRandomTypeCollection.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h?rev=305612&r1=305611&r2=305612&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/DebugInfo/CodeView/<wbr>LazyRandomTypeCollection.h?<wbr>rev=305612&r1=305611&r2=<wbr>305612&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/<wbr>LazyRandomTypeCollection.h (original)<br>
+++ llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/<wbr>LazyRandomTypeCollection.h Fri Jun 16 18:42:44 2017<br>
@@ -76,6 +76,11 @@ private:<br>
Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);<br>
Error visitOneRecord(TypeIndex TI, uint32_t Offset, CVType &Record);<br>
<br>
+ BumpPtrAllocator Allocator;<br>
+ StringSaver NameStorage;<br>
+<br>
+ SmallVector<StringRef, 10> TypeNames;<br>
+<br>
/// Visited records get automatically added to the type database.<br>
TypeDatabase Database;<br>
<br>
<br>
Added: llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/TypeName.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeName.h?rev=305612&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/DebugInfo/CodeView/<wbr>TypeName.h?rev=305612&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/TypeName.h (added)<br>
+++ llvm/trunk/include/llvm/<wbr>DebugInfo/CodeView/TypeName.h Fri Jun 16 18:42:44 2017<br>
@@ -0,0 +1,22 @@<br>
+//===- TypeName.h ------------------------------<wbr>--------------- *- C++ --*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_DEBUGINFO_CODEVIEW_<wbr>TYPENAME_H<br>
+#define LLVM_DEBUGINFO_CODEVIEW_<wbr>TYPENAME_H<br>
+<br>
+#include "llvm/DebugInfo/CodeView/<wbr>TypeCollection.h"<br>
+#include "llvm/DebugInfo/CodeView/<wbr>TypeIndex.h"<br>
+<br>
+namespace llvm {<br>
+namespace codeview {<br>
+std::string computeTypeName(TypeCollection &Types, TypeIndex Index);<br>
+}<br>
+} // namespace llvm<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/<wbr>CodeView/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=305612&r1=305611&r2=305612&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>DebugInfo/CodeView/CMakeLists.<wbr>txt?rev=305612&r1=305611&r2=<wbr>305612&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/DebugInfo/<wbr>CodeView/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/DebugInfo/<wbr>CodeView/CMakeLists.txt Fri Jun 16 18:42:44 2017<br>
@@ -29,6 +29,7 @@ add_llvm_library(<wbr>LLVMDebugInfoCodeView<br>
TypeDumpVisitor.cpp<br>
TypeIndex.cpp<br>
TypeIndexDiscovery.cpp<br>
+ TypeName.cpp<br>
TypeRecordMapping.cpp<br>
TypeSerializer.cpp<br>
TypeStreamMerger.cpp<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/<wbr>CodeView/<wbr>LazyRandomTypeCollection.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp?rev=305612&r1=305611&r2=305612&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>DebugInfo/CodeView/<wbr>LazyRandomTypeCollection.cpp?<wbr>rev=305612&r1=305611&r2=<wbr>305612&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/DebugInfo/<wbr>CodeView/<wbr>LazyRandomTypeCollection.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/<wbr>CodeView/<wbr>LazyRandomTypeCollection.cpp Fri Jun 16 18:42:44 2017<br>
@@ -12,6 +12,7 @@<br>
#include "llvm/DebugInfo/CodeView/<wbr>CVTypeVisitor.h"<br>
#include "llvm/DebugInfo/CodeView/<wbr>CodeViewError.h"<br>
#include "llvm/DebugInfo/CodeView/<wbr>TypeDatabase.h"<br>
+#include "llvm/DebugInfo/CodeView/<wbr>TypeName.h"<br>
#include "llvm/DebugInfo/CodeView/<wbr>TypeServerHandler.h"<br>
#include "llvm/DebugInfo/CodeView/<wbr>TypeVisitorCallbacks.h"<br>
<br>
@@ -31,8 +32,8 @@ LazyRandomTypeCollection::<wbr>LazyRandomType<br>
LazyRandomTypeCollection::<wbr>LazyRandomTypeCollection(<br>
const CVTypeArray &Types, uint32_t RecordCountHint,<br>
PartialOffsetArray PartialOffsets)<br>
- : Database(RecordCountHint), Types(Types), DatabaseVisitor(Database),<br>
- PartialOffsets(PartialOffsets) {<br>
+ : NameStorage(Allocator), Database(RecordCountHint), Types(Types),<br>
+ DatabaseVisitor(Database), PartialOffsets(PartialOffsets) {<br>
KnownOffsets.resize(Database.<wbr>capacity());<br>
}<br>
<br>
@@ -71,15 +72,18 @@ CVType LazyRandomTypeCollection::<wbr>getType<br>
}<br>
<br>
StringRef LazyRandomTypeCollection::<wbr>getTypeName(TypeIndex Index) {<br>
- if (!Index.isSimple()) {<br>
- // Try to make sure the type exists. Even if it doesn't though, it may be<br>
- // because we're dumping a symbol stream with no corresponding type stream<br>
- // present, in which case we still want to be able to print <unknown UDT><br>
- // for the type names.<br>
- consumeError(ensureTypeExists(<wbr>Index));<br>
- }<br>
+ if (Index.isNoneType() || Index.isSimple())<br>
+ return TypeIndex::simpleTypeName(<wbr>Index);<br>
<br>
- return Database.getTypeName(Index);<br>
+ uint32_t I = Index.toArrayIndex();<br>
+ if (I >= TypeNames.size())<br>
+ TypeNames.resize(I + 1);<br>
+<br>
+ if (TypeNames[I].data() == nullptr) {<br>
+ StringRef Result = NameStorage.save(<wbr>computeTypeName(*this, Index));<br>
+ TypeNames[I] = Result;<br>
+ }<br>
+ return TypeNames[I];<br>
}<br>
<br>
bool LazyRandomTypeCollection::<wbr>contains(TypeIndex Index) {<br>
<br>
Added: llvm/trunk/lib/DebugInfo/<wbr>CodeView/TypeName.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeName.cpp?rev=305612&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>DebugInfo/CodeView/TypeName.<wbr>cpp?rev=305612&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/DebugInfo/<wbr>CodeView/TypeName.cpp (added)<br>
+++ llvm/trunk/lib/DebugInfo/<wbr>CodeView/TypeName.cpp Fri Jun 16 18:42:44 2017<br>
@@ -0,0 +1,243 @@<br>
+//===- TypeName.cpp ------------------------------<wbr>------------- *- C++ --*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "llvm/DebugInfo/CodeView/<wbr>TypeName.h"<br>
+<br>
+#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/DebugInfo/CodeView/<wbr>CVTypeVisitor.h"<br>
+#include "llvm/DebugInfo/CodeView/<wbr>TypeVisitorCallbacks.h"<br>
+#include "llvm/Support/FormatVariadic.<wbr>h"<br>
+<br>
+using namespace llvm;<br>
+using namespace llvm::codeview;<br>
+<br>
+namespace {<br>
+class TypeNameComputer : public TypeVisitorCallbacks {<br>
+ /// The type collection. Used to calculate names of nested types.<br>
+ TypeCollection &Types;<br>
+ TypeIndex CurrentTypeIndex = TypeIndex::None();<br>
+<br>
+ /// Name of the current type. Only valid before visitTypeEnd.<br>
+ SmallString<256> Name;<br>
+<br>
+public:<br>
+ explicit TypeNameComputer(<wbr>TypeCollection &Types) : Types(Types) {}<br>
+<br>
+ StringRef name() const { return Name; }<br>
+<br>
+ /// Paired begin/end actions for all types. Receives all record data,<br>
+ /// including the fixed-length record prefix.<br>
+ Error visitTypeBegin(CVType &Record) override;<br>
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override;<br>
+ Error visitTypeEnd(CVType &Record) override;<br>
+<br>
+#define TYPE_RECORD(EnumName, EnumVal, Name) \<br>
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;<br>
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)<br>
+#define MEMBER_RECORD(EnumName, EnumVal, Name)<br>
+#include "llvm/DebugInfo/CodeView/<wbr>CodeViewTypes.def"<br>
+};<br>
+} // namespace<br>
+<br>
+Error TypeNameComputer::<wbr>visitTypeBegin(CVType &Record) {<br>
+ llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitTypeBegin(CVType &Record, TypeIndex Index) {<br>
+ // Reset Name to the empty string. If the visitor sets it, we know it.<br>
+ Name = "";<br>
+ CurrentTypeIndex = Index;<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitTypeEnd(CVType &CVR) { return Error::success(); }<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR,<br>
+ FieldListRecord &FieldList) {<br>
+ Name = "<field list>";<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVRecord<<wbr>TypeLeafKind> &CVR,<br>
+ StringIdRecord &String) {<br>
+ Name = String.getString();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, ArgListRecord &Args) {<br>
+ auto Indices = Args.getIndices();<br>
+ uint32_t Size = Indices.size();<br>
+ Name = "(";<br>
+ for (uint32_t I = 0; I < Size; ++I) {<br>
+ assert(Indices[I] < CurrentTypeIndex);<br>
+<br>
+ Name.append(Types.getTypeName(<wbr>Indices[I]));<br>
+ if (I + 1 != Size)<br>
+ Name.append(", ");<br>
+ }<br>
+ Name.push_back(')');<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR,<br>
+ StringListRecord &Strings) {<br>
+ auto Indices = Strings.getIndices();<br>
+ uint32_t Size = Indices.size();<br>
+ Name = "\"";<br>
+ for (uint32_t I = 0; I < Size; ++I) {<br>
+ Name.append(Types.getTypeName(<wbr>Indices[I]));<br>
+ if (I + 1 != Size)<br>
+ Name.append("\" \"");<br>
+ }<br>
+ Name.push_back('\"');<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, ClassRecord &Class) {<br>
+ Name = Class.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, UnionRecord &Union) {<br>
+ Name = Union.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, EnumRecord &Enum) {<br>
+ Name = Enum.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, ArrayRecord &AT) {<br>
+ Name = AT.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {<br>
+ Name = VFT.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {<br>
+ Name = Id.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {<br>
+ StringRef Ret = Types.getTypeName(Proc.<wbr>getReturnType());<br>
+ StringRef Params = Types.getTypeName(Proc.<wbr>getArgumentList());<br>
+ Name = formatv("{0} {1}", Ret, Params).sstr<256>();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR,<br>
+ MemberFunctionRecord &MF) {<br>
+ StringRef Ret = Types.getTypeName(MF.<wbr>getReturnType());<br>
+ StringRef Class = Types.getTypeName(MF.<wbr>getClassType());<br>
+ StringRef Params = Types.getTypeName(MF.<wbr>getArgumentList());<br>
+ Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {<br>
+ Name = Func.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {<br>
+ Name = TS.getName();<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {<br>
+<br>
+ if (Ptr.isPointerToMember()) {<br>
+ const MemberPointerInfo &MI = Ptr.getMemberInfo();<br>
+<br>
+ StringRef Pointee = Types.getTypeName(Ptr.<wbr>getReferentType());<br>
+ StringRef Class = Types.getTypeName(MI.<wbr>getContainingType());<br>
+ Name = formatv("{0} {1}::*", Pointee, Class);<br>
+ } else {<br>
+ if (Ptr.isConst())<br>
+ Name.append("const ");<br>
+ if (Ptr.isVolatile())<br>
+ Name.append("volatile ");<br>
+ if (Ptr.isUnaligned())<br>
+ Name.append("__unaligned ");<br>
+<br>
+ Name.append(Types.getTypeName(<wbr>Ptr.getReferentType()));<br>
+<br>
+ if (Ptr.getMode() == PointerMode::LValueReference)<br>
+ Name.append("&");<br>
+ else if (Ptr.getMode() == PointerMode::RValueReference)<br>
+ Name.append("&&");<br>
+ else if (Ptr.getMode() == PointerMode::Pointer)<br>
+ Name.append("*");<br>
+ }<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {<br>
+ uint16_t Mods = static_cast<uint16_t>(Mod.<wbr>getModifiers());<br>
+<br>
+ SmallString<256> TypeName;<br>
+ if (Mods & uint16_t(ModifierOptions::<wbr>Const))<br>
+ Name.append("const ");<br>
+ if (Mods & uint16_t(ModifierOptions::<wbr>Volatile))<br>
+ Name.append("volatile ");<br>
+ if (Mods & uint16_t(ModifierOptions::<wbr>Unaligned))<br>
+ Name.append("__unaligned ");<br>
+ Name.append(Types.getTypeName(<wbr>Mod.getModifiedType()));<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR,<br>
+ VFTableShapeRecord &Shape) {<br>
+ Name = formatv("<vftable {0} methods>", Shape.getEntryCount());<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(<br>
+ CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR,<br>
+ UdtSourceLineRecord &SourceLine) {<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR,<br>
+ MethodOverloadListRecord &Overloads) {<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {<br>
+ return Error::success();<br>
+}<br>
+<br>
+Error TypeNameComputer::<wbr>visitKnownRecord(CVType &CVR, LabelRecord &R) {<br>
+ return Error::success();<br>
+}<br>
+<br>
+std::string llvm::codeview::<wbr>computeTypeName(TypeCollection &Types,<br>
+ TypeIndex Index) {<br>
+ TypeNameComputer Computer(Types);<br>
+ CVType Record = Types.getType(Index);<br>
+ if (auto EC = visitTypeRecord(Record, Index, Computer)) {<br>
+ consumeError(std::move(EC));<br>
+ return "<unknown UDT>";<br>
+ }<br>
+ return Computer.name();<br>
+}<br>
<br>
Modified: llvm/trunk/unittests/<wbr>DebugInfo/CodeView/<wbr>RandomAccessVisitorTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp?rev=305612&r1=305611&r2=305612&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/unittests/<wbr>DebugInfo/CodeView/<wbr>RandomAccessVisitorTest.cpp?<wbr>rev=305612&r1=305611&r2=<wbr>305612&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/unittests/<wbr>DebugInfo/CodeView/<wbr>RandomAccessVisitorTest.cpp (original)<br>
+++ llvm/trunk/unittests/<wbr>DebugInfo/CodeView/<wbr>RandomAccessVisitorTest.cpp Fri Jun 16 18:42:44 2017<br>
@@ -351,3 +351,54 @@ TEST_F(<wbr>RandomAccessVisitorTest, InnerChu<br>
for (auto &I : enumerate(IndicesToVisit))<br>
EXPECT_TRUE(<wbr>ValidateVisitedRecord(I.index(<wbr>), I.value()));<br>
}<br>
+<br>
+TEST_F(<wbr>RandomAccessVisitorTest, CrossChunkName) {<br>
+ TypeTableBuilder Builder(GlobalState-><wbr>Allocator);<br>
+<br>
+ // TypeIndex 0<br>
+ ClassRecord Class(TypeRecordKind::Class);<br>
+ Class.Name = "FooClass";<br>
+ Class.Options = ClassOptions::None;<br>
+ Class.MemberCount = 0;<br>
+ Class.DerivationList = TypeIndex::fromArrayIndex(0);<br>
+ Class.FieldList = TypeIndex::fromArrayIndex(0);<br>
+ Class.VTableShape = TypeIndex::fromArrayIndex(0);<br>
+ TypeIndex IndexZero = Builder.writeKnownType(Class);<br>
+<br>
+ // TypeIndex 1 refers to type index 0.<br>
+ ModifierRecord Modifier(TypeRecordKind::<wbr>Modifier);<br>
+ Modifier.ModifiedType = TypeIndex::fromArrayIndex(0);<br>
+ Modifier.Modifiers = ModifierOptions::Const;<br>
+ TypeIndex IndexOne = Builder.writeKnownType(<wbr>Modifier);<br>
+<br>
+ // set up a type stream that refers to the above two serialized records.<br>
+ std::vector<CVType> TypeArray;<br>
+ TypeArray.push_back(<br>
+ CVType(static_cast<<wbr>TypeLeafKind>(Class.Kind), Builder.records()[0]));<br>
+ TypeArray.push_back(<br>
+ CVType(static_cast<<wbr>TypeLeafKind>(Modifier.Kind), Builder.records()[1]));<br>
+ BinaryItemStream<CVType> ItemStream(llvm::support::<wbr>little);<br>
+ ItemStream.setItems(TypeArray)<wbr>;<br>
+ VarStreamArray<CVType> TypeStream(ItemStream);<br>
+<br>
+ // Figure out the byte offset of the second item.<br>
+ auto ItemOneIter = TypeStream.begin();<br>
+ ++ItemOneIter;<br>
+<br>
+ // Set up a partial offsets buffer that contains the first and second items<br>
+ // in separate chunks.<br>
+ std::vector<TypeIndexOffset> TIO;<br>
+ TIO.push_back({IndexZero, ulittle32_t(0u)});<br>
+ TIO.push_back({IndexOne, ulittle32_t(ItemOneIter.<wbr>offset())});<br>
+ ArrayRef<uint8_t> Buffer(reinterpret_cast<const uint8_t *>(TIO.data()),<br>
+ TIO.size() * sizeof(TypeIndexOffset));<br>
+<br>
+ BinaryStreamReader Reader(Buffer, llvm::support::little);<br>
+ FixedStreamArray<<wbr>TypeIndexOffset> PartialOffsets;<br>
+ ASSERT_THAT_ERROR(Reader.<wbr>readArray(PartialOffsets, 2), Succeeded());<br>
+<br>
+ LazyRandomTypeCollection Types(TypeStream, 2, PartialOffsets);<br>
+<br>
+ StringRef Name = Types.getTypeName(IndexOne);<br>
+ EXPECT_EQ("const FooClass", Name);<br>
+}<br>
\ No newline at end of file<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>