mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[DebugInfo] IR/Bitcode changes for DISubprogram flags.
Packing the flags into one bitcode word will save effort in adding new flags in the future. Differential Revision: https://reviews.llvm.org/D54755 llvm-svn: 347806
This commit is contained in:
parent
dadc75adba
commit
f2c09f1782
@ -78,8 +78,8 @@ HANDLE_DI_FLAG((1 << 29), Largest)
|
||||
// Use this as a zero/initialization value.
|
||||
// For example: void foo(DISPFlags Flags = SPFlagZero).
|
||||
HANDLE_DISP_FLAG(0, Zero)
|
||||
// Virtuality is a two-bit valued field.
|
||||
HANDLE_DISP_FLAG(0u, Nonvirtual)
|
||||
// Virtuality is a two-bit enum field in the LSB of the word.
|
||||
// Values should match DW_VIRTUALITY_*.
|
||||
HANDLE_DISP_FLAG(1u, Virtual)
|
||||
HANDLE_DISP_FLAG(2u, PureVirtual)
|
||||
HANDLE_DISP_FLAG((1u << 2), LocalToUnit)
|
||||
|
@ -1620,9 +1620,21 @@ public:
|
||||
#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID,
|
||||
#define DISP_FLAG_LARGEST_NEEDED
|
||||
#include "llvm/IR/DebugInfoFlags.def"
|
||||
SPFlagVirtuality = SPFlagNonvirtual | SPFlagVirtual | SPFlagPureVirtual,
|
||||
SPFlagNonvirtual = SPFlagZero,
|
||||
SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
|
||||
LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
|
||||
};
|
||||
|
||||
static DISPFlags getFlag(StringRef Flag);
|
||||
static StringRef getFlagString(DISPFlags Flag);
|
||||
|
||||
/// Split up a flags bitfield for easier printing.
|
||||
///
|
||||
/// Split \c Flags into \c SplitFlags, a vector of its components. Returns
|
||||
/// any remaining (unrecognized) bits.
|
||||
static DISPFlags splitFlags(DISPFlags Flags,
|
||||
SmallVectorImpl<DISPFlags> &SplitFlags);
|
||||
|
||||
// Helper for converting old bitfields to new flags word.
|
||||
static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
|
||||
bool IsOptimized,
|
||||
|
@ -905,6 +905,11 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
return lltok::DIFlag;
|
||||
}
|
||||
|
||||
if (Keyword.startswith("DISPFlag")) {
|
||||
StrVal.assign(Keyword.begin(), Keyword.end());
|
||||
return lltok::DISPFlag;
|
||||
}
|
||||
|
||||
if (Keyword.startswith("CSK_")) {
|
||||
StrVal.assign(Keyword.begin(), Keyword.end());
|
||||
return lltok::ChecksumKind;
|
||||
|
@ -3749,6 +3749,10 @@ struct DIFlagField : public MDFieldImpl<DINode::DIFlags> {
|
||||
DIFlagField() : MDFieldImpl(DINode::FlagZero) {}
|
||||
};
|
||||
|
||||
struct DISPFlagField : public MDFieldImpl<DISubprogram::DISPFlags> {
|
||||
DISPFlagField() : MDFieldImpl(DISubprogram::SPFlagZero) {}
|
||||
};
|
||||
|
||||
struct MDSignedField : public MDFieldImpl<int64_t> {
|
||||
int64_t Min;
|
||||
int64_t Max;
|
||||
@ -4041,6 +4045,46 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// DISPFlagField
|
||||
/// ::= uint32
|
||||
/// ::= DISPFlagVector
|
||||
/// ::= DISPFlagVector '|' DISPFlag* '|' uint32
|
||||
template <>
|
||||
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) {
|
||||
|
||||
// Parser for a single flag.
|
||||
auto parseFlag = [&](DISubprogram::DISPFlags &Val) {
|
||||
if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) {
|
||||
uint32_t TempVal = static_cast<uint32_t>(Val);
|
||||
bool Res = ParseUInt32(TempVal);
|
||||
Val = static_cast<DISubprogram::DISPFlags>(TempVal);
|
||||
return Res;
|
||||
}
|
||||
|
||||
if (Lex.getKind() != lltok::DISPFlag)
|
||||
return TokError("expected debug info flag");
|
||||
|
||||
Val = DISubprogram::getFlag(Lex.getStrVal());
|
||||
if (!Val)
|
||||
return TokError(Twine("invalid subprogram debug info flag '") +
|
||||
Lex.getStrVal() + "'");
|
||||
Lex.Lex();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Parse the flags and combine them together.
|
||||
DISubprogram::DISPFlags Combined = DISubprogram::SPFlagZero;
|
||||
do {
|
||||
DISubprogram::DISPFlags Val;
|
||||
if (parseFlag(Val))
|
||||
return true;
|
||||
Combined |= Val;
|
||||
} while (EatIfPresent(lltok::bar));
|
||||
|
||||
Result.assign(Combined);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
|
||||
MDSignedField &Result) {
|
||||
@ -4517,8 +4561,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
|
||||
/// isDefinition: true, scopeLine: 8, containingType: !3,
|
||||
/// virtuality: DW_VIRTUALTIY_pure_virtual,
|
||||
/// virtualIndex: 10, thisAdjustment: 4, flags: 11,
|
||||
/// isOptimized: false, templateParams: !4, declaration: !5,
|
||||
/// retainedNodes: !6, thrownTypes: !7)
|
||||
/// spFlags: 10, isOptimized: false, templateParams: !4,
|
||||
/// declaration: !5, retainedNodes: !6, thrownTypes: !7)
|
||||
bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
|
||||
auto Loc = Lex.getLoc();
|
||||
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
|
||||
@ -4536,21 +4580,26 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
|
||||
OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
|
||||
OPTIONAL(thisAdjustment, MDSignedField, (0, INT32_MIN, INT32_MAX)); \
|
||||
OPTIONAL(flags, DIFlagField, ); \
|
||||
OPTIONAL(spFlags, DISPFlagField, ); \
|
||||
OPTIONAL(isOptimized, MDBoolField, ); \
|
||||
OPTIONAL(unit, MDField, ); \
|
||||
OPTIONAL(templateParams, MDField, ); \
|
||||
OPTIONAL(declaration, MDField, ); \
|
||||
OPTIONAL(retainedNodes, MDField, ); \
|
||||
OPTIONAL(retainedNodes, MDField, ); \
|
||||
OPTIONAL(thrownTypes, MDField, );
|
||||
PARSE_MD_FIELDS();
|
||||
#undef VISIT_MD_FIELDS
|
||||
|
||||
if (isDefinition.Val && !IsDistinct)
|
||||
// An explicit spFlags field takes precedence over individual fields in
|
||||
// older IR versions.
|
||||
DISubprogram::DISPFlags SPFlags =
|
||||
spFlags.Seen ? spFlags.Val
|
||||
: DISubprogram::toSPFlags(isLocal.Val, isDefinition.Val,
|
||||
isOptimized.Val, virtuality.Val);
|
||||
if ((SPFlags & DISubprogram::SPFlagDefinition) && !IsDistinct)
|
||||
return Lex.Error(
|
||||
Loc,
|
||||
"missing 'distinct', required for !DISubprogram when 'isDefinition'");
|
||||
DISubprogram::DISPFlags SPFlags = DISubprogram::toSPFlags(
|
||||
isLocal.Val, isDefinition.Val, isOptimized.Val, virtuality.Val);
|
||||
"missing 'distinct', required for !DISubprogram that is a Definition");
|
||||
Result = GET_OR_DISTINCT(
|
||||
DISubprogram,
|
||||
(Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val,
|
||||
|
@ -442,6 +442,7 @@ enum Kind {
|
||||
NameTableKind, // GNU
|
||||
DwarfOp, // DW_OP_foo
|
||||
DIFlag, // DIFlagFoo
|
||||
DISPFlag, // DISPFlagFoo
|
||||
DwarfMacinfo, // DW_MACINFO_foo
|
||||
ChecksumKind, // CSK_foo
|
||||
|
||||
|
@ -1406,23 +1406,43 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
||||
if (Record.size() < 18 || Record.size() > 21)
|
||||
return error("Invalid record");
|
||||
|
||||
IsDistinct =
|
||||
(Record[0] & 1) || Record[8]; // All definitions should be distinct.
|
||||
bool HasSPFlags = Record[0] & 4;
|
||||
DISubprogram::DISPFlags SPFlags =
|
||||
HasSPFlags
|
||||
? static_cast<DISubprogram::DISPFlags>(Record[9])
|
||||
: DISubprogram::toSPFlags(
|
||||
/*IsLocalToUnit=*/Record[7], /*IsDefinition=*/Record[8],
|
||||
/*IsOptimized=*/Record[14], /*Virtuality=*/Record[11]);
|
||||
|
||||
// All definitions should be distinct.
|
||||
IsDistinct = (Record[0] & 1) || (SPFlags & DISubprogram::SPFlagDefinition);
|
||||
// Version 1 has a Function as Record[15].
|
||||
// Version 2 has removed Record[15].
|
||||
// Version 3 has the Unit as Record[15].
|
||||
// Version 4 added thisAdjustment.
|
||||
bool HasUnit = Record[0] >= 2;
|
||||
if (HasUnit && Record.size() < 19)
|
||||
// Version 5 repacked flags into DISPFlags, changing many element numbers.
|
||||
bool HasUnit = Record[0] & 2;
|
||||
if (!HasSPFlags && HasUnit && Record.size() < 19)
|
||||
return error("Invalid record");
|
||||
Metadata *CUorFn = getMDOrNull(Record[15]);
|
||||
unsigned Offset = Record.size() >= 19 ? 1 : 0;
|
||||
bool HasFn = Offset && !HasUnit;
|
||||
bool HasThisAdj = Record.size() >= 20;
|
||||
bool HasThrownTypes = Record.size() >= 21;
|
||||
DISubprogram::DISPFlags SPFlags = DISubprogram::toSPFlags(
|
||||
/*IsLocalToUnit=*/Record[7], /*IsDefinition=*/Record[8],
|
||||
/*IsOptimized=*/Record[14], /*Virtuality=*/Record[11]);
|
||||
if (HasSPFlags && !HasUnit)
|
||||
return error("Invalid record");
|
||||
// Accommodate older formats.
|
||||
bool HasFn = false;
|
||||
bool HasThisAdj = true;
|
||||
bool HasThrownTypes = true;
|
||||
unsigned OffsetA = 0;
|
||||
unsigned OffsetB = 0;
|
||||
if (!HasSPFlags) {
|
||||
OffsetA = 2;
|
||||
OffsetB = 2;
|
||||
if (Record.size() >= 19) {
|
||||
HasFn = !HasUnit;
|
||||
OffsetB++;
|
||||
}
|
||||
HasThisAdj = Record.size() >= 20;
|
||||
HasThrownTypes = Record.size() >= 21;
|
||||
}
|
||||
Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]);
|
||||
DISubprogram *SP = GET_OR_DISTINCT(
|
||||
DISubprogram,
|
||||
(Context,
|
||||
@ -1432,17 +1452,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
||||
getMDOrNull(Record[4]), // file
|
||||
Record[5], // line
|
||||
getMDOrNull(Record[6]), // type
|
||||
Record[9], // scopeLine
|
||||
getDITypeRefOrNull(Record[10]), // containingType
|
||||
Record[12], // virtualIndex
|
||||
HasThisAdj ? Record[19] : 0, // thisAdjustment
|
||||
static_cast<DINode::DIFlags>(Record[13]), // flags
|
||||
Record[7 + OffsetA], // scopeLine
|
||||
getDITypeRefOrNull(Record[8 + OffsetA]), // containingType
|
||||
Record[10 + OffsetA], // virtualIndex
|
||||
HasThisAdj ? Record[16 + OffsetB] : 0, // thisAdjustment
|
||||
static_cast<DINode::DIFlags>(Record[11 + OffsetA]),// flags
|
||||
SPFlags, // SPFlags
|
||||
HasUnit ? CUorFn : nullptr, // unit
|
||||
getMDOrNull(Record[15 + Offset]), // templateParams
|
||||
getMDOrNull(Record[16 + Offset]), // declaration
|
||||
getMDOrNull(Record[17 + Offset]), // retainedNodes
|
||||
HasThrownTypes ? getMDOrNull(Record[20]) : nullptr // thrownTypes
|
||||
getMDOrNull(Record[13 + OffsetB]), // templateParams
|
||||
getMDOrNull(Record[14 + OffsetB]), // declaration
|
||||
getMDOrNull(Record[15 + OffsetB]), // retainedNodes
|
||||
HasThrownTypes ? getMDOrNull(Record[17 + OffsetB])
|
||||
: nullptr // thrownTypes
|
||||
));
|
||||
MetadataList.assignValue(SP, NextMetadataNo);
|
||||
NextMetadataNo++;
|
||||
|
@ -1633,22 +1633,20 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N,
|
||||
void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N,
|
||||
SmallVectorImpl<uint64_t> &Record,
|
||||
unsigned Abbrev) {
|
||||
uint64_t HasUnitFlag = 1 << 1;
|
||||
Record.push_back(N->isDistinct() | HasUnitFlag);
|
||||
const uint64_t HasUnitFlag = 1 << 1;
|
||||
const uint64_t HasSPFlagsFlag = 1 << 2;
|
||||
Record.push_back(uint64_t(N->isDistinct()) | HasUnitFlag | HasSPFlagsFlag);
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
|
||||
Record.push_back(N->getLine());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getType()));
|
||||
Record.push_back(N->isLocalToUnit());
|
||||
Record.push_back(N->isDefinition());
|
||||
Record.push_back(N->getScopeLine());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getContainingType()));
|
||||
Record.push_back(N->getVirtuality());
|
||||
Record.push_back(N->getSPFlags());
|
||||
Record.push_back(N->getVirtualIndex());
|
||||
Record.push_back(N->getFlags());
|
||||
Record.push_back(N->isOptimized());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawUnit()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));
|
||||
|
@ -1607,6 +1607,7 @@ struct MDFieldPrinter {
|
||||
void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
|
||||
void printBool(StringRef Name, bool Value, Optional<bool> Default = None);
|
||||
void printDIFlags(StringRef Name, DINode::DIFlags Flags);
|
||||
void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
|
||||
template <class IntTy, class Stringifier>
|
||||
void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
|
||||
bool ShouldSkipZero = true);
|
||||
@ -1705,6 +1706,30 @@ void MDFieldPrinter::printDIFlags(StringRef Name, DINode::DIFlags Flags) {
|
||||
Out << FlagsFS << Extra;
|
||||
}
|
||||
|
||||
void MDFieldPrinter::printDISPFlags(StringRef Name,
|
||||
DISubprogram::DISPFlags Flags) {
|
||||
// Always print this field, because no flags in the IR at all will be
|
||||
// interpreted as old-style isDefinition: true.
|
||||
Out << FS << Name << ": ";
|
||||
|
||||
if (!Flags) {
|
||||
Out << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SmallVector<DISubprogram::DISPFlags, 8> SplitFlags;
|
||||
auto Extra = DISubprogram::splitFlags(Flags, SplitFlags);
|
||||
|
||||
FieldSeparator FlagsFS(" | ");
|
||||
for (auto F : SplitFlags) {
|
||||
auto StringF = DISubprogram::getFlagString(F);
|
||||
assert(!StringF.empty() && "Expected valid flag");
|
||||
Out << FlagsFS << StringF;
|
||||
}
|
||||
if (Extra || SplitFlags.empty())
|
||||
Out << FlagsFS << Extra;
|
||||
}
|
||||
|
||||
void MDFieldPrinter::printEmissionKind(StringRef Name,
|
||||
DICompileUnit::DebugEmissionKind EK) {
|
||||
Out << FS << Name << ": " << DICompileUnit::emissionKindString(EK);
|
||||
@ -1925,18 +1950,14 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
|
||||
Printer.printMetadata("file", N->getRawFile());
|
||||
Printer.printInt("line", N->getLine());
|
||||
Printer.printMetadata("type", N->getRawType());
|
||||
Printer.printBool("isLocal", N->isLocalToUnit());
|
||||
Printer.printBool("isDefinition", N->isDefinition());
|
||||
Printer.printInt("scopeLine", N->getScopeLine());
|
||||
Printer.printMetadata("containingType", N->getRawContainingType());
|
||||
Printer.printDwarfEnum("virtuality", N->getVirtuality(),
|
||||
dwarf::VirtualityString);
|
||||
if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
|
||||
N->getVirtualIndex() != 0)
|
||||
Printer.printInt("virtualIndex", N->getVirtualIndex(), false);
|
||||
Printer.printInt("thisAdjustment", N->getThisAdjustment());
|
||||
Printer.printDIFlags("flags", N->getFlags());
|
||||
Printer.printBool("isOptimized", N->isOptimized());
|
||||
Printer.printDISPFlags("spFlags", N->getSPFlags());
|
||||
Printer.printMetadata("unit", N->getRawUnit());
|
||||
Printer.printMetadata("templateParams", N->getRawTemplateParams());
|
||||
Printer.printMetadata("declaration", N->getRawDeclaration());
|
||||
|
@ -542,6 +542,40 @@ DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {
|
||||
return const_cast<DILocalScope *>(this);
|
||||
}
|
||||
|
||||
DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) {
|
||||
return StringSwitch<DISPFlags>(Flag)
|
||||
#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
|
||||
#include "llvm/IR/DebugInfoFlags.def"
|
||||
.Default(SPFlagZero);
|
||||
}
|
||||
|
||||
StringRef DISubprogram::getFlagString(DISPFlags Flag) {
|
||||
switch (Flag) {
|
||||
case SPFlagVirtuality: // Appease a warning.
|
||||
return "";
|
||||
#define HANDLE_DISP_FLAG(ID, NAME) \
|
||||
case SPFlag##NAME: \
|
||||
return "DISPFlag" #NAME;
|
||||
#include "llvm/IR/DebugInfoFlags.def"
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
DISubprogram::DISPFlags
|
||||
DISubprogram::splitFlags(DISPFlags Flags,
|
||||
SmallVectorImpl<DISPFlags> &SplitFlags) {
|
||||
// Multi-bit fields can require special handling. In our case, however, the
|
||||
// only multi-bit field is virtuality, and all its values happen to be
|
||||
// single-bit values, so the right behavior just falls out.
|
||||
#define HANDLE_DISP_FLAG(ID, NAME) \
|
||||
if (DISPFlags Bit = Flags & SPFlag##NAME) { \
|
||||
SplitFlags.push_back(Bit); \
|
||||
Flags &= ~Bit; \
|
||||
}
|
||||
#include "llvm/IR/DebugInfoFlags.def"
|
||||
return Flags;
|
||||
}
|
||||
|
||||
DISubprogram *DISubprogram::getImpl(
|
||||
LLVMContext &Context, Metadata *Scope, MDString *Name,
|
||||
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
|
||||
|
@ -6,8 +6,8 @@ define void @_Z3foov() !dbg !9 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14}
|
||||
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15}
|
||||
|
||||
!0 = !{null}
|
||||
!1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
|
||||
@ -17,7 +17,7 @@ define void @_Z3foov() !dbg !9 {
|
||||
!5 = distinct !{}
|
||||
!6 = distinct !{}
|
||||
|
||||
; CHECK: !7 = distinct !DISubprogram(scope: null, isLocal: false, isDefinition: true, isOptimized: false, unit: !8)
|
||||
; CHECK: !7 = distinct !DISubprogram(scope: null, spFlags: DISPFlagDefinition, unit: !8)
|
||||
!7 = distinct !DISubprogram(unit: !8)
|
||||
|
||||
!8 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang",
|
||||
@ -25,10 +25,10 @@ define void @_Z3foov() !dbg !9 {
|
||||
isOptimized: true, flags: "-O2",
|
||||
splitDebugFilename: "abc.debug", emissionKind: 2)
|
||||
|
||||
; CHECK: !9 = !DISubprogram(scope: null, isLocal: false, isDefinition: false, isOptimized: false)
|
||||
; CHECK: !9 = !DISubprogram(scope: null, spFlags: 0)
|
||||
!9 = !DISubprogram(isDefinition: false)
|
||||
|
||||
; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, isLocal: true, isDefinition: true, scopeLine: 8, containingType: !4, virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn, isOptimized: true, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6)
|
||||
; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6)
|
||||
!10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, isLocal: true,
|
||||
isDefinition: true, scopeLine: 8,
|
||||
@ -63,12 +63,21 @@ define void @_Z3foov() !dbg !9 {
|
||||
|
||||
!13 = !{!4}
|
||||
; CHECK: !13 = !{!4}
|
||||
; CHECK: !14 = distinct !DISubprogram(name: "foo", scope: !1, file: !2, line: 1, type: !3, isLocal: true, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !8, thrownTypes: !13)
|
||||
; CHECK: !14 = distinct !DISubprogram(name: "foo", scope: !1, file: !2, line: 1, type: !3, scopeLine: 2, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !8, thrownTypes: !13)
|
||||
!14 = distinct !DISubprogram(name: "foo", scope: !1,
|
||||
file: !2, line: 1, type: !3, isLocal: true,
|
||||
isDefinition: true, scopeLine: 2, isOptimized: false,
|
||||
unit: !8, thrownTypes: !13)
|
||||
|
||||
!15 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!llvm.module.flags = !{!15}
|
||||
; CHECK: !15 = distinct !DISubprogram({{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized,
|
||||
!15 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, scopeLine: 8,
|
||||
containingType: !4, virtualIndex: 0,
|
||||
flags: DIFlagPrototyped,
|
||||
spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized,
|
||||
unit: !8, templateParams: !5, declaration: !9,
|
||||
retainedNodes: !6)
|
||||
|
||||
!16 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!llvm.module.flags = !{!16}
|
||||
!llvm.dbg.cu = !{!8}
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK: <stdin>:[[@LINE+1]]:6: error: missing 'distinct', required for !DISubprogram when 'isDefinition'
|
||||
; CHECK: <stdin>:[[@LINE+1]]:6: error: missing 'distinct', required for !DISubprogram that is a Definition
|
||||
!0 = !DISubprogram(isDefinition: true)
|
||||
|
@ -43,7 +43,7 @@
|
||||
; CHECK-NEXT: !17 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !18, file: !1, size: 192, elements: !19, runtimeLang: DW_LANG_C89, identifier: "MyStruct")
|
||||
; CHECK-NEXT: !18 = !DINamespace(name: "NameSpace", scope: !6)
|
||||
; CHECK-NEXT: !19 = !{!11, !11, !11}
|
||||
; CHECK-NEXT: !20 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !21, isLocal: true, isDefinition: true, scopeLine: 42, isOptimized: false, unit: !0, retainedNodes: !26)
|
||||
; CHECK-NEXT: !20 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !21, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !26)
|
||||
; CHECK-NEXT: !21 = !DISubroutineType(types: !22)
|
||||
; CHECK-NEXT: !22 = !{!11, !11, !23}
|
||||
; CHECK-NEXT: !23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 640, flags: DIFlagVector, elements: !24)
|
||||
|
@ -9,6 +9,6 @@ define void @f() !dbg !3 { ret void }
|
||||
!0 = distinct !DICompileUnit(language: 12, file: !1, subprograms: !{!3})
|
||||
!1 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
|
||||
|
||||
; CHECK: = distinct !DISubprogram({{.*}}, isDefinition: true
|
||||
; CHECK: = distinct !DISubprogram({{.*}} DISPFlagDefinition
|
||||
!3 = !DISubprogram(name: "foo", isDefinition: true)
|
||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
|
86
test/Bitcode/DISubprogram-v4.ll
Normal file
86
test/Bitcode/DISubprogram-v4.ll
Normal file
@ -0,0 +1,86 @@
|
||||
; The .bc file was generated from this source using llvm-as from r347766.
|
||||
; A 7.0 release version should work to recreate it if necessary.
|
||||
; RUN: llvm-dis < %s.bc | FileCheck %s
|
||||
|
||||
; CHECK: define void @_Z3foov() !dbg !9
|
||||
define void @_Z3foov() !dbg !9 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18}
|
||||
|
||||
!0 = !{null}
|
||||
!1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
|
||||
!2 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
|
||||
!3 = !DISubroutineType(types: !0)
|
||||
!4 = distinct !DICompositeType(tag: DW_TAG_structure_type)
|
||||
!5 = distinct !{}
|
||||
!6 = distinct !{}
|
||||
|
||||
; CHECK: !7 = distinct !DISubprogram(scope: null, spFlags: DISPFlagDefinition, unit: !8)
|
||||
!7 = distinct !DISubprogram(unit: !8)
|
||||
|
||||
!8 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang",
|
||||
file: !2, isOptimized: true, flags: "-O2")
|
||||
|
||||
; CHECK: !9 = !DISubprogram(scope: null, spFlags: 0)
|
||||
!9 = !DISubprogram(isDefinition: false)
|
||||
|
||||
; CHECK: !10 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized,
|
||||
!10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: true, isDefinition: true, isOptimized: true,
|
||||
virtuality: DW_VIRTUALITY_pure_virtual,
|
||||
unit: !8)
|
||||
|
||||
; CHECK: !11 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized,
|
||||
!11 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: true, isDefinition: true, isOptimized: true,
|
||||
virtuality: DW_VIRTUALITY_virtual,
|
||||
unit: !8)
|
||||
|
||||
; CHECK: !12 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized,
|
||||
!12 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: true, isDefinition: true, isOptimized: true,
|
||||
virtuality: DW_VIRTUALITY_none,
|
||||
unit: !8)
|
||||
|
||||
; CHECK: !13 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized,
|
||||
!13 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: false, isDefinition: true, isOptimized: true,
|
||||
unit: !8)
|
||||
|
||||
; CHECK: !14 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagLocalToUnit | DISPFlagOptimized)
|
||||
!14 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: true, isDefinition: false, isOptimized: true)
|
||||
|
||||
; CHECK: !15 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition,
|
||||
!15 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: true, isDefinition: true, isOptimized: false,
|
||||
unit: !8)
|
||||
|
||||
; CHECK: !16 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagLocalToUnit)
|
||||
!16 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: true, isDefinition: false, isOptimized: false)
|
||||
|
||||
; CHECK: !17 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagDefinition,
|
||||
!17 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: false, isDefinition: true, isOptimized: false,
|
||||
unit: !8)
|
||||
|
||||
; CHECK: !18 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagOptimized)
|
||||
!18 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
|
||||
file: !2, line: 7, type: !3, containingType: !4,
|
||||
isLocal: false, isDefinition: false, isOptimized: true)
|
||||
|
||||
!19 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!llvm.module.flags = !{!19}
|
||||
!llvm.dbg.cu = !{!8}
|
BIN
test/Bitcode/DISubprogram-v4.ll.bc
Normal file
BIN
test/Bitcode/DISubprogram-v4.ll.bc
Normal file
Binary file not shown.
@ -3,9 +3,9 @@
|
||||
; Make sure we emit this diagnostic only once (which means we don't visit the
|
||||
; same DISubprogram twice.
|
||||
; CHECK: subprogram definitions must have a compile unit
|
||||
; CHECK-NEXT: !3 = distinct !DISubprogram(name: "patatino", scope: null, isLocal: false, isDefinition: true, isOptimized: false)
|
||||
; CHECK-NEXT: !3 = distinct !DISubprogram(name: "patatino", scope: null, spFlags: DISPFlagDefinition)
|
||||
; CHECK-NOT: subprogram definitions must have a compile unit
|
||||
; CHECK-NOT: !3 = distinct !DISubprogram(name: "patatino", scope: null, isLocal: false, isDefinition: true, isOptimized: false)
|
||||
; CHECK-NOT: !3 = distinct !DISubprogram(name: "patatino", scope: null, spFlags: DISPFlagDefinition)
|
||||
; CHECK: warning: ignoring invalid debug info
|
||||
|
||||
define void @tinkywinky() !dbg !3 { ret void }
|
||||
|
@ -63,8 +63,8 @@ define i32 @boom() {
|
||||
|
||||
; CHECK-DAG: ![[CU]] = distinct !DICompileUnit(language: DW_LANG_C, file: {{.*}}, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: {{.*}})
|
||||
; CHECK-DAG: !DIFile(filename: "<stdin>", directory: "/")
|
||||
; CHECK-DAG: distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: {{.*}}, line: 1, type: {{.*}}, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: {{.*}}, retainedNodes: {{.*}})
|
||||
; CHECK-DAG: distinct !DISubprogram(name: "bar", linkageName: "bar", scope: null, file: {{.*}}, line: 2, type: {{.*}}, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: {{.*}}, retainedNodes: {{.*}})
|
||||
; CHECK-DAG: distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: {{.*}}, line: 1, type: {{.*}}, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: {{.*}}, retainedNodes: {{.*}})
|
||||
; CHECK-DAG: distinct !DISubprogram(name: "bar", linkageName: "bar", scope: null, file: {{.*}}, line: 2, type: {{.*}}, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: {{.*}}, retainedNodes: {{.*}})
|
||||
|
||||
; --- DILocations
|
||||
; CHECK-DAG: ![[RET1]] = !DILocation(line: 1, column: 1
|
||||
|
@ -54,7 +54,7 @@ entry:
|
||||
|
||||
; We can't use CHECK-NOT/CHECK-SAME with a CHECK-DAG, so rely on field order to
|
||||
; prove that there's no function: here.
|
||||
; CHECK-DAG: ![[SP2r:.*]] = {{.*}}!DISubprogram({{.*}} isOptimized: false, unit: ![[CU1]], retainedNodes:
|
||||
; CHECK-DAG: ![[SP2r:.*]] = {{.*}}!DISubprogram({{.*}} unit: ![[CU1]], retainedNodes:
|
||||
!7 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 2, file: !8, scope: !9, type: !6, retainedNodes: !2)
|
||||
|
||||
; The new subprogram should be pointing at the new directory.
|
||||
|
@ -19,7 +19,7 @@ entry:
|
||||
!1 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky")
|
||||
!2 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky")
|
||||
!3 = !{}
|
||||
!5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, retainedNodes: !3)
|
||||
!5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 1, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, retainedNodes: !3)
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DILocation(line: 1, scope: !5)
|
||||
|
Loading…
Reference in New Issue
Block a user