diff options
-rw-r--r-- | docs/LangRef.rst | 34 | ||||
-rw-r--r-- | include/llvm/Bitcode/LLVMBitCodes.h | 4 | ||||
-rw-r--r-- | include/llvm/IR/DebugInfoMetadata.h | 187 | ||||
-rw-r--r-- | include/llvm/IR/Metadata.def | 3 | ||||
-rw-r--r-- | include/llvm/IR/Metadata.h | 4 | ||||
-rw-r--r-- | include/llvm/Support/Dwarf.h | 2 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 64 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 30 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 28 | ||||
-rw-r--r-- | lib/IR/AsmWriter.cpp | 33 | ||||
-rw-r--r-- | lib/IR/DIBuilder.cpp | 2 | ||||
-rw-r--r-- | lib/IR/DebugInfoMetadata.cpp | 25 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 43 | ||||
-rw-r--r-- | lib/IR/Verifier.cpp | 29 | ||||
-rw-r--r-- | lib/Support/Dwarf.cpp | 10 | ||||
-rw-r--r-- | test/Assembler/debug-info.ll | 19 | ||||
-rw-r--r-- | test/Assembler/dicompileunit.ll | 15 | ||||
-rw-r--r-- | unittests/IR/MetadataTest.cpp | 15 |
20 files changed, 509 insertions, 40 deletions
diff --git a/docs/LangRef.rst b/docs/LangRef.rst index ca0939e5357..7f1a97428ee 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -3751,9 +3751,9 @@ DICompileUnit """"""""""""" ``DICompileUnit`` nodes represent a compile unit. The ``enums:``, -``retainedTypes:``, ``subprograms:``, ``globals:`` and ``imports:`` fields are -tuples containing the debug info to be emitted along with the compile unit, -regardless of code optimizations (some nodes are only emitted if there are +``retainedTypes:``, ``subprograms:``, ``globals:``, ``imports:`` and ``macros:`` +fields are tuples containing the debug info to be emitted along with the compile +unit, regardless of code optimizations (some nodes are only emitted if there are references to them from instructions). .. code-block:: llvm @@ -3762,7 +3762,7 @@ references to them from instructions). isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: 1, enums: !2, retainedTypes: !3, subprograms: !4, - globals: !5, imports: !6) + globals: !5, imports: !6, macros: !7, dwoId: 0x0abcd) Compile unit descriptors provide the root scope for objects declared in a specific compilation unit. File descriptors are defined using this scope. @@ -4128,6 +4128,32 @@ compile unit. !2 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "foo", scope: !0, entity: !1, line: 7) +DIMacro +""""""" + +``DIMacro`` nodes represent definition or undefinition of a macro identifiers. +The ``name:`` field is the macro identifier, followed by macro parameters when +definining a function-like macro, and the ``value`` field is the token-string +used to expand the macro identifier. + +.. code-block:: llvm + + !2 = !DIMacro(macinfo: DW_MACINFO_define, line: 7, name: "foo(x)", + value: "((x) + 1)") + !3 = !DIMacro(macinfo: DW_MACINFO_undef, line: 30, name: "foo") + +DIMacroFile +""""""""""" + +``DIMacroFile`` nodes represent inclusion of source files. +The ``nodes:`` field is a list of ``DIMacro`` and ``DIMacroFile`` nodes that +appear in the included source file. + +.. code-block:: llvm + + !2 = !DIMacroFile(macinfo: DW_MACINFO_start_file, line: 7, file: !2, + nodes: !3) + '``tbaa``' Metadata ^^^^^^^^^^^^^^^^^^^ diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 7cb0d7edff4..55fe05938e6 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -220,7 +220,9 @@ enum { BITCODE_CURRENT_EPOCH = 0 }; METADATA_EXPRESSION = 29, // [distinct, n x element] METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...] METADATA_IMPORTED_ENTITY=31, // [distinct, tag, scope, entity, line, name] - METADATA_MODULE=32, // [distinct, scope, name, ...] + METADATA_MODULE = 32, // [distinct, scope, name, ...] + METADATA_MACRO = 33, // [distinct, macinfo, line, name, value] + METADATA_MACRO_FILE = 34, // [distinct, macinfo, line, file, ...] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 0b3fe06f357..456313a70e8 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -949,15 +949,16 @@ class DICompileUnit : public DIScope { unsigned EmissionKind, DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes, DISubprogramArray Subprograms, DIGlobalVariableArray GlobalVariables, - DIImportedEntityArray ImportedEntities, uint64_t DWOId, - StorageType Storage, bool ShouldCreate = true) { + DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, + uint64_t DWOId, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, getCanonicalMDString(Context, SplitDebugFilename), EmissionKind, EnumTypes.get(), RetainedTypes.get(), Subprograms.get(), GlobalVariables.get(), - ImportedEntities.get(), DWOId, Storage, ShouldCreate); + ImportedEntities.get(), Macros.get(), DWOId, Storage, + ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, @@ -965,15 +966,15 @@ class DICompileUnit : public DIScope { unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *Subprograms, Metadata *GlobalVariables, - Metadata *ImportedEntities, uint64_t DWOId, StorageType Storage, - bool ShouldCreate = true); + Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, + StorageType Storage, bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { return getTemporary( getContext(), getSourceLanguage(), getFile(), getProducer(), isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(), getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(), - getGlobalVariables(), getImportedEntities(), DWOId); + getGlobalVariables(), getImportedEntities(), getMacros(), DWOId); } static void get() = delete; @@ -987,20 +988,22 @@ public: StringRef SplitDebugFilename, unsigned EmissionKind, DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes, DISubprogramArray Subprograms, DIGlobalVariableArray GlobalVariables, - DIImportedEntityArray ImportedEntities, uint64_t DWOId), + DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, + uint64_t DWOId), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms, - GlobalVariables, ImportedEntities, DWOId)) + GlobalVariables, ImportedEntities, Macros, DWOId)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *Subprograms, - Metadata *GlobalVariables, Metadata *ImportedEntities, uint64_t DWOId), + Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, + uint64_t DWOId), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms, - GlobalVariables, ImportedEntities, DWOId)) + GlobalVariables, ImportedEntities, Macros, DWOId)) TempDICompileUnit clone() const { return cloneImpl(); } @@ -1026,6 +1029,9 @@ public: DIImportedEntityArray getImportedEntities() const { return cast_or_null<MDTuple>(getRawImportedEntities()); } + DIMacroNodeArray getMacros() const { + return cast_or_null<MDTuple>(getRawMacros()); + } uint64_t getDWOId() const { return DWOId; } void setDWOId(uint64_t DwoId) { DWOId = DwoId; } @@ -1039,6 +1045,7 @@ public: Metadata *getRawSubprograms() const { return getOperand(6); } Metadata *getRawGlobalVariables() const { return getOperand(7); } Metadata *getRawImportedEntities() const { return getOperand(8); } + Metadata *getRawMacros() const { return getOperand(9); } /// \brief Replace arrays. /// @@ -1061,6 +1068,7 @@ public: void replaceImportedEntities(DIImportedEntityArray N) { replaceOperandWith(8, N.get()); } + void replaceMacros(DIMacroNodeArray N) { replaceOperandWith(9, N.get()); } /// @} static bool classof(const Metadata *MD) { @@ -2199,6 +2207,165 @@ public: } }; +/// \brief Macro Info DWARF-like metadata node. +/// +/// A metadata node with a DWARF macro info (i.e., a constant named +/// \c DW_MACINFO_*, defined in llvm/Support/Dwarf.h). Called \a DIMacroNode +/// because it's potentially used for non-DWARF output. +class DIMacroNode : public MDNode { + friend class LLVMContextImpl; + friend class MDNode; + +protected: + DIMacroNode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned MIType, + ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None) + : MDNode(C, ID, Storage, Ops1, Ops2) { + assert(MIType < 1u << 16); + SubclassData16 = MIType; + } + ~DIMacroNode() = default; + + template <class Ty> Ty *getOperandAs(unsigned I) const { + return cast_or_null<Ty>(getOperand(I)); + } + + StringRef getStringOperand(unsigned I) const { + if (auto *S = getOperandAs<MDString>(I)) + return S->getString(); + return StringRef(); + } + + static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) { + if (S.empty()) + return nullptr; + return MDString::get(Context, S); + } + +public: + unsigned getMacinfoType() const { return SubclassData16; } + + static bool classof(const Metadata *MD) { + switch (MD->getMetadataID()) { + default: + return false; + case DIMacroKind: + case DIMacroFileKind: + return true; + } + } +}; + +class DIMacro : public DIMacroNode { + friend class LLVMContextImpl; + friend class MDNode; + + unsigned Line; + + DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line, + ArrayRef<Metadata *> Ops) + : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {} + ~DIMacro() = default; + + static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, + StringRef Name, StringRef Value, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, MIType, Line, getCanonicalMDString(Context, Name), + getCanonicalMDString(Context, Value), Storage, ShouldCreate); + } + static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line, + MDString *Name, MDString *Value, StorageType Storage, + bool ShouldCreate = true); + + TempDIMacro cloneImpl() const { + return getTemporary(getContext(), getMacinfoType(), getLine(), getName(), + getValue()); + } + +public: + DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name, + StringRef Value = ""), + (MIType, Line, Name, Value)) + DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name, + MDString *Value), + (MIType, Line, Name, Value)) + + TempDIMacro clone() const { return cloneImpl(); } + + unsigned getLine() const { return Line; } + + StringRef getName() const { return getStringOperand(0); } + StringRef getValue() const { return getStringOperand(1); } + + MDString *getRawName() const { return getOperandAs<MDString>(0); } + MDString *getRawValue() const { return getOperandAs<MDString>(1); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DIMacroKind; + } +}; + +class DIMacroFile : public DIMacroNode { + friend class LLVMContextImpl; + friend class MDNode; + + unsigned Line; + + DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType, + unsigned Line, ArrayRef<Metadata *> Ops) + : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {} + ~DIMacroFile() = default; + + static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType, + unsigned Line, DIFile *File, + DIMacroNodeArray Elements, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, MIType, Line, static_cast<Metadata *>(File), + Elements.get(), Storage, ShouldCreate); + } + + static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType, + unsigned Line, Metadata *File, Metadata *Elements, + StorageType Storage, bool ShouldCreate = true); + + TempDIMacroFile cloneImpl() const { + return getTemporary(getContext(), getMacinfoType(), getLine(), getFile(), + getElements()); + } + +public: + DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File, + DIMacroNodeArray Elements), + (MIType, Line, File, Elements)) + DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, + Metadata *File, Metadata *Elements), + (MIType, Line, File, Elements)) + + TempDIMacroFile clone() const { return cloneImpl(); } + + void replaceElements(DIMacroNodeArray Elements) { +#ifndef NDEBUG + for (DIMacroNode *Op : getElements()) + assert(std::find(Elements->op_begin(), Elements->op_end(), Op) && + "Lost a macro node during macro node list replacement"); +#endif + replaceOperandWith(1, Elements.get()); + } + + unsigned getLine() const { return Line; } + DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); } + + DIMacroNodeArray getElements() const { + return cast_or_null<MDTuple>(getRawElements()); + } + + Metadata *getRawFile() const { return getOperand(0); } + Metadata *getRawElements() const { return getOperand(1); } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DIMacroFileKind; + } +}; + } // end namespace llvm #undef DEFINE_MDNODE_GET_UNPACK_IMPL diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def index 9d6f929be34..b1d22178e26 100644 --- a/include/llvm/IR/Metadata.def +++ b/include/llvm/IR/Metadata.def @@ -108,6 +108,9 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIObjCProperty) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity) +HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile) #undef HANDLE_METADATA #undef HANDLE_METADATA_LEAF diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 276fa7d1188..84c82476c4f 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -83,7 +83,9 @@ public: DIImportedEntityKind, ConstantAsMetadataKind, LocalAsMetadataKind, - MDStringKind + MDStringKind, + DIMacroKind, + DIMacroFileKind }; protected: diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 8d71353b167..b63d12e9ff3 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -625,6 +625,7 @@ const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage); /// /// \li \a getTag() returns \a DW_TAG_invalid on invalid input. /// \li \a getVirtuality() returns \a DW_VIRTUALITY_invalid on invalid input. +/// \li \a getMacinfo() returns \a DW_MACINFO_invalid on invalid input. /// /// @{ unsigned getTag(StringRef TagString); @@ -632,6 +633,7 @@ unsigned getOperationEncoding(StringRef OperationEncodingString); unsigned getVirtuality(StringRef VirtualityString); unsigned getLanguage(StringRef LanguageString); unsigned getAttributeEncoding(StringRef EncodingString); +unsigned getMacinfo(StringRef MacinfoString); /// @} /// \brief Returns the symbolic string representing Val when used as a value diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index f95a763e3da..db90f78b318 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -778,6 +778,7 @@ lltok::Kind LLLexer::LexIdentifier() { DWKEYWORD(VIRTUALITY, DwarfVirtuality); DWKEYWORD(LANG, DwarfLang); DWKEYWORD(OP, DwarfOp); + DWKEYWORD(MACINFO, DwarfMacinfo); #undef DWKEYWORD if (Keyword.startswith("DIFlag")) { diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 145b5eaacec..b5cbee5085b 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -3279,6 +3279,11 @@ struct DwarfTagField : public MDUnsignedField { DwarfTagField(dwarf::Tag DefaultTag) : MDUnsignedField(DefaultTag, dwarf::DW_TAG_hi_user) {} }; +struct DwarfMacinfoTypeField : public MDUnsignedField { + DwarfMacinfoTypeField() : MDUnsignedField(0, dwarf::DW_MACINFO_vendor_ext) {} + DwarfMacinfoTypeField(dwarf::MacinfoRecordType DefaultType) + : MDUnsignedField(DefaultType, dwarf::DW_MACINFO_vendor_ext) {} +}; struct DwarfAttEncodingField : public MDUnsignedField { DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {} }; @@ -3372,6 +3377,26 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) { template <> bool LLParser::ParseMDField(LocTy Loc, StringRef Name, + DwarfMacinfoTypeField &Result) { + if (Lex.getKind() == lltok::APSInt) + return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); + + if (Lex.getKind() != lltok::DwarfMacinfo) + return TokError("expected DWARF macinfo type"); + + unsigned Macinfo = dwarf::getMacinfo(Lex.getStrVal()); + if (Macinfo == dwarf::DW_MACINFO_invalid) + return TokError( + "invalid DWARF macinfo type" + Twine(" '") + Lex.getStrVal() + "'"); + assert(Macinfo <= Result.Max && "Expected valid DWARF macinfo type"); + + Result.assign(Macinfo); + Lex.Lex(); + return false; +} + +template <> +bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfVirtualityField &Result) { if (Lex.getKind() == lltok::APSInt) return ParseMDField(Loc, Name, static_cast<MDUnsignedField &>(Result)); @@ -3782,7 +3807,7 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { /// isOptimized: true, flags: "-O2", runtimeVersion: 1, /// splitDebugFilename: "abc.debug", emissionKind: 1, /// enums: !1, retainedTypes: !2, subprograms: !3, -/// globals: !4, imports: !5, dwoId: 0x0abcd) +/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd) bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { if (!IsDistinct) return Lex.Error("missing 'distinct', required for !DICompileUnit"); @@ -3801,6 +3826,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(subprograms, MDField, ); \ OPTIONAL(globals, MDField, ); \ OPTIONAL(imports, MDField, ); \ + OPTIONAL(macros, MDField, ); \ OPTIONAL(dwoId, MDUnsignedField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -3808,7 +3834,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { Result = DICompileUnit::getDistinct( Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, - retainedTypes.Val, subprograms.Val, globals.Val, imports.Val, dwoId.Val); + retainedTypes.Val, subprograms.Val, globals.Val, imports.Val, macros.Val, + dwoId.Val); return false; } @@ -3904,6 +3931,39 @@ bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) { return false; } +/// ParseDIMacro: +/// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value: "SomeValue") +bool LLParser::ParseDIMacro(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(type, DwarfMacinfoTypeField, ); \ + REQUIRED(line, LineField, ); \ + REQUIRED(name, MDStringField, ); \ + OPTIONAL(value, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DIMacro, + (Context, type.Val, line.Val, name.Val, value.Val)); + return false; +} + +/// ParseDIMacroFile: +/// ::= !DIMacroFile(line: 9, file: !2, nodes: !3) +bool LLParser::ParseDIMacroFile(MDNode *&Result, bool IsDistinct) { +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(type, DwarfMacinfoTypeField, (dwarf::DW_MACINFO_start_file)); \ + REQUIRED(line, LineField, ); \ + REQUIRED(file, MDField, ); \ + OPTIONAL(nodes, MDField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(DIMacroFile, + (Context, type.Val, line.Val, file.Val, nodes.Val)); + return false; +} + + /// ParseDIModule: /// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: "-DNDEBUG", /// includePath: "/usr/include", isysroot: "/") diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 48abeac9506..10c840d257f 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -215,6 +215,7 @@ namespace lltok { DwarfLang, // DW_LANG_foo DwarfOp, // DW_OP_foo DIFlag, // DIFlagFoo + DwarfMacinfo, // DW_MACINFO_foo // Type valued tokens (TyVal). Type, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e95aba771b9..4b5af3dd80f 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2214,10 +2214,10 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() < 14 || Record.size() > 15) + if (Record.size() < 14 || Record.size() > 16) return error("Invalid record"); - // Ignore Record[1], which indicates whether this compile unit is + // Ignore Record[0], which indicates whether this compile unit is // distinct. It's always distinct. MDValueList.assignValue( DICompileUnit::getDistinct( @@ -2226,7 +2226,9 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { Record[6], getMDString(Record[7]), Record[8], getMDOrNull(Record[9]), getMDOrNull(Record[10]), getMDOrNull(Record[11]), getMDOrNull(Record[12]), - getMDOrNull(Record[13]), Record.size() == 14 ? 0 : Record[14]), + getMDOrNull(Record[13]), + Record.size() <= 15 ? 0 : getMDOrNull(Record[15]), + Record.size() <= 14 ? 0 : Record[14]), NextMDValueNo++); break; } @@ -2294,6 +2296,28 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { NextMDValueNo++); break; } + case bitc::METADATA_MACRO: { + if (Record.size() != 5) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIMacro, Record[0], + (Context, Record[1], Record[2], + getMDString(Record[3]), getMDString(Record[4]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_MACRO_FILE: { + if (Record.size() != 5) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIMacroFile, Record[0], + (Context, Record[1], Record[2], + getMDOrNull(Record[3]), getMDOrNull(Record[4]))), + NextMDValueNo++); + break; + } case bitc::METADATA_TEMPLATE_TYPE: { if (Record.size() != 3) return error("Invalid record"); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index b1b699765bd..201b4bc34c2 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1017,6 +1017,7 @@ static void WriteDICompileUnit(const DICompileUnit *N, Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get())); Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get())); Record.push_back(N->getDWOId()); + Record.push_back(VE.getMetadataOrNullID(N->getMacros().get())); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); @@ -1092,6 +1093,33 @@ static void WriteDINamespace(const DINamespace *N, const ValueEnumerator &VE, Record.clear(); } +static void WriteDIMacro(const DIMacro *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getMacinfoType()); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getRawValue())); + + Stream.EmitRecord(bitc::METADATA_MACRO, Record, Abbrev); + Record.clear(); +} + +static void WriteDIMacroFile(const DIMacroFile *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getMacinfoType()); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(VE.getMetadataOrNullID(N->getElements().get())); + + Stream.EmitRecord(bitc::METADATA_MACRO_FILE, Record, Abbrev); + Record.clear(); +} + static void WriteDIModule(const DIModule *N, const ValueEnumerator &VE, BitstreamWriter &Stream, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index f8040a7b5f8..e41815aafa8 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1396,6 +1396,7 @@ struct MDFieldPrinter { : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) { } void printTag(const DINode *N); + void printMacinfoType(const DIMacroNode *N); void printString(StringRef Name, StringRef Value, bool ShouldSkipEmpty = true); void printMetadata(StringRef Name, const Metadata *MD, @@ -1418,6 +1419,14 @@ void MDFieldPrinter::printTag(const DINode *N) { Out << N->getTag(); } +void MDFieldPrinter::printMacinfoType(const DIMacroNode *N) { + Out << FS << "type: "; + if (const char *Type = dwarf::MacinfoString(N->getMacinfoType())) + Out << Type; + else + Out << N->getMacinfoType(); +} + void MDFieldPrinter::printString(StringRef Name, StringRef Value, bool ShouldSkipEmpty) { if (ShouldSkipEmpty && Value.empty()) @@ -1643,6 +1652,7 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, Printer.printMetadata("subprograms", N->getRawSubprograms()); Printer.printMetadata("globals", N->getRawGlobalVariables()); Printer.printMetadata("imports", N->getRawImportedEntities()); + Printer.printMetadata("macros", N->getRawMacros()); Printer.printInt("dwoId", N->getDWOId()); Out << ")"; } @@ -1711,6 +1721,29 @@ static void writeDINamespace(raw_ostream &Out, const DINamespace *N, Out << ")"; } +static void writeDIMacro(raw_ostream &Out, const DIMacro *N, + TypePrinting *TypePrinter, SlotTracker *Machine, + const Module *Context) { + Out << "!DIMacro("; + MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); + Printer.printMacinfoType(N); + Printer.printInt("line", N->getLine()); + Printer.printString("name", N->getName()); + Printer.printString("value", N->getValue()); + Out << ")"; +} + +static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N, + TypePrinting *TypePrinter, SlotTracker *Machine, + const Module *Context) { + Out << "!DIMacroFile("; + MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); + Printer.printInt("line", N->getLine()); + Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false); + Printer.printMetadata("nodes", N->getRawElements()); + Out << ")"; +} + static void writeDIModule(raw_ostream &Out, const DIModule *N, TypePrinting *TypePrinter, SlotTracker *Machine, const Module *Context) { diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 09b540350c2..b7841fe2b85 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -148,7 +148,7 @@ DICompileUnit *DIBuilder::createCompileUnit( CUNode = DICompileUnit::getDistinct( VMContext, Lang, DIFile::get(VMContext, Filename, Directory), Producer, isOptimized, Flags, RunTimeVer, SplitName, Kind, nullptr, - nullptr, nullptr, nullptr, nullptr, DWOId); + nullptr, nullptr, nullptr, nullptr, nullptr, DWOId); // Create a named metadata so that it is easier to find cu in a module. // Note that we only generate this when the caller wants to actually diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index cead10652e0..58e0abdd577 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -315,7 +315,7 @@ DICompileUnit *DICompileUnit::getImpl( unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *Subprograms, Metadata *GlobalVariables, - Metadata *ImportedEntities, uint64_t DWOId, + Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, StorageType Storage, bool ShouldCreate) { assert(Storage != Uniqued && "Cannot unique DICompileUnit"); assert(isCanonical(Producer) && "Expected canonical MDString"); @@ -324,7 +324,7 @@ DICompileUnit *DICompileUnit::getImpl( Metadata *Ops[] = {File, Producer, Flags, SplitDebugFilename, EnumTypes, RetainedTypes, Subprograms, GlobalVariables, - ImportedEntities}; + ImportedEntities, Macros}; return storeImpl(new (ArrayRef<Metadata *>(Ops).size()) DICompileUnit( Context, Storage, SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind, DWOId, Ops), @@ -557,3 +557,24 @@ DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag, Metadata *Ops[] = {Scope, Entity, Name}; DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops); } + +DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, + unsigned Line, MDString *Name, MDString *Value, + StorageType Storage, bool ShouldCreate) { + assert(isCanonical(Name) && "Expected canonical MDString"); + DEFINE_GETIMPL_LOOKUP(DIMacro, + (MIType, Line, getString(Name), getString(Value))); + Metadata *Ops[] = { Name, Value }; + DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops); +} + +DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType, + unsigned Line, Metadata *File, + Metadata *Elements, StorageType Storage, + bool ShouldCreate) { + DEFINE_GETIMPL_LOOKUP(DIMacroFile, + (MIType, Line, File, Elements)); + Metadata *Ops[] = { File, Elements }; + DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops); +} + diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 7e89b582cbd..ae987e65bcb 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -792,6 +792,49 @@ template <> struct MDNodeKeyImpl<DIImportedEntity> { } }; +template <> struct MDNodeKeyImpl<DIMacro> { + unsigned MIType; + unsigned Line; + StringRef Name; + StringRef Value; + + MDNodeKeyImpl(unsigned MIType, unsigned Line, StringRef Name, StringRef Value) + : MIType(MIType), Line(Line), Name(Name), Value(Value) {} + MDNodeKeyImpl(const DIMacro *N) + : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getName()), + Value(N->getValue()) {} + + bool isKeyOf(const DIMacro *RHS) const { + return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && + Name == RHS->getName() && Value == RHS->getValue(); + } + unsigned getHashValue() const { + return hash_combine(MIType, Line, Name, Value); + } +}; + +template <> struct MDNodeKeyImpl<DIMacroFile> { + unsigned MIType; + unsigned Line; + Metadata *File; + Metadata *Elements; + + MDNodeKeyImpl(unsigned MIType, unsigned Line, Metadata *File, + Metadata *Elements) + : MIType(MIType), Line(Line), File(File), Elements(Elements) {} + MDNodeKeyImpl(const DIMacroFile *N) + : MIType(N->getMacinfoType()), Line(N->getLine()), File(N->getRawFile()), + Elements(N->getRawElements()) {} + + bool isKeyOf(const DIMacroFile *RHS) const { + return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && + File == RHS->getRawFile() && File == RHS->getRawElements(); + } + unsigned getHashValue() const { + return hash_combine(MIType, Line, File, Elements); + } +}; + /// \brief DenseMapInfo for MDNode subclasses. template <class NodeTy> struct MDNodeInfo { typedef MDNodeKeyImpl<NodeTy> KeyTy; diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 96b8a779577..819d7bb9ad9 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -860,8 +860,6 @@ void Verifier::visitDICompositeType(const DICompositeType &N) { "invalid composite elements", &N, N.getRawElements()); Assert(isTypeRef(N, N.getRawVTableHolder()), "invalid vtable holder", &N, N.getRawVTableHolder()); - Assert(!N.getRawElements() || isa<MDTuple>(N.getRawElements()), - "invalid composite elements", &N, N.getRawElements()); Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags", &N); if (auto *Params = N.getRawTemplateParams()) @@ -935,6 +933,12 @@ void Verifier::visitDICompileUnit(const DICompileUnit &N) { Op); } } + if (auto *Array = N.getRawMacros()) { + Assert(isa<MDTuple>(Array), "invalid macro list", &N, Array); + for (Metadata *Op : N.getMacros()->operands()) { + Assert(Op && isa<DIMacroNode>(Op), "invalid macro ref", &N, Op); + } + } } void Verifier::visitDISubprogram(const DISubprogram &N) { @@ -988,6 +992,27 @@ void Verifier::visitDINamespace(const DINamespace &N) { Assert(isa<DIScope>(S), "invalid scope ref", &N, S); } +void Verifier::visitDIMacro(const DIMacro &N) { + Assert(N.getMacinfoType() == dwarf::DW_MACINFO_define || + N.getMacinfoType() == dwarf::DW_MACINFO_undef, + "invalid macinfo type", &N); + Assert(!N.getName().empty(), "anonymous macro", &N); +} + +void Verifier::visitDIMacroFile(const DIMacroFile &N) { + Assert(N.getMacinfoType() == dwarf::DW_MACINFO_start_file, + "invalid macinfo type", &N); + if (auto *F = N.getRawFile()) + Assert(isa<DIFile>(F), "invalid file", &N, F); + + if (auto *Array = N.getRawElements()) { + Assert(isa<MDTuple>(Array), "invalid macro list", &N, Array); + for (Metadata *Op : N.getElements()->operands()) { + Assert(Op && isa<DIMacroNode>(Op), "invalid macro ref", &N, Op); + } + } +} + void Verifier::visitDIModule(const DIModule &N) { Assert(N.getTag() == dwarf::DW_TAG_module, "invalid tag", &N); Assert(!N.getName().empty(), "anonymous module", &N); diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp index dd740384de3..7d722567173 100644 --- a/lib/Support/Dwarf.cpp +++ b/lib/Support/Dwarf.cpp @@ -473,6 +473,16 @@ const char *llvm::dwarf::MacinfoString(unsigned Encoding) { return nullptr; } +unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) { + return StringSwitch<unsigned>(MacinfoString) + .Case("DW_MACINFO_define", DW_MACINFO_define) + .Case("DW_MACINFO_undef", DW_MACINFO_undef) + .Case("DW_MACINFO_start_file", DW_MACINFO_start_file) + .Case("DW_MACINFO_end_file", DW_MACINFO_end_file) + .Case("DW_MACINFO_vendor_ext", DW_MACINFO_vendor_ext) + .Default(DW_MACINFO_invalid); +} + const char *llvm::dwarf::CallFrameString(unsigned Encoding) { switch (Encoding) { case DW_CFA_nop: return "DW_CFA_nop"; diff --git a/test/Assembler/debug-info.ll b/test/Assembler/debug-info.ll index 91dfe561a2f..86630840dc2 100644 --- a/test/Assembler/debug-info.ll +++ b/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} -!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} +; 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: !0 = !DISubrange(count: 3) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -63,10 +63,19 @@ !25 = !DICompositeType(tag: DW_TAG_structure_type) !26 = !DICompositeType(tag: DW_TAG_structure_type, runtimeLang: 6) -; !25 = !{!7, !7} -; !26 = !DISubroutineType(flags: DIFlagPublic | DIFlagStaticMember, types: !25) -; !27 = !DISubroutineType(types: !25) +; CHECK-NEXT: !25 = !{!6, !6} +; CHECK-NEXT: !26 = !DISubroutineType(flags: DIFlagPublic | DIFlagStaticMember, types: !25) +; CHECK-NEXT: !27 = !DISubroutineType(types: !25) !27 = !{!7, !7} !28 = !DISubroutineType(flags: DIFlagPublic | DIFlagStaticMember, types: !27) !29 = !DISubroutineType(flags: 0, types: !27) !30 = !DISubroutineType(types: !27) + +; CHECK-NEXT: !28 = !DIMacro(type: DW_MACINFO_define, line: 9, name: "Name", value: "Value") +; CHECK-NEXT: !29 = distinct !{!28} +; CHECK-NEXT: !30 = !DIMacroFile(line: 9, file: !12, nodes: !29) +; CHECK-NEXT: !31 = !DIMacroFile(line: 11, file: !12) +!31 = !DIMacro(type: DW_MACINFO_define, line: 9, name: "Name", value: "Value") +!32 = distinct !{!31} +!33 = !DIMacroFile(line: 9, file: !14, nodes: !32) +!34 = !DIMacroFile(type: DW_MACINFO_start_file, line: 11, file: !14) diff --git a/test/Assembler/dicompileunit.ll b/test/Assembler/dicompileunit.ll index ba6731827cd..92fa61fe6b9 100644 --- a/test/Assembler/dicompileunit.ll +++ b/test/Assembler/dicompileunit.ll @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} +; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9} !0 = distinct !{} !1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") @@ -11,15 +11,16 @@ !4 = distinct !{} !5 = distinct !{} !6 = distinct !{} +!7 = distinct !{} -; CHECK: !7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: 3, enums: !2, retainedTypes: !3, subprograms: !4, globals: !5, imports: !6, dwoId: 42) -!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", +; CHECK: !8 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: 3, enums: !2, retainedTypes: !3, subprograms: !4, globals: !5, imports: !6, macros: !7, dwoId: 42) +!8 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: 3, enums: !2, retainedTypes: !3, subprograms: !4, - globals: !5, imports: !6, dwoId: 42) + globals: !5, imports: !6, macros: !7, dwoId: 42) -; CHECK: !8 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: 0) -!8 = distinct !DICompileUnit(language: 12, file: !1, producer: "", +; CHECK: !9 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: 0) +!9 = distinct !DICompileUnit(language: 12, file: !1, producer: "", isOptimized: false, flags: "", runtimeVersion: 0, splitDebugFilename: "", emissionKind: 0) diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 8f346f53a2d..257ab7204c6 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -1312,10 +1312,12 @@ TEST_F(DICompileUnitTest, get) { MDTuple *GlobalVariables = getTuple(); MDTuple *ImportedEntities = getTuple(); uint64_t DWOId = 0x10000000c0ffee; + MDTuple *Macros = getTuple(); auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, DWOId); + RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, Macros, + DWOId); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); @@ -1331,6 +1333,7 @@ TEST_F(DICompileUnitTest, get) { EXPECT_EQ(Subprograms, N->getSubprograms().get()); EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); EXPECT_EQ(ImportedEntities, N->getImportedEntities().get()); + EXPECT_EQ(Macros, N->getMacros().get()); EXPECT_EQ(DWOId, N->getDWOId()); TempDICompileUnit Temp = N->clone(); @@ -1348,6 +1351,7 @@ TEST_F(DICompileUnitTest, get) { EXPECT_EQ(Subprograms, Temp->getSubprograms().get()); EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get()); EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get()); + EXPECT_EQ(Macros, Temp->getMacros().get()); EXPECT_EQ(DWOId, Temp->getDWOId()); auto *TempAddress = Temp.get(); @@ -1372,7 +1376,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, nullptr, ImportedEntities, DWOId); + RetainedTypes, nullptr, nullptr, ImportedEntities, nullptr, DWOId); auto *Subprograms = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getSubprograms().get()); @@ -1387,6 +1391,13 @@ TEST_F(DICompileUnitTest, replaceArrays) { EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get()); N->replaceGlobalVariables(nullptr); EXPECT_EQ(nullptr, N->getGlobalVariables().get()); + + auto *Macros = MDTuple::getDistinct(Context, None); + EXPECT_EQ(nullptr, N->getMacros().get()); + N->replaceMacros(Macros); + EXPECT_EQ(Macros, N->getMacros().get()); + N->replaceMacros(nullptr); + EXPECT_EQ(nullptr, N->getMacros().get()); } typedef MetadataTest DISubprogramTest; |