summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--llvm/include/llvm/IR/DebugInfoMetadata.h3
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp64
-rw-r--r--llvm/lib/AsmParser/LLParser.h3
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp16
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp32
-rw-r--r--llvm/lib/IR/AsmWriter.cpp63
-rw-r--r--llvm/test/Assembler/invalid-mdsubprogram-missing-name.ll4
-rw-r--r--llvm/test/Assembler/mdsubprogram.ll28
9 files changed, 203 insertions, 13 deletions
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index be35428fa05..1936e3434d6 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -155,7 +155,8 @@ namespace bitc {
METADATA_DERIVED_TYPE = 17, // [distinct, ...]
METADATA_COMPOSITE_TYPE= 18, // [distinct, ...]
METADATA_SUBROUTINE_TYPE=19, // [distinct, flags, types]
- METADATA_COMPILE_UNIT = 20 // [distinct, ...]
+ METADATA_COMPILE_UNIT = 20, // [distinct, ...]
+ METADATA_SUBPROGRAM = 21 // [distinct, ...]
};
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 6c47f755827..64af1a873ef 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -957,6 +957,9 @@ public:
StringRef getDisplayName() const { return getStringOperand(3); }
StringRef getLinkageName() const { return getStringOperand(4); }
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
+
Metadata *getType() const { return getOperand(5); }
Metadata *getContainingType() const { return getOperand(6); }
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d7bf205ce00..9c3bb4a5836 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2969,6 +2969,9 @@ struct MDBoolField : public MDFieldImpl<bool> {
struct MDField : public MDFieldImpl<Metadata *> {
MDField() : ImplTy(nullptr) {}
};
+struct MDConstant : public MDFieldImpl<ConstantAsMetadata *> {
+ MDConstant() : ImplTy(nullptr) {}
+};
struct MDStringField : public MDFieldImpl<std::string> {
MDStringField() : ImplTy(std::string()) {}
};
@@ -3098,6 +3101,12 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) {
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
+ if (Lex.getKind() == lltok::kw_null) {
+ Lex.Lex();
+ Result.assign(nullptr);
+ return false;
+ }
+
Metadata *MD;
if (ParseMetadata(MD, nullptr))
return true;
@@ -3107,6 +3116,16 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
}
template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDConstant &Result) {
+ Metadata *MD;
+ if (ParseValueAsMetadata(MD, "expected constant", nullptr))
+ return true;
+
+ Result.assign(cast<ConstantAsMetadata>(MD));
+ return false;
+}
+
+template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
std::string S;
if (ParseStringConstant(S))
@@ -3385,9 +3404,45 @@ bool LLParser::ParseMDCompileUnit(MDNode *&Result, bool IsDistinct) {
return false;
}
+/// ParseMDSubprogram:
+/// ::= !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoo",
+/// file: !1, line: 7, type: !2, isLocal: false,
+/// isDefinition: true, scopeLine: 8, containingType: !3,
+/// virtuality: 2, virtualIndex: 10, flags: 11,
+/// isOptimized: false, function: void ()* @_Z3foov,
+/// templateParams: !4, declaration: !5, variables: !6)
bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) {
- return TokError("unimplemented parser");
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(scope, MDField, ); \
+ REQUIRED(name, MDStringField, ); \
+ OPTIONAL(linkageName, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(type, MDField, ); \
+ OPTIONAL(isLocal, MDBoolField, ); \
+ OPTIONAL(isDefinition, MDBoolField, (true)); \
+ OPTIONAL(scopeLine, LineField, ); \
+ OPTIONAL(containingType, MDField, ); \
+ OPTIONAL(virtuality, MDUnsignedField, (0, dwarf::DW_VIRTUALITY_max)); \
+ OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(isOptimized, MDBoolField, ); \
+ OPTIONAL(function, MDConstant, ); \
+ OPTIONAL(templateParams, MDField, ); \
+ OPTIONAL(declaration, MDField, ); \
+ OPTIONAL(variables, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(
+ MDSubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val,
+ line.Val, type.Val, isLocal.Val, isDefinition.Val,
+ scopeLine.Val, containingType.Val, virtuality.Val,
+ virtualIndex.Val, flags.Val, isOptimized.Val, function.Val,
+ templateParams.Val, declaration.Val, variables.Val));
+ return false;
}
+
bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser");
}
@@ -3444,10 +3499,11 @@ bool LLParser::ParseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
/// ::= i32 %local
/// ::= i32 @global
/// ::= i32 7
-bool LLParser::ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS) {
+bool LLParser::ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
+ PerFunctionState *PFS) {
Type *Ty;
LocTy Loc;
- if (ParseType(Ty, "expected metadata operand", Loc))
+ if (ParseType(Ty, TypeMsg, Loc))
return true;
if (Ty->isMetadataTy())
return Error(Loc, "invalid metadata-value-metadata roundtrip");
@@ -3480,7 +3536,7 @@ bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
// ValueAsMetadata:
// <type> <value>
if (Lex.getKind() != lltok::exclaim)
- return ParseValueAsMetadata(MD, PFS);
+ return ParseValueAsMetadata(MD, "expected metadata operand", PFS);
// '!'.
assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h
index 368c3054b19..5e92e570e72 100644
--- a/llvm/lib/AsmParser/LLParser.h
+++ b/llvm/lib/AsmParser/LLParser.h
@@ -385,7 +385,8 @@ namespace llvm {
bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts);
bool parseOptionalComdat(StringRef GlobalName, Comdat *&C);
bool ParseMetadataAsValue(Value *&V, PerFunctionState &PFS);
- bool ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS);
+ bool ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
+ PerFunctionState *PFS);
bool ParseMetadata(Metadata *&MD, PerFunctionState *PFS);
bool ParseMDTuple(MDNode *&MD, bool IsDistinct = false);
bool ParseMDNode(MDNode *&MD);
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index d1c122f70ab..12996d19e0d 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1452,6 +1452,22 @@ std::error_code BitcodeReader::ParseMetadata() {
NextMDValueNo++);
break;
}
+ case bitc::METADATA_SUBPROGRAM: {
+ if (Record.size() != 19)
+ return Error("Invalid record");
+
+ MDValueList.AssignValue(
+ GET_OR_DISTINCT(
+ MDSubprogram, Record[0],
+ (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
+ getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
+ getMDOrNull(Record[6]), Record[7], Record[8], Record[9],
+ getMDOrNull(Record[10]), Record[11], Record[12], Record[13],
+ Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]),
+ getMDOrNull(Record[17]), getMDOrNull(Record[18]))),
+ NextMDValueNo++);
+ break;
+ }
case bitc::METADATA_STRING: {
std::string String(Record.begin(), Record.end());
llvm::UpgradeMDStringConstant(String);
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 5e27f30a48d..f0453fff122 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -949,11 +949,35 @@ static void WriteMDCompileUnit(const MDCompileUnit *N,
Record.clear();
}
-static void WriteMDSubprogram(const MDSubprogram *, const ValueEnumerator &,
- BitstreamWriter &, SmallVectorImpl<uint64_t> &,
- unsigned) {
- llvm_unreachable("write not implemented");
+static void WriteMDSubprogram(const MDSubprogram *N,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ 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->getVirtualIndex());
+ Record.push_back(N->getFlags());
+ Record.push_back(N->isOptimized());
+ Record.push_back(VE.getMetadataOrNullID(N->getFunction()));
+ Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams()));
+ Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));
+ Record.push_back(VE.getMetadataOrNullID(N->getVariables()));
+
+ Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev);
+ Record.clear();
}
+
static void WriteMDLexicalBlock(const MDLexicalBlock *, const ValueEnumerator &,
BitstreamWriter &, SmallVectorImpl<uint64_t> &,
unsigned) {
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index cf002e4d7f9..fbc12ae7ec4 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1557,10 +1557,67 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
Out << ")";
}
-static void writeMDSubprogram(raw_ostream &, const MDSubprogram *,
- TypePrinting *, SlotTracker *, const Module *) {
- llvm_unreachable("write not implemented");
+static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!MDSubprogram(";
+ FieldSeparator FS;
+ Out << FS << "scope: ";
+ writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
+ Out << FS << "name: \"" << N->getName() << "\"";
+ if (!N->getLinkageName().empty())
+ Out << FS << "linkageName: \"" << N->getLinkageName() << "\"";
+ if (N->getFile()) {
+ Out << FS << "file: ";
+ writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
+ Context);
+ }
+ if (N->getLine())
+ Out << FS << "line: " << N->getLine();
+ if (N->getType()) {
+ Out << FS << "type: ";
+ writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
+ Context);
+ }
+ Out << FS << "isLocal: " << (N->isLocalToUnit() ? "true" : "false");
+ Out << FS << "isDefinition: " << (N->isDefinition() ? "true" : "false");
+ if (N->getScopeLine())
+ Out << FS << "scopeLine: " << N->getScopeLine();
+ if (N->getContainingType()) {
+ Out << FS << "containingType: ";
+ writeMetadataAsOperand(Out, N->getContainingType(), TypePrinter, Machine,
+ Context);
+ }
+ if (N->getVirtuality())
+ Out << FS << "virtuality: " << N->getVirtuality();
+ if (N->getVirtualIndex())
+ Out << FS << "virtualIndex: " << N->getVirtualIndex();
+ if (N->getFlags())
+ Out << FS << "flags: " << N->getFlags();
+ Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
+ if (N->getFunction()) {
+ Out << FS << "function: ";
+ writeMetadataAsOperand(Out, N->getFunction(), TypePrinter, Machine,
+ Context);
+ }
+ if (N->getTemplateParams()) {
+ Out << FS << "templateParams: ";
+ writeMetadataAsOperand(Out, N->getTemplateParams(), TypePrinter, Machine,
+ Context);
+ }
+ if (N->getDeclaration()) {
+ Out << FS << "declaration: ";
+ writeMetadataAsOperand(Out, N->getDeclaration(), TypePrinter, Machine,
+ Context);
+ }
+ if (N->getVariables()) {
+ Out << FS << "variables: ";
+ writeMetadataAsOperand(Out, N->getVariables(), TypePrinter, Machine,
+ Context);
+ }
+ Out << ")";
}
+
static void writeMDLexicalBlock(raw_ostream &, const MDLexicalBlock *,
TypePrinting *, SlotTracker *, const Module *) {
llvm_unreachable("write not implemented");
diff --git a/llvm/test/Assembler/invalid-mdsubprogram-missing-name.ll b/llvm/test/Assembler/invalid-mdsubprogram-missing-name.ll
new file mode 100644
index 00000000000..54ded222231
--- /dev/null
+++ b/llvm/test/Assembler/invalid-mdsubprogram-missing-name.ll
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: <stdin>:[[@LINE+1]]:38: error: missing required field 'name'
+!0 = !MDSubprogram(linkageName: "foo")
diff --git a/llvm/test/Assembler/mdsubprogram.ll b/llvm/test/Assembler/mdsubprogram.ll
new file mode 100644
index 00000000000..cbf907b6107
--- /dev/null
+++ b/llvm/test/Assembler/mdsubprogram.ll
@@ -0,0 +1,28 @@
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+
+declare void @_Z3foov()
+
+; 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 = !{!"path/to/file", !"/path/to/dir"}
+!2 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
+!3 = distinct !{}
+!4 = distinct !{}
+!5 = distinct !{}
+!6 = distinct !{}
+!7 = distinct !{}
+
+; CHECK: !8 = !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoov", file: !2, line: 7, type: !3, isLocal: true, isDefinition: false, scopeLine: 8, containingType: !4, virtuality: 2, virtualIndex: 10, flags: 11, isOptimized: true, function: void ()* @_Z3foov, templateParams: !5, declaration: !6, variables: !7)
+!8 = !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoov",
+ file: !2, line: 7, type: !3, isLocal: true,
+ isDefinition: false, scopeLine: 8, containingType: !4,
+ virtuality: 2, virtualIndex: 10, flags: 11,
+ isOptimized: true, function: void ()* @_Z3foov,
+ templateParams: !5, declaration: !6, variables: !7)
+
+; CHECK: !9 = !MDSubprogram(scope: null, name: "bar", isLocal: false, isDefinition: true, isOptimized: false)
+!9 = !MDSubprogram(name: "bar")
+
OpenPOWER on IntegriCloud