Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -598,10 +598,11 @@ private: Optional> Checksum; - Optional Source; + /// An optional source. A nullptr means None. + MDString *Source; DIFile(LLVMContext &C, StorageType Storage, - Optional> CS, Optional Src, + Optional> CS, MDString *Src, ArrayRef Ops); ~DIFile() = default; @@ -613,17 +614,15 @@ Optional> MDChecksum; if (CS) MDChecksum.emplace(CS->Kind, getCanonicalMDString(Context, CS->Value)); - return getImpl( - Context, getCanonicalMDString(Context, Filename), - getCanonicalMDString(Context, Directory), MDChecksum, - Source ? Optional(getCanonicalMDString(Context, *Source)) - : None, - Storage, ShouldCreate); + return getImpl(Context, getCanonicalMDString(Context, Filename), + getCanonicalMDString(Context, Directory), MDChecksum, + Source ? getCanonicalMDString(Context, *Source) : nullptr, + Storage, ShouldCreate); } static DIFile *getImpl(LLVMContext &Context, MDString *Filename, MDString *Directory, Optional> CS, - Optional Source, StorageType Storage, + MDString *Source, StorageType Storage, bool ShouldCreate = true); TempDIFile cloneImpl() const { @@ -640,7 +639,7 @@ DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory, Optional> CS = None, - Optional Source = None), + MDString *Source = nullptr), (Filename, Directory, CS, Source)) TempDIFile clone() const { return cloneImpl(); } @@ -654,13 +653,13 @@ return StringRefChecksum; } Optional getSource() const { - return Source ? Optional((*Source)->getString()) : None; + return Source ? Optional(Source->getString()) : None; } MDString *getRawFilename() const { return getOperandAs(0); } MDString *getRawDirectory() const { return getOperandAs(1); } Optional> getRawChecksum() const { return Checksum; } - Optional getRawSource() const { return Source; } + MDString *getRawSource() const { return Source; } static StringRef getChecksumKindAsString(ChecksumKind CSKind); static Optional getChecksumKind(StringRef CSKindStr); Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4995,11 +4995,11 @@ else if (checksumkind.Seen || checksum.Seen) return Lex.Error("'checksumkind' and 'checksum' must be provided together"); - Optional OptSource; + MDString *Source = nullptr; if (source.Seen) - OptSource = source.Val; - Result = GET_OR_DISTINCT(DIFile, (Context, filename.Val, directory.Val, - OptChecksum, OptSource)); + Source = source.Val; + Result = GET_OR_DISTINCT( + DIFile, (Context, filename.Val, directory.Val, OptChecksum, Source)); return false; } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1620,11 +1620,10 @@ Checksum.emplace(static_cast(Record[3]), getMDString(Record[4])); MetadataList.assignValue( - GET_OR_DISTINCT( - DIFile, - (Context, getMDString(Record[1]), getMDString(Record[2]), Checksum, - Record.size() > 5 ? Optional(getMDString(Record[5])) - : None)), + GET_OR_DISTINCT(DIFile, + (Context, getMDString(Record[1]), + getMDString(Record[2]), Checksum, + Record.size() > 5 ? getMDString(Record[5]) : nullptr)), NextMetadataNo); NextMetadataNo++; break; Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1808,7 +1808,7 @@ } auto Source = N->getRawSource(); if (Source) - Record.push_back(VE.getMetadataOrNullID(*Source)); + Record.push_back(VE.getMetadataOrNullID(Source)); Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev); Record.clear(); Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -798,7 +798,7 @@ } DIFile::DIFile(LLVMContext &C, StorageType Storage, - Optional> CS, Optional Src, + Optional> CS, MDString *Src, ArrayRef Ops) : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops), Checksum(CS), Source(Src) {} @@ -830,15 +830,14 @@ DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename, MDString *Directory, Optional> CS, - Optional Source, StorageType Storage, + MDString *Source, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Filename) && "Expected canonical MDString"); assert(isCanonical(Directory) && "Expected canonical MDString"); assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString"); - assert((!Source || isCanonical(*Source)) && "Expected canonical MDString"); + assert((!Source || isCanonical(Source)) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source)); - Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, - Source.value_or(nullptr)}; + Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source}; DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops); } DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage, Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -668,11 +668,11 @@ MDString *Filename; MDString *Directory; Optional> Checksum; - Optional Source; + MDString *Source; MDNodeKeyImpl(MDString *Filename, MDString *Directory, Optional> Checksum, - Optional Source) + MDString *Source) : Filename(Filename), Directory(Directory), Checksum(Checksum), Source(Source) {} MDNodeKeyImpl(const DIFile *N) @@ -687,8 +687,7 @@ unsigned getHashValue() const { return hash_combine(Filename, Directory, Checksum ? Checksum->Kind : 0, - Checksum ? Checksum->Value : nullptr, - Source.value_or(nullptr)); + Checksum ? Checksum->Value : nullptr, Source); } }; Index: llvm/unittests/IR/DebugInfoTest.cpp =================================================================== --- llvm/unittests/IR/DebugInfoTest.cpp +++ llvm/unittests/IR/DebugInfoTest.cpp @@ -190,6 +190,24 @@ EXPECT_TRUE(isa(DVIs[0]->getValue(0))); } +TEST(DIBuiler, CreateFile) { + LLVMContext Ctx; + std::unique_ptr M(new Module("MyModule", Ctx)); + DIBuilder DIB(*M); + + DIFile *F = DIB.createFile("main.c", "/"); + EXPECT_EQ(None, F->getSource()); + + Optional> Checksum = None; + F = DIB.createFile("main.c", "/", Checksum, /*Source=*/None); + EXPECT_EQ(None, F->getSource()); + + // Test that passing an empty string gives the same result. + F = DIB.createFile("main.c", "/", Checksum, + /*Source=*/Optional("")); + EXPECT_EQ(None, F->getSource()); +} + TEST(DIBuilder, CreateFortranArrayTypeWithAttributes) { LLVMContext Ctx; std::unique_ptr M(new Module("MyModule", Ctx)); Index: llvm/unittests/IR/MetadataTest.cpp =================================================================== --- llvm/unittests/IR/MetadataTest.cpp +++ llvm/unittests/IR/MetadataTest.cpp @@ -2221,6 +2221,20 @@ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } +TEST_F(DIFileTest, EmptySource) { + DIFile *N = DIFile::get(Context, "file", "dir"); + EXPECT_EQ(None, N->getSource()); + + Optional> Checksum = None; + N = DIFile::get(Context, "file", "dir", Checksum, /*Source=*/None); + EXPECT_EQ(None, N->getSource()); + + // Test that passing an empty string gives the same result. + N = DIFile::get(Context, "file", "dir", Checksum, + /*Source=*/Optional("")); + EXPECT_EQ(None, N->getSource()); +} + TEST_F(DIFileTest, ScopeGetFile) { // Ensure that DIScope::getFile() returns itself. DIScope *N = DIFile::get(Context, "file", "dir");