AsmWriter/Bitcode: MDSubprogram

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229014 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-02-13 01:26:47 +00:00
parent 37742c3591
commit ed356a925a
9 changed files with 203 additions and 13 deletions

View File

@ -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

View File

@ -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); }

View File

@ -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;
@ -3106,6 +3115,16 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
return false;
}
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;
@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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");

View File

@ -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")

View File

@ -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")