summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp5
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp63
-rw-r--r--llvm/lib/AsmParser/LLToken.h1
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp63
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp10
-rw-r--r--llvm/lib/IR/AsmWriter.cpp31
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp34
7 files changed, 168 insertions, 39 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 045214590d8..eab7ec81953 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -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;
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index bcc881926bb..c94b62bad65 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -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,
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index 836d9a06562..c2e2795a946 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -442,6 +442,7 @@ enum Kind {
NameTableKind, // GNU
DwarfOp, // DW_OP_foo
DIFlag, // DIFlagFoo
+ DISPFlag, // DISPFlagFoo
DwarfMacinfo, // DW_MACINFO_foo
ChecksumKind, // CSK_foo
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 08a6ab5d847..3289aa0acdd 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -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++;
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 9f6027c34df..29d0f87d826 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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()));
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index b74b158def8..23aee723205 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -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());
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index bf3b284fcce..be98577eda5 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -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,
OpenPOWER on IntegriCloud