Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -141,11 +141,10 @@ /// Create a file descriptor to hold debugging information for a file. /// \param Filename File name. /// \param Directory 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()); + /// \param Checksum Checksum kind (e.g. CSK_MD5, CSK_SHA1, etc.) and value. + DIFile * + createFile(StringRef Filename, StringRef Directory, + Optional> Checksum = None); /// Create debugging information entry for a macro. /// \param Parent Macro parent (could be nullptr). Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -499,63 +499,93 @@ friend class MDNode; public: - // These values must be explictly set, as they end up in the final object - // file. + /// Which algorithm (e.g. MD5) a checksum was generated with. + /// + /// The encoding is explicit because it is used directly in Bitcode. The + /// value 0 is reserved to indicate the absence of a checksum in Bitcode. enum ChecksumKind { - CSK_None = 0, + // The first variant was originally CSK_None, encoded as 0. The new + // internal representation removes the need for this by wrapping the + // ChecksumInfo in an Optional, but to preserve Bitcode compatibility the 0 + // encoding is reserved. CSK_MD5 = 1, CSK_SHA1 = 2, CSK_Last = CSK_SHA1 // Should be last enumeration. }; + /// A single checksum, represented by a \a Kind and a \a Value (a string). + template + struct ChecksumInfo { + /// The kind of checksum which \a Value encodes. + ChecksumKind Kind; + /// The string value of the checksum. + T Value; + + ChecksumInfo(ChecksumKind Kind, T Value) : Kind(Kind), Value(Value) { } + ~ChecksumInfo() = default; + bool operator==(const ChecksumInfo &X) const { + return Kind == X.Kind && Value == X.Value; + } + bool operator!=(const ChecksumInfo &X) const { return !(*this == X); } + StringRef getKindAsString() const { return getChecksumKindAsString(Kind); } + }; + private: - ChecksumKind CSKind; + Optional> Checksum; - DIFile(LLVMContext &C, StorageType Storage, ChecksumKind CSK, + DIFile(LLVMContext &C, StorageType Storage, + Optional> CS, ArrayRef Ops) : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops), - CSKind(CSK) {} + Checksum(CS) {} ~DIFile() = default; static DIFile *getImpl(LLVMContext &Context, StringRef Filename, - StringRef Directory, ChecksumKind CSK, StringRef CS, + StringRef Directory, + Optional> CS, StorageType Storage, bool ShouldCreate = true) { + Optional> MDChecksum; + if (CS) + MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value)); return getImpl(Context, getCanonicalMDString(Context, Filename), - getCanonicalMDString(Context, Directory), CSK, - getCanonicalMDString(Context, CS), Storage, ShouldCreate); + getCanonicalMDString(Context, Directory), MDChecksum, + Storage, ShouldCreate); } static DIFile *getImpl(LLVMContext &Context, MDString *Filename, - MDString *Directory, ChecksumKind CSK, MDString *CS, + MDString *Directory, + Optional> CS, StorageType Storage, bool ShouldCreate = true); TempDIFile cloneImpl() const { return getTemporary(getContext(), getFilename(), getDirectory(), - getChecksumKind(), getChecksum()); + getChecksum()); } public: DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory, - ChecksumKind CSK = CSK_None, - StringRef CS = StringRef()), - (Filename, Directory, CSK, CS)) + Optional> CS = None), + (Filename, Directory, CS)) DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory, - ChecksumKind CSK = CSK_None, - MDString *CS = nullptr), - (Filename, Directory, CSK, CS)) + Optional> CS = None), + (Filename, Directory, 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; + Optional> getChecksum() const { + Optional> StringRefChecksum; + if (Checksum) + StringRefChecksum.emplace(Checksum->Kind, Checksum->Value->getString()); + return StringRefChecksum; + } MDString *getRawFilename() const { return getOperandAs(0); } MDString *getRawDirectory() const { return getOperandAs(1); } - MDString *getRawChecksum() const { return getOperandAs(2); } + Optional> getRawChecksum() const { return Checksum; } - static ChecksumKind getChecksumKind(StringRef CSKindStr); + static StringRef getChecksumKindAsString(ChecksumKind CSKind); + static Optional getChecksumKind(StringRef CSKindStr); static bool classof(const Metadata *MD) { return MD->getMetadataID() == DIFileKind; Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -3612,7 +3612,6 @@ }; struct ChecksumKindField : public MDFieldImpl { - ChecksumKindField() : ImplTy(DIFile::CSK_None) {} ChecksumKindField(DIFile::ChecksumKind CSKind) : ImplTy(CSKind) {} }; @@ -3976,13 +3975,14 @@ template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, ChecksumKindField &Result) { - if (Lex.getKind() != lltok::ChecksumKind) + Optional CSKind = + DIFile::getChecksumKind(Lex.getStrVal()); + + if (Lex.getKind() != lltok::ChecksumKind || !CSKind) return TokError( "invalid checksum kind" + Twine(" '") + Lex.getStrVal() + "'"); - DIFile::ChecksumKind CSKind = DIFile::getChecksumKind(Lex.getStrVal()); - - Result.assign(CSKind); + Result.assign(*CSKind); Lex.Lex(); return false; } @@ -4247,16 +4247,25 @@ /// checksumkind: CSK_MD5, /// checksum: "000102030405060708090a0b0c0d0e0f") bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { + // The default constructed value for checksumkind is required, but will never + // be used, as the parser checks if the field was actually Seen before using + // the Val. #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(filename, MDStringField, ); \ REQUIRED(directory, MDStringField, ); \ - OPTIONAL(checksumkind, ChecksumKindField, ); \ + OPTIONAL(checksumkind, ChecksumKindField, (DIFile::CSK_MD5)); \ OPTIONAL(checksum, MDStringField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS + Optional> OptChecksum; + if (checksumkind.Seen && checksum.Seen) + OptChecksum.emplace(checksumkind.Val, checksum.Val); + else if (checksumkind.Seen || checksum.Seen) + return Lex.Error("'checksumkind' and 'checksum' must be provided together"); + Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val, - checksumkind.Val, checksum.Val)); + OptChecksum)); return false; } Index: lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- lib/Bitcode/Reader/MetadataLoader.cpp +++ lib/Bitcode/Reader/MetadataLoader.cpp @@ -1354,13 +1354,20 @@ return error("Invalid record"); IsDistinct = Record[0]; + Optional> Checksum; + // The BitcodeWriter writes null bytes into Record[3:4] when the Checksum + // is not present. This matches up with the old internal representation, + // and the old encoding for CSK_None in the ChecksumKind. The new + // representation reserves the value 0 in the ChecksumKind to continue to + // encode None in a backwards-compatible way. + if (Record.size() == 5 && Record[3] && Record[4]) + Checksum.emplace(static_cast(Record[3]), + getMDString(Record[4])); MetadataList.assignValue( GET_OR_DISTINCT( DIFile, (Context, getMDString(Record[1]), getMDString(Record[2]), - Record.size() == 3 ? DIFile::CSK_None - : static_cast(Record[3]), - Record.size() == 3 ? nullptr : getMDString(Record[4]))), + Checksum)), NextMetadataNo); NextMetadataNo++; break; Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1551,8 +1551,15 @@ 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())); + if (N->getRawChecksum()) { + Record.push_back(N->getRawChecksum()->Kind); + Record.push_back(VE.getMetadataOrNullID(N->getRawChecksum()->Value)); + } else { + // Maintain backwards compatibility with the old internal representation of + // CSK_None in ChecksumKind by writing nulls here when Checksum is None. + Record.push_back(0); + Record.push_back(VE.getMetadataOrNullID(nullptr)); + } Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev); Record.clear(); Index: lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -165,14 +165,21 @@ auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId)); if (Insertion.second) { // We have to compute the full filepath and emit a .cv_file directive. - std::string Checksum = fromHex(F->getChecksum()); - void *CKMem = OS.getContext().allocate(Checksum.size(), 1); - memcpy(CKMem, Checksum.data(), Checksum.size()); - ArrayRef ChecksumAsBytes(reinterpret_cast(CKMem), - Checksum.size()); - DIFile::ChecksumKind ChecksumKind = F->getChecksumKind(); + ArrayRef ChecksumAsBytes; + FileChecksumKind CSKind = FileChecksumKind::None; + if (F->getChecksum()) { + std::string Checksum = fromHex(F->getChecksum()->Value); + void *CKMem = OS.getContext().allocate(Checksum.size(), 1); + memcpy(CKMem, Checksum.data(), Checksum.size()); + ChecksumAsBytes = ArrayRef( + reinterpret_cast(CKMem), Checksum.size()); + switch (F->getChecksum()->Kind) { + case DIFile::CSK_MD5: CSKind = FileChecksumKind::MD5; break; + case DIFile::CSK_SHA1: CSKind = FileChecksumKind::SHA1; break; + } + } bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes, - static_cast(ChecksumKind)); + static_cast(CSKind)); (void)Success; assert(Success && ".cv_file directive failed"); } Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -280,15 +280,16 @@ MD5::MD5Result *DwarfUnit::getMD5AsBytes(const DIFile *File) { assert(File); - if (File->getChecksumKind() != DIFile::CSK_MD5) + Optional> Checksum = File->getChecksum(); + if (!Checksum || Checksum->Kind != DIFile::CSK_MD5) return nullptr; // Convert the string checksum to an MD5Result for the streamer. // The verifier validates the checksum so we assume it's okay. // An MD5 checksum is 16 bytes. - std::string Checksum = fromHex(File->getChecksum()); + std::string ChecksumString = fromHex(Checksum->Value); void *CKMem = Asm->OutStreamer->getContext().allocate(16, 1); - memcpy(CKMem, Checksum.data(), 16); + memcpy(CKMem, ChecksumString.data(), 16); return reinterpret_cast(CKMem); } Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -1453,7 +1453,7 @@ void printTag(const DINode *N); void printMacinfoType(const DIMacroNode *N); - void printChecksumKind(const DIFile *N); + void printChecksum(const DIFile::ChecksumInfo &N); void printString(StringRef Name, StringRef Value, bool ShouldSkipEmpty = true); void printMetadata(StringRef Name, const Metadata *MD, @@ -1488,11 +1488,10 @@ 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::printChecksum( + const DIFile::ChecksumInfo &Checksum) { + Out << FS << "checksumkind: " << Checksum.getKindAsString(); + printString("checksum", Checksum.Value, /* ShouldSkipEmpty */ false); } void MDFieldPrinter::printString(StringRef Name, StringRef Value, @@ -1721,8 +1720,9 @@ /* ShouldSkipEmpty */ false); Printer.printString("directory", N->getDirectory(), /* ShouldSkipEmpty */ false); - Printer.printChecksumKind(N); - Printer.printString("checksum", N->getChecksum(), /* ShouldSkipEmpty */ true); + // Print all values for checksum together, or not at all. + if (N->getChecksum()) + Printer.printChecksum(*N->getChecksum()); Out << ")"; } Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -204,8 +204,8 @@ } DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory, - DIFile::ChecksumKind CSKind, StringRef Checksum) { - return DIFile::get(VMContext, Filename, Directory, CSKind, Checksum); + Optional> CS) { + return DIFile::get(VMContext, Filename, Directory, CS); } DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber, Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -394,34 +394,36 @@ // FIXME: Implement this string-enum correspondence with a .def file and macros, // so that the association is explicit rather than implied. -static const char *ChecksumKindName[DIFile::CSK_Last + 1] = { - "CSK_None", +static const char *ChecksumKindName[DIFile::CSK_Last] = { "CSK_MD5", "CSK_SHA1" }; -DIFile::ChecksumKind DIFile::getChecksumKind(StringRef CSKindStr) { - return StringSwitch(CSKindStr) - .Case("CSK_MD5", DIFile::CSK_MD5) - .Case("CSK_SHA1", DIFile::CSK_SHA1) - .Default(DIFile::CSK_None); +StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) { + assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind"); + // The first space was originally the CSK_None variant, which is now + // obsolete, but the space is still reserved in ChecksumKind, so we account + // for it here. + return ChecksumKindName[CSKind - 1]; } -StringRef DIFile::getChecksumKindAsString() const { - assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind"); - return ChecksumKindName[CSKind]; +Optional DIFile::getChecksumKind(StringRef CSKindStr) { + return StringSwitch>(CSKindStr) + .Case("CSK_MD5", DIFile::CSK_MD5) + .Case("CSK_SHA1", DIFile::CSK_SHA1) + .Default(None); } DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename, - MDString *Directory, DIFile::ChecksumKind CSKind, - MDString *Checksum, StorageType Storage, - bool ShouldCreate) { + MDString *Directory, + Optional> CS, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Filename) && "Expected canonical MDString"); assert(isCanonical(Directory) && "Expected canonical MDString"); - 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); + assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString"); + DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS)); + Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr}; + DEFINE_GETIMPL_STORE(DIFile, (CS), Ops); } DICompileUnit *DICompileUnit::getImpl( @@ -894,4 +896,3 @@ Metadata *Ops[] = { File, Elements }; DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops); } - Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -574,26 +574,25 @@ template <> struct MDNodeKeyImpl { MDString *Filename; MDString *Directory; - DIFile::ChecksumKind CSKind; - MDString *Checksum; + Optional> Checksum; MDNodeKeyImpl(MDString *Filename, MDString *Directory, - DIFile::ChecksumKind CSKind, MDString *Checksum) - : Filename(Filename), Directory(Directory), CSKind(CSKind), - Checksum(Checksum) {} + Optional> Checksum) + : Filename(Filename), Directory(Directory), Checksum(Checksum) {} MDNodeKeyImpl(const DIFile *N) : Filename(N->getRawFilename()), Directory(N->getRawDirectory()), - CSKind(N->getChecksumKind()), Checksum(N->getRawChecksum()) {} + Checksum(N->getRawChecksum()) {} bool isKeyOf(const DIFile *RHS) const { return Filename == RHS->getRawFilename() && Directory == RHS->getRawDirectory() && - CSKind == RHS->getChecksumKind() && Checksum == RHS->getRawChecksum(); } unsigned getHashValue() const { - return hash_combine(Filename, Directory, CSKind, Checksum); + if (Checksum) + return hash_combine(Filename, Directory, Checksum->Kind, Checksum->Value); + return hash_combine(Filename, Directory); } }; Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -988,23 +988,23 @@ void Verifier::visitDIFile(const DIFile &N) { AssertDI(N.getTag() == dwarf::DW_TAG_file_type, "invalid tag", &N); - AssertDI(N.getChecksumKind() <= DIFile::CSK_Last, "invalid checksum kind", - &N); - size_t Size; - switch (N.getChecksumKind()) { - case DIFile::CSK_None: - Size = 0; - break; - case DIFile::CSK_MD5: - Size = 32; - break; - case DIFile::CSK_SHA1: - Size = 40; - break; + Optional> Checksum = N.getChecksum(); + if (Checksum) { + AssertDI(Checksum->Kind <= DIFile::ChecksumKind::CSK_Last, + "invalid checksum kind", &N); + size_t Size; + switch (Checksum->Kind) { + case DIFile::CSK_MD5: + Size = 32; + break; + case DIFile::CSK_SHA1: + Size = 40; + break; + } + AssertDI(Checksum->Value.size() == Size, "invalid checksum length", &N); + AssertDI(Checksum->Value.find_if_not(llvm::isHexDigit) == StringRef::npos, + "invalid checksum", &N); } - AssertDI(N.getChecksum().size() == Size, "invalid checksum length", &N); - AssertDI(N.getChecksum().find_if_not(llvm::isHexDigit) == StringRef::npos, - "invalid checksum", &N); } void Verifier::visitDICompileUnit(const DICompileUnit &N) { Index: test/Assembler/debug-info.ll =================================================================== --- test/Assembler/debug-info.ll +++ test/Assembler/debug-info.ll @@ -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, !32, !33, !34, !35, !36} -!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, !38, !39, !40} +; 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, !34, !35} +!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, !38} ; CHECK: !0 = !DISubrange(count: 3) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -81,14 +81,11 @@ !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: "") -; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !14, size: 64) -; CHECK-NEXT: !35 = !DIDerivedType(tag: DW_TAG_member, scope: !34, baseType: !36, size: 64, align: 64, flags: DIFlagArtificial) -; CHECK-NEXT: !36 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) -!38 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !16, size: 64, discriminator: !39) -!39 = !DIDerivedType(tag: DW_TAG_member, scope: !38, baseType: !40, size: 64, align: 64, flags: DIFlagArtificial) -!40 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) +; CHECK-NEXT: !33 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !14, size: 64) +; CHECK-NEXT: !34 = !DIDerivedType(tag: DW_TAG_member, scope: !33, baseType: !35, size: 64, align: 64, flags: DIFlagArtificial) +; CHECK-NEXT: !35 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) +!36 = !DICompositeType(tag: DW_TAG_variant_part, name: "A", scope: !16, size: 64, discriminator: !37) +!37 = !DIDerivedType(tag: DW_TAG_member, scope: !36, baseType: !38, size: 64, align: 64, flags: DIFlagArtificial) +!38 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) Index: test/Bitcode/upgrade-dbg-checksum.ll =================================================================== --- /dev/null +++ test/Bitcode/upgrade-dbg-checksum.ll @@ -0,0 +1,47 @@ +; Test that DIFile(checksumkind, checksum) representation in Bitcode does +; not change. +; +; RUN: llvm-dis < %s.bc | FileCheck %s +; RUN: verify-uselistorder < %s.bc + +; ModuleID = 'upgrade-dbg-checksum.c' +source_filename = "upgrade-dbg-checksum.c" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = common global i32 0, align 4, !dbg !0 +@b = common global i32 0, align 4, !dbg !6 + +; Function Attrs: noinline nounwind optnone uwtable +define i32 @f() #0 !dbg !15 { + ret i32 42, !dbg !18 +} + +attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +!0 = !DIGlobalVariableExpression(var: !1) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !10, line: 1, type: !9, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 5.0.1 (tags/RELEASE_501/final)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +; CHECK: !DIFile(filename: "upgrade-dbg-checksum.c", directory: "/home/slinder1/llvm/test/Bitcode") +!3 = !DIFile(filename: "upgrade-dbg-checksum.c", directory: "/home/slinder1/llvm/test/Bitcode", checksumkind: CSK_None, checksum: "") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7) +!7 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !8, line: 1, type: !9, isLocal: false, isDefinition: true) +; CHECK: !DIFile(filename: "./b.h", directory: "/home/slinder1/llvm/test/Bitcode", checksumkind: CSK_MD5, checksum: "595f44fec1e92a71d3e9e77456ba80d1") +!8 = !DIFile(filename: "./b.h", directory: "/home/slinder1/llvm/test/Bitcode", checksumkind: CSK_MD5, checksum: "595f44fec1e92a71d3e9e77456ba80d1") +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +; CHECK: !DIFile(filename: "./a.h", directory: "/home/slinder1/llvm/test/Bitcode", checksumkind: CSK_SHA1, checksum: "d5db29cd03a2ed055086cef9c31c252b4587d6d0") +!10 = !DIFile(filename: "./a.h", directory: "/home/slinder1/llvm/test/Bitcode", checksumkind: CSK_SHA1, checksum: "d5db29cd03a2ed055086cef9c31c252b4587d6d0") +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 5.0.1 (tags/RELEASE_501/final)"} +!15 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 3, type: !16, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: false, unit: !2, variables: !4) +!16 = !DISubroutineType(types: !17) +!17 = !{!9} +!18 = !DILocation(line: 4, column: 3, scope: !15) Index: test/Verifier/DIFile.ll =================================================================== --- test/Verifier/DIFile.ll +++ test/Verifier/DIFile.ll @@ -1,7 +1,6 @@ ; RUN: llvm-as -disable-output < %s 2>&1 | FileCheck %s ; The lengths for None and MD5 are wrong; SHA1 has a non-hex digit. -; CHECK: invalid checksum length ; CHECK: invalid checksum{{$}} ; CHECK: invalid checksum length ; CHECK: warning: ignoring invalid debug info in @@ -16,7 +15,7 @@ !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "t1", scope: !2, file: !10, line: 1, type: !9, isLocal: false, isDefinition: true) !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0 (trunk 322159)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) -!3 = !DIFile(filename: "t.c", directory: "/scratch", checksumkind: CSK_None, checksum: "00") +!3 = !DIFile(filename: "t.c", directory: "/scratch") !4 = !{} !5 = !{!0, !6} !6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) Index: unittests/IR/MetadataTest.cpp =================================================================== --- unittests/IR/MetadataTest.cpp +++ unittests/IR/MetadataTest.cpp @@ -1447,21 +1447,22 @@ TEST_F(DIFileTest, get) { StringRef Filename = "file"; StringRef Directory = "dir"; - DIFile::ChecksumKind CSKind = DIFile::CSK_MD5; - StringRef Checksum = "000102030405060708090a0b0c0d0e0f"; - auto *N = DIFile::get(Context, Filename, Directory, CSKind, Checksum); + DIFile::ChecksumKind CSKind = DIFile::ChecksumKind::CSK_MD5; + StringRef ChecksumString = "000102030405060708090a0b0c0d0e0f"; + DIFile::ChecksumInfo Checksum(CSKind, ChecksumString); + auto *N = DIFile::get(Context, Filename, Directory, Checksum); EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag()); EXPECT_EQ(Filename, N->getFilename()); EXPECT_EQ(Directory, N->getDirectory()); - EXPECT_EQ(CSKind, N->getChecksumKind()); EXPECT_EQ(Checksum, N->getChecksum()); - EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, CSKind, Checksum)); + EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum)); - 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, "other", Directory, Checksum)); + EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum)); + DIFile::ChecksumInfo OtherChecksum(DIFile::ChecksumKind::CSK_SHA1, ChecksumString); EXPECT_NE( - N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1, Checksum)); + N, DIFile::get(Context, Filename, Directory, OtherChecksum)); EXPECT_NE(N, DIFile::get(Context, Filename, Directory)); TempDIFile Temp = N->clone();