summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/LangRef.rst34
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h4
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h187
-rw-r--r--include/llvm/IR/Metadata.def3
-rw-r--r--include/llvm/IR/Metadata.h4
-rw-r--r--include/llvm/Support/Dwarf.h2
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp64
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp30
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp28
-rw-r--r--lib/IR/AsmWriter.cpp33
-rw-r--r--lib/IR/DIBuilder.cpp2
-rw-r--r--lib/IR/DebugInfoMetadata.cpp25
-rw-r--r--lib/IR/LLVMContextImpl.h43
-rw-r--r--lib/IR/Verifier.cpp29
-rw-r--r--lib/Support/Dwarf.cpp10
-rw-r--r--test/Assembler/debug-info.ll19
-rw-r--r--test/Assembler/dicompileunit.ll15
-rw-r--r--unittests/IR/MetadataTest.cpp15
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;