diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 63 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 63 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 34 |
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, |