mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Macro debug info support in LLVM IR
Introduced DIMacro and DIMacroFile debug info metadata in the LLVM IR to support macros. Differential Revision: http://reviews.llvm.org/D14687 llvm-svn: 255245
This commit is contained in:
parent
c26660fa6c
commit
85f2758759
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -83,7 +83,9 @@ public:
|
||||
DIImportedEntityKind,
|
||||
ConstantAsMetadataKind,
|
||||
LocalAsMetadataKind,
|
||||
MDStringKind
|
||||
MDStringKind,
|
||||
DIMacroKind,
|
||||
DIMacroFileKind
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -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
|
||||
|
@ -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")) {
|
||||
|
@ -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) {}
|
||||
};
|
||||
@ -3370,6 +3375,26 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -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: "/")
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user