diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index f975c234ea7..f067384d1fe 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -165,7 +165,8 @@ namespace bitc { METADATA_GLOBAL_VAR = 27, // [distinct, ...] METADATA_LOCAL_VAR = 28, // [distinct, ...] METADATA_EXPRESSION = 29, // [distinct, n x element] - METADATA_OBJC_PROPERTY = 30 // [distinct, name, file, line, ...] + METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...] + METADATA_IMPORTED_ENTITY=31 // [distinct, tag, scope, entity, line, name] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 3ddadbaa714..8058bbe8385 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -1626,6 +1626,8 @@ public: Metadata *getEntity() const { return getOperand(1); } StringRef getName() const { return getStringOperand(2); } + MDString *getRawName() const { return getOperandAs(2); } + static bool classof(const Metadata *MD) { return MD->getMetadataID() == MDImportedEntityKind; } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 360e8a49c8f..fc829166abf 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -3658,9 +3658,24 @@ bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) { return false; } +/// ParseMDImportedEntity: +/// ::= !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, +/// line: 7, name: "foo") bool LLParser::ParseMDImportedEntity(MDNode *&Result, bool IsDistinct) { - return TokError("unimplemented parser"); +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + REQUIRED(tag, DwarfTagField, ); \ + REQUIRED(scope, MDField, ); \ + OPTIONAL(entity, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(name, MDStringField, ); + PARSE_MD_FIELDS(); +#undef VISIT_MD_FIELDS + + Result = GET_OR_DISTINCT(MDImportedEntity, (Context, tag.Val, scope.Val, + entity.Val, line.Val, name.Val)); + return false; } + #undef PARSE_MD_FIELD #undef NOP_FIELD #undef REQUIRE_FIELD diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 5430ebcb231..358c6f2b898 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1575,6 +1575,18 @@ std::error_code BitcodeReader::ParseMetadata() { NextMDValueNo++); break; } + case bitc::METADATA_IMPORTED_ENTITY: { + if (Record.size() != 6) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDImportedEntity, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDString(Record[5]))), + NextMDValueNo++); + break; + } case bitc::METADATA_STRING: { std::string String(Record.begin(), Record.end()); llvm::UpgradeMDStringConstant(String); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index ee522c41d16..0a3c57e8c26 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1124,10 +1124,20 @@ static void WriteMDObjCProperty(const MDObjCProperty *N, Record.clear(); } -static void WriteMDImportedEntity(const MDImportedEntity *, - const ValueEnumerator &, BitstreamWriter &, - SmallVectorImpl &, unsigned) { - llvm_unreachable("write not implemented"); +static void WriteMDImportedEntity(const MDImportedEntity *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getEntity())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + + Stream.EmitRecord(bitc::METADATA_IMPORTED_ENTITY, Record, Abbrev); + Record.clear(); } static void WriteModuleMetadata(const Module *M, diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index c363da2f560..6248f3e7c3c 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1827,12 +1827,25 @@ static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N, Out << ")"; } -static void writeMDImportedEntity(raw_ostream &, const MDImportedEntity *, - TypePrinting *, SlotTracker *, - const Module *) { - llvm_unreachable("write not implemented"); +static void writeMDImportedEntity(raw_ostream &Out, const MDImportedEntity *N, + TypePrinting *TypePrinter, + SlotTracker *Machine, const Module *Context) { + Out << "!MDImportedEntity("; + FieldSeparator FS; + writeTag(Out, FS, N); + Out << FS << "scope: "; + writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context); + if (N->getEntity()) { + Out << FS << "entity: "; + writeMetadataAsOperand(Out, N->getEntity(), TypePrinter, Machine, Context); + } + if (N->getLine()) + Out << FS << "line: " << N->getLine(); + Out << FS << "name: \"" << N->getName() << "\""; + Out << ")"; } + static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, TypePrinting *TypePrinter, SlotTracker *Machine, diff --git a/test/Assembler/invalid-mdimportedentity-missing-parent.ll b/test/Assembler/invalid-mdimportedentity-missing-parent.ll new file mode 100644 index 00000000000..710a0276480 --- /dev/null +++ b/test/Assembler/invalid-mdimportedentity-missing-parent.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK: [[@LINE+1]]:51: error: missing required field 'scope' +!3 = !MDImportedEntity(tag: DW_TAG_imported_module) diff --git a/test/Assembler/invalid-mdimportedentity-missing-tag.ll b/test/Assembler/invalid-mdimportedentity-missing-tag.ll new file mode 100644 index 00000000000..63cf0d25650 --- /dev/null +++ b/test/Assembler/invalid-mdimportedentity-missing-tag.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK: [[@LINE+1]]:33: error: missing required field 'tag' +!3 = !MDImportedEntity(scope: !0) diff --git a/test/Assembler/mdimportedentity.ll b/test/Assembler/mdimportedentity.ll new file mode 100644 index 00000000000..a1ac48d550f --- /dev/null +++ b/test/Assembler/mdimportedentity.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; RUN: verify-uselistorder %s + +; CHECK: !named = !{!0, !1, !2, !3, !3} +!named = !{!0, !1, !2, !3, !4} + +; CHECK: !0 = distinct !{} +; CHECK-NEXT: !1 = distinct !{} +!0 = distinct !{} +!1 = distinct !{} + +; CHECK-NEXT: !2 = !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, line: 7, name: "foo") +!2 = !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, + line: 7, name: "foo") + +; CHECK-NEXT: !3 = !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0, name: "") +!3 = !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0) +!4 = !MDImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: null, + line: 0, name: "") +