[llvm] [llvm-debuginfo-analyzer] Support DW_AT_byte_size and DW_TAG_module (PR #137228)
Javier Lopez-Gomez via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 25 07:28:07 PDT 2025
https://github.com/jalopezg-git updated https://github.com/llvm/llvm-project/pull/137228
>From 9c38deb04a380e8d7d5d0e21c0f399e815abd45c Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Fri, 25 Apr 2025 16:27:25 +0200
Subject: [PATCH 1/2] [llvm-debuginfo-analyzer] Add support for DWARF
`DW_AT_byte_size`
---
.../DebugInfo/LogicalView/Core/LVElement.h | 7 ++++
.../llvm/DebugInfo/LogicalView/Core/LVScope.h | 6 +++
.../llvm/DebugInfo/LogicalView/Core/LVType.h | 7 ++++
.../lib/DebugInfo/LogicalView/Core/LVType.cpp | 5 ++-
.../LogicalView/Readers/LVCodeViewVisitor.cpp | 3 ++
.../LogicalView/Readers/LVDWARFReader.cpp | 3 ++
.../LogicalView/CodeViewReaderTest.cpp | 41 +++++++++++++++++++
.../DebugInfo/LogicalView/DWARFReaderTest.cpp | 6 +++
8 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index 17fa04040ad77..b2ef6579caf41 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -64,6 +64,10 @@ using LVElementKindSet = std::set<LVElementKind>;
using LVElementDispatch = std::map<LVElementKind, LVElementGetFunction>;
using LVElementRequest = std::vector<LVElementGetFunction>;
+// Assume 8-bit bytes; this is consistent, e.g. with
+// lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp.
+constexpr unsigned int DWARF_CHAR_BIT = 8u;
+
class LVElement : public LVObject {
enum class Property {
IsLine, // A logical line.
@@ -239,6 +243,9 @@ class LVElement : public LVObject {
virtual bool isBase() const { return false; }
virtual bool isTemplateParam() const { return false; }
+ uint32_t getStorageSizeInBytes() const {
+ return (getBitSize() + (DWARF_CHAR_BIT - 1)) / DWARF_CHAR_BIT;
+ }
virtual uint32_t getBitSize() const { return 0; }
virtual void setBitSize(uint32_t Size) {}
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index 1b3c377cd7dbb..1cf61d085d84f 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -93,6 +93,9 @@ class LVScope : public LVElement {
LVProperties<Property> Properties;
static LVScopeDispatch Dispatch;
+ // Size in bits if this scope represents also a compound type.
+ uint32_t BitSize = 0;
+
// Coverage factor in units (bytes).
unsigned CoverageFactor = 0;
@@ -269,6 +272,9 @@ class LVScope : public LVElement {
bool removeElement(LVElement *Element) override;
void updateLevel(LVScope *Parent, bool Moved) override;
+ uint32_t getBitSize() const override { return BitSize; }
+ void setBitSize(uint32_t Size) override { BitSize = Size; }
+
void resolve() override;
void resolveName() override;
void resolveReferences() override;
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
index 28881b3c95b17..58d5bc48c3a72 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
@@ -56,6 +56,9 @@ class LVType : public LVElement {
LVProperties<Property> Properties;
static LVTypeDispatch Dispatch;
+ // Size in bits of a symbol of this type.
+ uint32_t BitSize = 0;
+
// Find the current type in the given 'Targets'.
LVType *findIn(const LVTypes *Targets) const;
@@ -109,6 +112,10 @@ class LVType : public LVElement {
virtual LVElement *getUnderlyingType() { return nullptr; }
virtual void setUnderlyingType(LVElement *Element) {}
+ // Return the size in bits of an entity of this type.
+ uint32_t getBitSize() const override { return BitSize; }
+ void setBitSize(uint32_t Size) override { BitSize = Size; }
+
void resolveName() override;
void resolveReferences() override;
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
index 28bccadce598c..e5c9936c008e2 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
@@ -292,7 +292,10 @@ void LVType::print(raw_ostream &OS, bool Full) const {
}
void LVType::printExtra(raw_ostream &OS, bool Full) const {
- OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
+ OS << formattedKind(kind()) << " " << formattedName(getName());
+ if (uint32_t Size = getStorageSizeInBytes())
+ OS << " [Size = " << Size << "]";
+ OS << "\n";
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index 97214948d014a..4a1eb888095e2 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -1987,6 +1987,7 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,
Scope->setName(Class.getName());
if (Class.hasUniqueName())
Scope->setLinkageName(Class.getUniqueName());
+ Scope->setBitSize(Class.getSize() * DWARF_CHAR_BIT);
if (Class.isNested()) {
Scope->setIsNested();
@@ -2455,6 +2456,7 @@ Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,
Scope->setName(Union.getName());
if (Union.hasUniqueName())
Scope->setLinkageName(Union.getUniqueName());
+ Scope->setBitSize(Union.getSize() * DWARF_CHAR_BIT);
if (Union.isNested()) {
Scope->setIsNested();
@@ -3208,6 +3210,7 @@ LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {
if (createElement(TIR, SimpleKind)) {
CurrentType->setName(TypeName);
+ CurrentType->setBitSize(getSizeInBytesForTypeIndex(TIR) * DWARF_CHAR_BIT);
Reader->getCompileUnit()->addElement(CurrentType);
}
return CurrentType;
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 42da957233667..269630896e077 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -307,6 +307,9 @@ void LVDWARFReader::processOneAttribute(const DWARFDie &Die,
case dwarf::DW_AT_bit_size:
CurrentElement->setBitSize(GetAsUnsignedConstant());
break;
+ case dwarf::DW_AT_byte_size:
+ CurrentElement->setBitSize(GetAsUnsignedConstant() * DWARF_CHAR_BIT);
+ break;
case dwarf::DW_AT_call_file:
CurrentElement->setCallFilenameIndex(IncrementFileIndex
? GetAsUnsignedConstant() + 1
diff --git a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
index c93a79094dce9..0549aa2976b46 100644
--- a/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/CodeViewReaderTest.cpp
@@ -21,6 +21,7 @@
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
+#include <algorithm>
using namespace llvm;
using namespace llvm::logicalview;
@@ -128,6 +129,26 @@ void checkElementPropertiesClangCodeview(LVReader *Reader) {
const LVLines *Lines = Foo->getLines();
ASSERT_NE(Lines, nullptr);
EXPECT_EQ(Lines->size(), 0x10u);
+
+ // Check size of types in CompileUnit.
+ const LVTypes *Types = CompileUnit->getTypes();
+ ASSERT_NE(Types, nullptr);
+ EXPECT_EQ(Types->size(), 6u);
+
+ const auto BoolType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "bool";
+ });
+ ASSERT_NE(BoolType, Types->end());
+ const auto IntType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "int";
+ });
+ ASSERT_NE(IntType, Types->end());
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);
}
// Check the logical elements basic properties (MSVC - Codeview).
@@ -194,6 +215,26 @@ void checkElementPropertiesMsvcCodeview(LVReader *Reader) {
const LVLines *Lines = Foo->getLines();
ASSERT_NE(Lines, nullptr);
EXPECT_EQ(Lines->size(), 0x0eu);
+
+ // Check size of types in CompileUnit.
+ const LVTypes *Types = CompileUnit->getTypes();
+ ASSERT_NE(Types, nullptr);
+ EXPECT_EQ(Types->size(), 8u);
+
+ const auto BoolType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "bool";
+ });
+ ASSERT_NE(BoolType, Types->end());
+ const auto IntType =
+ std::find_if(Types->begin(), Types->end(), [](const LVElement *elt) {
+ return elt->getName() == "int";
+ });
+ ASSERT_NE(IntType, Types->end());
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);
+ EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);
+ EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);
}
// Check the logical elements basic properties (MSVC library - Codeview).
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index c062c15481da9..6c53be959d951 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -155,6 +155,12 @@ void checkElementSelection(LVReader *Reader) {
ASSERT_NE(Element, nullptr);
EXPECT_NE(Element->getName().find("INTEGER"), StringRef::npos);
EXPECT_EQ(Element->getIsType(), 1);
+ // Underlying type is `int`
+ const LVElement *UnderlyingType =
+ static_cast<LVType *>(Element)->getUnderlyingType();
+ EXPECT_EQ(UnderlyingType->getIsType(), 1);
+ EXPECT_EQ(UnderlyingType->getBitSize(), 32u);
+ EXPECT_EQ(UnderlyingType->getStorageSizeInBytes(), 4u);
Element = MapElements[0x000000000f]; // 'movl %edx, %eax'
ASSERT_NE(Element, nullptr);
>From f1b83dd4b3ed285bc60910f69c4b98057f516d27 Mon Sep 17 00:00:00 2001
From: Javier Lopez-Gomez <javier.lopez.gomez at proton.me>
Date: Fri, 25 Apr 2025 16:27:25 +0200
Subject: [PATCH 2/2] [llvm-debuginfo-analyzer] Add support for parsing DWARF
DW_TAG_module
---
.../DebugInfo/LogicalView/Core/LVElement.h | 1 +
.../DebugInfo/LogicalView/Core/LVReader.h | 2 ++
.../llvm/DebugInfo/LogicalView/Core/LVScope.h | 19 +++++++++++++++++
.../DebugInfo/LogicalView/Core/LVScope.cpp | 18 +++++++++++++++-
.../LogicalView/Readers/LVDWARFReader.cpp | 3 +++
.../DebugInfo/LogicalView/DWARFReaderTest.cpp | 20 ++++++++++++++++++
.../Inputs/test-dwarf-clang-module.o | Bin 0 -> 960 bytes
7 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-module.o
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
index b2ef6579caf41..131078ea7d59b 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h
@@ -45,6 +45,7 @@ enum class LVSubclassID : unsigned char {
LV_SCOPE_NAMESPACE,
LV_SCOPE_ROOT,
LV_SCOPE_TEMPLATE_PACK,
+ LV_SCOPE_MODULE,
LV_SCOPE_LAST,
LV_SYMBOL_FIRST,
LV_SYMBOL,
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
index 9ce26398e48df..b0d8ff4952d79 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h
@@ -107,6 +107,7 @@ class LVReader {
LV_OBJECT_ALLOCATOR(ScopeNamespace)
LV_OBJECT_ALLOCATOR(ScopeRoot)
LV_OBJECT_ALLOCATOR(ScopeTemplatePack)
+ LV_OBJECT_ALLOCATOR(ScopeModule)
// Symbols allocator.
LV_OBJECT_ALLOCATOR(Symbol)
@@ -213,6 +214,7 @@ class LVReader {
LV_CREATE_OBJECT(ScopeNamespace)
LV_CREATE_OBJECT(ScopeRoot)
LV_CREATE_OBJECT(ScopeTemplatePack)
+ LV_CREATE_OBJECT(ScopeModule)
// Symbols creation.
LV_CREATE_OBJECT(Symbol)
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
index 1cf61d085d84f..23553297e54c2 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
@@ -57,6 +57,7 @@ enum class LVScopeKind {
IsTemplatePack,
IsTryBlock,
IsUnion,
+ IsModule,
LastEntry
};
using LVScopeKindSet = std::set<LVScopeKind>;
@@ -184,6 +185,7 @@ class LVScope : public LVElement {
KIND(LVScopeKind, IsTemplatePack);
KIND_1(LVScopeKind, IsTryBlock, IsBlock);
KIND_1(LVScopeKind, IsUnion, IsAggregate);
+ KIND_3(LVScopeKind, IsModule, CanHaveRanges, CanHaveLines, TransformName);
PROPERTY(Property, HasDiscriminator);
PROPERTY(Property, CanHaveRanges);
@@ -832,6 +834,23 @@ class LVScopeTemplatePack final : public LVScope {
void printExtra(raw_ostream &OS, bool Full = true) const override;
};
+// Class to represent a DWARF Module.
+class LVScopeModule final : public LVScope {
+public:
+ LVScopeModule() : LVScope() {
+ setIsModule();
+ setIsLexicalBlock();
+ }
+ LVScopeModule(const LVScopeModule &) = delete;
+ LVScopeModule &operator=(const LVScopeModule &) = delete;
+ ~LVScopeModule() = default;
+
+ // Returns true if current scope is logically equal to the given 'Scope'.
+ bool equals(const LVScope *Scope) const override;
+
+ void printExtra(raw_ostream &OS, bool Full = true) const override;
+};
+
} // end namespace logicalview
} // end namespace llvm
diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
index 8bbaf93db0caa..7ffeed8f18f8a 100644
--- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp
@@ -40,6 +40,7 @@ const char *const KindTemplateAlias = "TemplateAlias";
const char *const KindTemplatePack = "TemplatePack";
const char *const KindUndefined = "Undefined";
const char *const KindUnion = "Union";
+const char *const KindModule = "Module";
} // end anonymous namespace
//===----------------------------------------------------------------------===//
@@ -50,6 +51,8 @@ const char *LVScope::kind() const {
const char *Kind = KindUndefined;
if (getIsArray())
Kind = KindArray;
+ else if (getIsModule())
+ Kind = KindModule;
else if (getIsBlock())
Kind = KindBlock;
else if (getIsCallSite())
@@ -101,7 +104,8 @@ LVScopeDispatch LVScope::Dispatch = {
{LVScopeKind::IsTemplateAlias, &LVScope::getIsTemplateAlias},
{LVScopeKind::IsTemplatePack, &LVScope::getIsTemplatePack},
{LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},
- {LVScopeKind::IsUnion, &LVScope::getIsUnion}};
+ {LVScopeKind::IsUnion, &LVScope::getIsUnion},
+ {LVScopeKind::IsModule, &LVScope::getIsModule}};
void LVScope::addToChildren(LVElement *Element) {
if (!Children)
@@ -2107,3 +2111,15 @@ bool LVScopeTemplatePack::equals(const LVScope *Scope) const {
void LVScopeTemplatePack::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
}
+
+//===----------------------------------------------------------------------===//
+// DWARF module (DW_TAG_module).
+//===----------------------------------------------------------------------===//
+bool LVScopeModule::equals(const LVScope *Scope) const {
+ // For lexical blocks, LVScope::equals() compares the parent scope.
+ return LVScope::equals(Scope) && (Scope->getName() == getName());
+}
+
+void LVScopeModule::printExtra(raw_ostream &OS, bool Full) const {
+ OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
+}
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
index 269630896e077..0c49488614d36 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp
@@ -233,6 +233,9 @@ LVElement *LVDWARFReader::createElement(dwarf::Tag Tag) {
case dwarf::DW_TAG_GNU_template_parameter_pack:
CurrentScope = createScopeTemplatePack();
return CurrentScope;
+ case dwarf::DW_TAG_module:
+ CurrentScope = createScopeModule();
+ return CurrentScope;
default:
// Collect TAGs not implemented.
if (options().getInternalTag() && Tag)
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index 6c53be959d951..7362ea6468b61 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -30,6 +30,7 @@ extern const char *TestMainArgv0;
namespace {
const char *DwarfClang = "test-dwarf-clang.o";
+const char *DwarfClangModule = "test-dwarf-clang-module.o";
const char *DwarfGcc = "test-dwarf-gcc.o";
// Helper function to get the first compile unit.
@@ -124,6 +125,22 @@ void checkElementProperties(LVReader *Reader) {
ASSERT_EQ(Lines->size(), 0x12u);
}
+// Check the basic properties on parsed DW_TAG_module.
+void checkScopeModule(LVReader *Reader) {
+ LVScopeRoot *Root = Reader->getScopesRoot();
+ LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);
+
+ EXPECT_EQ(Root->getFileFormatName(), "Mach-O 64-bit x86-64");
+ EXPECT_EQ(Root->getName(), DwarfClangModule);
+
+ ASSERT_NE(CompileUnit->getChildren(), nullptr);
+ LVElement *FirstChild = *(CompileUnit->getChildren()->begin());
+ EXPECT_EQ(FirstChild->getIsScope(), 1);
+ LVScopeModule *Module = static_cast<LVScopeModule *>(FirstChild);
+ EXPECT_EQ(Module->getIsModule(), 1);
+ EXPECT_EQ(Module->getName(), "debugmodule");
+}
+
// Check the logical elements selection.
void checkElementSelection(LVReader *Reader) {
LVScopeRoot *Root = Reader->getScopesRoot();
@@ -270,6 +287,9 @@ void elementProperties(SmallString<128> &InputsDir) {
std::unique_ptr<LVReader> Reader =
createReader(ReaderHandler, InputsDir, DwarfClang);
checkElementProperties(Reader.get());
+
+ Reader = createReader(ReaderHandler, InputsDir, DwarfClangModule);
+ checkScopeModule(Reader.get());
}
// Logical elements selection.
diff --git a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-module.o b/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-module.o
new file mode 100644
index 0000000000000000000000000000000000000000..0cded9bfb37d1693729ab5a3ed263bfa6c57fa21
GIT binary patch
literal 960
zcmaiy-%A2P5Xa{{EkRlgA1Z<nBIuz!qrfl|f-?-1pzOz+XkKz~-ifzLg^&f&U)0~x
zU(sW4JrzVVcf06azXoP!=DRzeo4ecR_t(#907V5{gs(<0Nu#4JpnJ7feP1{=p_Qoz
zP1eW+ at +lJ0>UC~haX<I#TIswtuEUw+P3WVE9C<CH*>Bey&1TOS5MMvrJKCQ-;^iAc
z`GF at U_76y&X<s^|gn5!v5WMR^w<iV^$#Z$n+YIwMg7YBaQ=t2Ip55peE^dc;Z-TQe
zVgY|>2pK5le3oe&)Dq^c$^R;NoGwVv0z73_Sz)P|%I=3OIk(7OZWB1b5~%EM$VNl<
zIAj279P){s#C!@tG-%WV#=S=+fz-UG_%RZpk6lKmdvb%WDzRk at P^p|&(*vXDnvR{`
z%;Yjz&@5}v(YWJSu6AKH?6$@Ymupq0)wc{+E4aL6+C|Vnr)%TOu&!4R^^;2Jc=unx
zf!*zM7dn|n*R&mE;}~1$F?8{%FdOHj#nEZhY%ZInJ!v{7Q7Gc7D9Q($p+M)+mA~Hu
JK)#54<`)_HeKP<6
literal 0
HcmV?d00001
More information about the llvm-commits
mailing list