mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-30 15:10:33 +00:00
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:
parent
37742c3591
commit
ed356a925a
@ -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
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
4
test/Assembler/invalid-mdsubprogram-missing-name.ll
Normal file
4
test/Assembler/invalid-mdsubprogram-missing-name.ll
Normal 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")
|
28
test/Assembler/mdsubprogram.ll
Normal file
28
test/Assembler/mdsubprogram.ll
Normal 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")
|
||||
|
Loading…
Reference in New Issue
Block a user