mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-02 15:51:54 +00:00
[DebugInfo] Added support for Checksum debug info feature.
Differential Revision: https://reviews.llvm.org/D27642 llvm-svn: 290514
This commit is contained in:
parent
2badac86bf
commit
144e1a2ef2
@ -3998,10 +3998,13 @@ DIFile
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
!0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
|
||||
!0 = !DIFile(filename: "path/to/file", directory: "/path/to/dir",
|
||||
checksumkind: CSK_MD5,
|
||||
checksum: "000102030405060708090a0b0c0d0e0f")
|
||||
|
||||
Files are sometimes used in ``scope:`` fields, and are the only valid target
|
||||
for ``file:`` fields.
|
||||
Valid values for ``checksumkind:`` field are: {CSK_None, CSK_MD5, CSK_SHA1}
|
||||
|
||||
.. _DIBasicType:
|
||||
|
||||
|
@ -233,7 +233,7 @@ enum MetadataCodes {
|
||||
METADATA_SUBRANGE = 13, // [distinct, count, lo]
|
||||
METADATA_ENUMERATOR = 14, // [distinct, value, name]
|
||||
METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc]
|
||||
METADATA_FILE = 16, // [distinct, filename, directory]
|
||||
METADATA_FILE = 16, // [distinct, filename, directory, checksumkind, checksum]
|
||||
METADATA_DERIVED_TYPE = 17, // [distinct, ...]
|
||||
METADATA_COMPOSITE_TYPE = 18, // [distinct, ...]
|
||||
METADATA_SUBROUTINE_TYPE = 19, // [distinct, flags, types, cc]
|
||||
|
@ -107,9 +107,14 @@ namespace llvm {
|
||||
DICompileUnit::DebugEmissionKind::FullDebug,
|
||||
uint64_t DWOId = 0, bool SplitDebugInlining = true);
|
||||
|
||||
/// Create a file descriptor to hold debugging information
|
||||
/// for a file.
|
||||
DIFile *createFile(StringRef Filename, StringRef Directory);
|
||||
/// Create a file descriptor to hold debugging information for a file.
|
||||
/// \param File File name.
|
||||
/// \param Dir Directory.
|
||||
/// \param CSKind Checksum kind (e.g. CSK_None, CSK_MD5, CSK_SHA1, etc.).
|
||||
/// \param Checksum Checksum data.
|
||||
DIFile *createFile(StringRef Filename, StringRef Directory,
|
||||
DIFile::ChecksumKind CSKind = DIFile::CSK_None,
|
||||
StringRef Checksum = StringRef());
|
||||
|
||||
/// Create a single enumerator value.
|
||||
DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
|
||||
|
@ -470,38 +470,62 @@ class DIFile : public DIScope {
|
||||
friend class LLVMContextImpl;
|
||||
friend class MDNode;
|
||||
|
||||
DIFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
|
||||
: DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
|
||||
public:
|
||||
enum ChecksumKind {
|
||||
CSK_None,
|
||||
CSK_MD5,
|
||||
CSK_SHA1,
|
||||
CSK_Last = CSK_SHA1 // Should be last enumeration.
|
||||
};
|
||||
|
||||
private:
|
||||
ChecksumKind CSKind;
|
||||
|
||||
DIFile(LLVMContext &C, StorageType Storage, ChecksumKind CSK,
|
||||
ArrayRef<Metadata *> Ops)
|
||||
: DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
|
||||
CSKind(CSK) {}
|
||||
~DIFile() = default;
|
||||
|
||||
static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
|
||||
StringRef Directory, StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
StringRef Directory, ChecksumKind CSK, StringRef CS,
|
||||
StorageType Storage, bool ShouldCreate = true) {
|
||||
return getImpl(Context, getCanonicalMDString(Context, Filename),
|
||||
getCanonicalMDString(Context, Directory), Storage,
|
||||
ShouldCreate);
|
||||
getCanonicalMDString(Context, Directory), CSK,
|
||||
getCanonicalMDString(Context, CS), Storage, ShouldCreate);
|
||||
}
|
||||
static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
|
||||
MDString *Directory, StorageType Storage,
|
||||
bool ShouldCreate = true);
|
||||
MDString *Directory, ChecksumKind CSK, MDString *CS,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
|
||||
TempDIFile cloneImpl() const {
|
||||
return getTemporary(getContext(), getFilename(), getDirectory());
|
||||
return getTemporary(getContext(), getFilename(), getDirectory(),
|
||||
getChecksumKind(), getChecksum());
|
||||
}
|
||||
|
||||
public:
|
||||
DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory),
|
||||
(Filename, Directory))
|
||||
DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory),
|
||||
(Filename, Directory))
|
||||
DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory,
|
||||
ChecksumKind CSK = CSK_None,
|
||||
StringRef CS = StringRef()),
|
||||
(Filename, Directory, CSK, CS))
|
||||
DEFINE_MDNODE_GET(DIFile, (MDString *Filename, MDString *Directory,
|
||||
ChecksumKind CSK = CSK_None,
|
||||
MDString *CS = nullptr),
|
||||
(Filename, Directory, CSK, CS))
|
||||
|
||||
TempDIFile clone() const { return cloneImpl(); }
|
||||
|
||||
StringRef getFilename() const { return getStringOperand(0); }
|
||||
StringRef getDirectory() const { return getStringOperand(1); }
|
||||
StringRef getChecksum() const { return getStringOperand(2); }
|
||||
ChecksumKind getChecksumKind() const { return CSKind; }
|
||||
StringRef getChecksumKindAsString() const;
|
||||
|
||||
MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
|
||||
MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
|
||||
MDString *getRawChecksum() const { return getOperandAs<MDString>(2); }
|
||||
|
||||
static ChecksumKind getChecksumKind(StringRef CSKindStr);
|
||||
|
||||
static bool classof(const Metadata *MD) {
|
||||
return MD->getMetadataID() == DIFileKind;
|
||||
|
@ -808,6 +808,12 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
StrVal.assign(Keyword.begin(), Keyword.end());
|
||||
return lltok::DIFlag;
|
||||
}
|
||||
|
||||
if (Keyword.startswith("CSK_")) {
|
||||
StrVal.assign(Keyword.begin(), Keyword.end());
|
||||
return lltok::ChecksumKind;
|
||||
}
|
||||
|
||||
if (Keyword == "NoDebug" || Keyword == "FullDebug" ||
|
||||
Keyword == "LineTablesOnly") {
|
||||
StrVal.assign(Keyword.begin(), Keyword.end());
|
||||
|
@ -3465,6 +3465,11 @@ struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> {
|
||||
MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {}
|
||||
};
|
||||
|
||||
struct ChecksumKindField : public MDFieldImpl<DIFile::ChecksumKind> {
|
||||
ChecksumKindField() : ImplTy(DIFile::CSK_None) {}
|
||||
ChecksumKindField(DIFile::ChecksumKind CSKind) : ImplTy(CSKind) {}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace llvm {
|
||||
@ -3742,6 +3747,20 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
|
||||
ChecksumKindField &Result) {
|
||||
if (Lex.getKind() != lltok::ChecksumKind)
|
||||
return TokError(
|
||||
"invalid checksum kind" + Twine(" '") + Lex.getStrVal() + "'");
|
||||
|
||||
DIFile::ChecksumKind CSKind = DIFile::getChecksumKind(Lex.getStrVal());
|
||||
|
||||
Result.assign(CSKind);
|
||||
Lex.Lex();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
template <class ParserTy>
|
||||
@ -3971,15 +3990,20 @@ bool LLParser::ParseDISubroutineType(MDNode *&Result, bool IsDistinct) {
|
||||
}
|
||||
|
||||
/// ParseDIFileType:
|
||||
/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir")
|
||||
/// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir"
|
||||
/// checksumkind: CSK_MD5,
|
||||
/// checksum: "000102030405060708090a0b0c0d0e0f")
|
||||
bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) {
|
||||
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
|
||||
REQUIRED(filename, MDStringField, ); \
|
||||
REQUIRED(directory, MDStringField, );
|
||||
REQUIRED(directory, MDStringField, ); \
|
||||
OPTIONAL(checksumkind, ChecksumKindField, ); \
|
||||
OPTIONAL(checksum, MDStringField, );
|
||||
PARSE_MD_FIELDS();
|
||||
#undef VISIT_MD_FIELDS
|
||||
|
||||
Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val));
|
||||
Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val,
|
||||
checksumkind.Val, checksum.Val));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -353,6 +353,7 @@ enum Kind {
|
||||
DwarfOp, // DW_OP_foo
|
||||
DIFlag, // DIFlagFoo
|
||||
DwarfMacinfo, // DW_MACINFO_foo
|
||||
ChecksumKind, // CSK_foo
|
||||
|
||||
// Type valued tokens (TyVal).
|
||||
Type,
|
||||
|
@ -815,13 +815,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
||||
}
|
||||
|
||||
case bitc::METADATA_FILE: {
|
||||
if (Record.size() != 3)
|
||||
if (Record.size() != 3 && Record.size() != 5)
|
||||
return error("Invalid record");
|
||||
|
||||
IsDistinct = Record[0];
|
||||
MetadataList.assignValue(
|
||||
GET_OR_DISTINCT(
|
||||
DIFile, (Context, getMDString(Record[1]), getMDString(Record[2]))),
|
||||
DIFile,
|
||||
(Context, getMDString(Record[1]), getMDString(Record[2]),
|
||||
Record.size() == 3 ? DIFile::CSK_None
|
||||
: static_cast<DIFile::ChecksumKind>(Record[3]),
|
||||
Record.size() == 3 ? nullptr : getMDString(Record[4]))),
|
||||
NextMetadataNo++);
|
||||
break;
|
||||
}
|
||||
|
@ -1515,6 +1515,8 @@ void ModuleBitcodeWriter::writeDIFile(const DIFile *N,
|
||||
Record.push_back(N->isDistinct());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawFilename()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawDirectory()));
|
||||
Record.push_back(N->getChecksumKind());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawChecksum()));
|
||||
|
||||
Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev);
|
||||
Record.clear();
|
||||
|
@ -1408,6 +1408,7 @@ struct MDFieldPrinter {
|
||||
}
|
||||
void printTag(const DINode *N);
|
||||
void printMacinfoType(const DIMacroNode *N);
|
||||
void printChecksumKind(const DIFile *N);
|
||||
void printString(StringRef Name, StringRef Value,
|
||||
bool ShouldSkipEmpty = true);
|
||||
void printMetadata(StringRef Name, const Metadata *MD,
|
||||
@ -1441,6 +1442,13 @@ void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) {
|
||||
Out << N->getMacinfoType();
|
||||
}
|
||||
|
||||
void MDFieldPrinter::printChecksumKind(const DIFile *N) {
|
||||
if (N->getChecksumKind() == DIFile::CSK_None)
|
||||
// Skip CSK_None checksum kind.
|
||||
return;
|
||||
Out << FS << "checksumkind: " << N->getChecksumKindAsString();
|
||||
}
|
||||
|
||||
void MDFieldPrinter::printString(StringRef Name, StringRef Value,
|
||||
bool ShouldSkipEmpty) {
|
||||
if (ShouldSkipEmpty && Value.empty())
|
||||
@ -1653,6 +1661,8 @@ static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *,
|
||||
/* ShouldSkipEmpty */ false);
|
||||
Printer.printString("directory", N->getDirectory(),
|
||||
/* ShouldSkipEmpty */ false);
|
||||
Printer.printChecksumKind(N);
|
||||
Printer.printString("checksum", N->getChecksum(), /* ShouldSkipEmpty */ true);
|
||||
Out << ")";
|
||||
}
|
||||
|
||||
|
@ -174,8 +174,9 @@ DIImportedEntity *DIBuilder::createImportedDeclaration(DIScope *Context,
|
||||
Context, Decl, Line, Name, AllImportedModules);
|
||||
}
|
||||
|
||||
DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory) {
|
||||
return DIFile::get(VMContext, Filename, Directory);
|
||||
DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory,
|
||||
DIFile::ChecksumKind CSKind, StringRef Checksum) {
|
||||
return DIFile::get(VMContext, Filename, Directory, CSKind, Checksum);
|
||||
}
|
||||
|
||||
DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val) {
|
||||
|
@ -347,14 +347,34 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
|
||||
DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
|
||||
}
|
||||
|
||||
static const char *ChecksumKindName[DIFile::CSK_Last + 1] = {
|
||||
"CSK_None",
|
||||
"CSK_MD5",
|
||||
"CSK_SHA1"
|
||||
};
|
||||
|
||||
DIFile::ChecksumKind DIFile::getChecksumKind(StringRef CSKindStr) {
|
||||
return StringSwitch<DIFile::ChecksumKind>(CSKindStr)
|
||||
.Case("CSK_MD5", DIFile::CSK_MD5)
|
||||
.Case("CSK_SHA1", DIFile::CSK_SHA1)
|
||||
.Default(DIFile::CSK_None);
|
||||
}
|
||||
|
||||
StringRef DIFile::getChecksumKindAsString() const {
|
||||
assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
|
||||
return ChecksumKindName[CSKind];
|
||||
}
|
||||
|
||||
DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
|
||||
MDString *Directory, StorageType Storage,
|
||||
MDString *Directory, DIFile::ChecksumKind CSKind,
|
||||
MDString *Checksum, StorageType Storage,
|
||||
bool ShouldCreate) {
|
||||
assert(isCanonical(Filename) && "Expected canonical MDString");
|
||||
assert(isCanonical(Directory) && "Expected canonical MDString");
|
||||
DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory));
|
||||
Metadata *Ops[] = {Filename, Directory};
|
||||
DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIFile, Ops);
|
||||
assert(isCanonical(Checksum) && "Expected canonical MDString");
|
||||
DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CSKind, Checksum));
|
||||
Metadata *Ops[] = {Filename, Directory, Checksum};
|
||||
DEFINE_GETIMPL_STORE(DIFile, (CSKind), Ops);
|
||||
}
|
||||
|
||||
DICompileUnit *DICompileUnit::getImpl(
|
||||
|
@ -503,17 +503,26 @@ template <> struct MDNodeKeyImpl<DISubroutineType> {
|
||||
template <> struct MDNodeKeyImpl<DIFile> {
|
||||
MDString *Filename;
|
||||
MDString *Directory;
|
||||
DIFile::ChecksumKind CSKind;
|
||||
MDString *Checksum;
|
||||
|
||||
MDNodeKeyImpl(MDString *Filename, MDString *Directory)
|
||||
: Filename(Filename), Directory(Directory) {}
|
||||
MDNodeKeyImpl(MDString *Filename, MDString *Directory,
|
||||
DIFile::ChecksumKind CSKind, MDString *Checksum)
|
||||
: Filename(Filename), Directory(Directory), CSKind(CSKind),
|
||||
Checksum(Checksum) {}
|
||||
MDNodeKeyImpl(const DIFile *N)
|
||||
: Filename(N->getRawFilename()), Directory(N->getRawDirectory()) {}
|
||||
: Filename(N->getRawFilename()), Directory(N->getRawDirectory()),
|
||||
CSKind(N->getChecksumKind()), Checksum(N->getRawChecksum()) {}
|
||||
|
||||
bool isKeyOf(const DIFile *RHS) const {
|
||||
return Filename == RHS->getRawFilename() &&
|
||||
Directory == RHS->getRawDirectory();
|
||||
Directory == RHS->getRawDirectory() &&
|
||||
CSKind == RHS->getChecksumKind() &&
|
||||
Checksum == RHS->getRawChecksum();
|
||||
}
|
||||
unsigned getHashValue() const {
|
||||
return hash_combine(Filename, Directory, CSKind, Checksum);
|
||||
}
|
||||
unsigned getHashValue() const { return hash_combine(Filename, Directory); }
|
||||
};
|
||||
|
||||
template <> struct MDNodeKeyImpl<DISubprogram> {
|
||||
|
@ -961,6 +961,8 @@ void Verifier::visitDISubroutineType(const DISubroutineType &N) {
|
||||
|
||||
void Verifier::visitDIFile(const DIFile &N) {
|
||||
AssertDI(N.getTag() == dwarf::DW_TAG_file_type, "invalid tag", &N);
|
||||
AssertDI((N.getChecksumKind() != DIFile::CSK_None ||
|
||||
N.getChecksum().empty()), "invalid checksum kind", &N);
|
||||
}
|
||||
|
||||
void Verifier::visitDICompileUnit(const DICompileUnit &N) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||
; RUN: verify-uselistorder %s
|
||||
|
||||
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34}
|
||||
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !33}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37}
|
||||
|
||||
; CHECK: !0 = !DISubrange(count: 3)
|
||||
; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
|
||||
@ -79,3 +79,9 @@
|
||||
!32 = distinct !{!31}
|
||||
!33 = !DIMacroFile(line: 9, file: !14, nodes: !32)
|
||||
!34 = !DIMacroFile(type: DW_MACINFO_start_file, line: 11, file: !14)
|
||||
|
||||
; CHECK-NEXT: !32 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "000102030405060708090a0b0c0d0e0f")
|
||||
; CHECK-NEXT: !33 = !DIFile(filename: "file", directory: "dir")
|
||||
!35 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "000102030405060708090a0b0c0d0e0f")
|
||||
!36 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None)
|
||||
!37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None, checksum: "")
|
@ -1360,15 +1360,21 @@ typedef MetadataTest DIFileTest;
|
||||
TEST_F(DIFileTest, get) {
|
||||
StringRef Filename = "file";
|
||||
StringRef Directory = "dir";
|
||||
auto *N = DIFile::get(Context, Filename, Directory);
|
||||
DIFile::ChecksumKind CSKind = DIFile::CSK_MD5;
|
||||
StringRef Checksum = "000102030405060708090a0b0c0d0e0f";
|
||||
auto *N = DIFile::get(Context, Filename, Directory, CSKind, Checksum);
|
||||
|
||||
EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag());
|
||||
EXPECT_EQ(Filename, N->getFilename());
|
||||
EXPECT_EQ(Directory, N->getDirectory());
|
||||
EXPECT_EQ(N, DIFile::get(Context, Filename, Directory));
|
||||
EXPECT_EQ(CSKind, N->getChecksumKind());
|
||||
EXPECT_EQ(Checksum, N->getChecksum());
|
||||
EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, CSKind, Checksum));
|
||||
|
||||
EXPECT_NE(N, DIFile::get(Context, "other", Directory));
|
||||
EXPECT_NE(N, DIFile::get(Context, Filename, "other"));
|
||||
EXPECT_NE(N, DIFile::get(Context, "other", Directory, CSKind, Checksum));
|
||||
EXPECT_NE(N, DIFile::get(Context, Filename, "other", CSKind, Checksum));
|
||||
EXPECT_NE(N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1, Checksum));
|
||||
EXPECT_NE(N, DIFile::get(Context, Filename, Directory));
|
||||
|
||||
TempDIFile Temp = N->clone();
|
||||
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user