AsmWriter/Bitcode: MDDerivedType and MDCompositeType

llvm-svn: 229009
This commit is contained in:
Duncan P. N. Exon Smith 2015-02-13 01:20:38 +00:00
parent d6346e6f3e
commit 171d077ae4
9 changed files with 265 additions and 23 deletions

View File

@ -151,7 +151,9 @@ namespace bitc {
METADATA_SUBRANGE = 13, // [distinct, count, lo] METADATA_SUBRANGE = 13, // [distinct, count, lo]
METADATA_ENUMERATOR = 14, // [distinct, value, name?] METADATA_ENUMERATOR = 14, // [distinct, value, name?]
METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc] METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc]
METADATA_FILE = 16 // [distinct, filename, directory] METADATA_FILE = 16, // [distinct, filename, directory]
METADATA_DERIVED_TYPE = 17, // [distinct, ...]
METADATA_COMPOSITE_TYPE= 18 // [distinct, ...]
}; };
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each // The constants block (CONSTANTS_BLOCK_ID) describes emission for each

View File

@ -3233,12 +3233,61 @@ bool LLParser::ParseMDBasicType(MDNode *&Result, bool IsDistinct) {
return false; return false;
} }
/// ParseMDDerivedType:
/// ::= !MDDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,
/// line: 7, scope: !1, baseType: !2, size: 32,
/// align: 32, offset: 0, flags: 0, extraData: !3)
bool LLParser::ParseMDDerivedType(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseMDDerivedType(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser"); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
OPTIONAL(name, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(scope, MDField, ); \
REQUIRED(baseType, MDField, ); \
OPTIONAL(size, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(extraData, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(MDDerivedType,
(Context, tag.Val, name.Val, file.Val, line.Val,
scope.Val, baseType.Val, size.Val, align.Val,
offset.Val, flags.Val, extraData.Val));
return false;
} }
bool LLParser::ParseMDCompositeType(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseMDCompositeType(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser"); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
OPTIONAL(name, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(scope, MDField, ); \
OPTIONAL(baseType, MDField, ); \
OPTIONAL(size, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(elements, MDField, ); \
OPTIONAL(runtimeLang, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(vtableHolder, MDField, ); \
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(identifier, MDStringField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(
MDCompositeType,
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));
return false;
} }
bool LLParser::ParseMDSubroutineType(MDNode *&Result, bool IsDistinct) { bool LLParser::ParseMDSubroutineType(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser"); return TokError("unimplemented parser");
} }

View File

@ -1183,12 +1183,17 @@ std::error_code BitcodeReader::ParseMetadata() {
SmallVector<uint64_t, 64> Record; SmallVector<uint64_t, 64> Record;
auto getMD =
[&](unsigned ID) -> Metadata *{ return MDValueList.getValueFwdRef(ID); };
auto getMDOrNull = [&](unsigned ID) -> Metadata *{
if (ID)
return getMD(ID - 1);
return nullptr;
};
auto getMDString = [&](unsigned ID) -> MDString *{ auto getMDString = [&](unsigned ID) -> MDString *{
// This requires that the ID is not really a forward reference. In // This requires that the ID is not really a forward reference. In
// particular, the MDString must already have been resolved. // particular, the MDString must already have been resolved.
if (ID) return cast_or_null<MDString>(getMDOrNull(ID));
return cast<MDString>(MDValueList.getValueFwdRef(ID - 1));
return nullptr;
}; };
#define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \ #define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \
@ -1382,6 +1387,36 @@ std::error_code BitcodeReader::ParseMetadata() {
NextMDValueNo++); NextMDValueNo++);
break; break;
} }
case bitc::METADATA_DERIVED_TYPE: {
if (Record.size() != 12)
return Error("Invalid record");
MDValueList.AssignValue(
GET_OR_DISTINCT(MDDerivedType, Record[0],
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), Record[4],
getMDOrNull(Record[5]), getMD(Record[6]), Record[7],
Record[8], Record[9], Record[10],
getMDOrNull(Record[11]))),
NextMDValueNo++);
break;
}
case bitc::METADATA_COMPOSITE_TYPE: {
if (Record.size() != 16)
return Error("Invalid record");
MDValueList.AssignValue(
GET_OR_DISTINCT(MDCompositeType, Record[0],
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), Record[4],
getMDOrNull(Record[5]), getMDOrNull(Record[6]),
Record[7], Record[8], Record[9], Record[10],
getMDOrNull(Record[11]), Record[12],
getMDOrNull(Record[13]), getMDOrNull(Record[14]),
getMDString(Record[15]))),
NextMDValueNo++);
break;
}
case bitc::METADATA_FILE: { case bitc::METADATA_FILE: {
if (Record.size() != 3) if (Record.size() != 3)
return Error("Invalid record"); return Error("Invalid record");

View File

@ -853,16 +853,54 @@ static void WriteMDBasicType(const MDBasicType *N, const ValueEnumerator &VE,
Record.clear(); Record.clear();
} }
static void WriteMDDerivedType(const MDDerivedType *, const ValueEnumerator &, static void WriteMDDerivedType(const MDDerivedType *N,
BitstreamWriter &, SmallVectorImpl<uint64_t> &, const ValueEnumerator &VE,
unsigned) { BitstreamWriter &Stream,
llvm_unreachable("write not implemented"); SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
Record.push_back(N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Record.push_back(N->getLine());
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataID(N->getBaseType()));
Record.push_back(N->getSizeInBits());
Record.push_back(N->getAlignInBits());
Record.push_back(N->getOffsetInBits());
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getExtraData()));
Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev);
Record.clear();
} }
static void WriteMDCompositeType(const MDCompositeType *,
const ValueEnumerator &, BitstreamWriter &, static void WriteMDCompositeType(const MDCompositeType *N,
SmallVectorImpl<uint64_t> &, unsigned) { const ValueEnumerator &VE,
llvm_unreachable("write not implemented"); BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
Record.push_back(N->isDistinct());
Record.push_back(N->getTag());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Record.push_back(N->getLine());
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
Record.push_back(N->getSizeInBits());
Record.push_back(N->getAlignInBits());
Record.push_back(N->getOffsetInBits());
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getElements()));
Record.push_back(N->getRuntimeLang());
Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder()));
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams()));
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
Record.clear();
} }
static void WriteMDSubroutineType(const MDSubroutineType *, static void WriteMDSubroutineType(const MDSubroutineType *,
const ValueEnumerator &, BitstreamWriter &, const ValueEnumerator &, BitstreamWriter &,
SmallVectorImpl<uint64_t> &, unsigned) { SmallVectorImpl<uint64_t> &, unsigned) {

View File

@ -1387,15 +1387,97 @@ static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
Out << ")"; Out << ")";
} }
static void writeMDDerivedType(raw_ostream &, const MDDerivedType *, static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
TypePrinting *, SlotTracker *, const Module *) { TypePrinting *TypePrinter, SlotTracker *Machine,
llvm_unreachable("write not implemented"); const Module *Context) {
Out << "!MDDerivedType(";
FieldSeparator FS;
writeTag(Out, FS, N);
if (!N->getName().empty())
Out << FS << "name: \"" << N->getName() << "\"";
if (N->getFile()) {
Out << FS << "file: ";
writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
Context);
}
if (N->getLine())
Out << FS << "line: " << N->getLine();
if (N->getScope()) {
Out << FS << "scope: ";
writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
}
Out << FS << "baseType: ";
writeMetadataAsOperand(Out, N->getBaseType(), TypePrinter, Machine, Context);
if (N->getSizeInBits())
Out << FS << "size: " << N->getSizeInBits();
if (N->getAlignInBits())
Out << FS << "align: " << N->getAlignInBits();
if (N->getOffsetInBits())
Out << FS << "offset: " << N->getOffsetInBits();
if (N->getFlags())
Out << FS << "flags: " << N->getFlags();
if (N->getExtraData()) {
Out << FS << "extraData: ";
writeMetadataAsOperand(Out, N->getExtraData(), TypePrinter, Machine,
Context);
}
Out << ")";
} }
static void writeMDCompositeType(raw_ostream &, const MDCompositeType *,
TypePrinting *, SlotTracker *, static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
const Module *) { TypePrinting *TypePrinter,
llvm_unreachable("write not implemented"); SlotTracker *Machine, const Module *Context) {
Out << "!MDCompositeType(";
FieldSeparator FS;
writeTag(Out, FS, N);
if (!N->getName().empty())
Out << FS << "name: \"" << N->getName() << "\"";
if (N->getFile()) {
Out << FS << "file: ";
writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
Context);
}
if (N->getLine())
Out << FS << "line: " << N->getLine();
if (N->getScope()) {
Out << FS << "scope: ";
writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
}
if (N->getBaseType()) {
Out << FS << "baseType: ";
writeMetadataAsOperand(Out, N->getBaseType(), TypePrinter, Machine,
Context);
}
if (N->getSizeInBits())
Out << FS << "size: " << N->getSizeInBits();
if (N->getAlignInBits())
Out << FS << "align: " << N->getAlignInBits();
if (N->getOffsetInBits())
Out << FS << "offset: " << N->getOffsetInBits();
if (N->getFlags())
Out << FS << "flags: " << N->getFlags();
if (N->getElements()) {
Out << FS << "elements: ";
writeMetadataAsOperand(Out, N->getElements(), TypePrinter, Machine,
Context);
}
if (N->getRuntimeLang())
Out << FS << "runtimeLang: " << N->getRuntimeLang();
if (N->getVTableHolder()) {
Out << FS << "vtableHolder: ";
writeMetadataAsOperand(Out, N->getVTableHolder(), TypePrinter, Machine,
Context);
}
if (N->getTemplateParams()) {
Out << FS << "templateParams: ";
writeMetadataAsOperand(Out, N->getTemplateParams(), TypePrinter, Machine,
Context);
}
if (!N->getIdentifier().empty())
Out << FS << "identifier: \"" << N->getIdentifier() << "\"";
Out << ")";
} }
static void writeMDSubroutineType(raw_ostream &, const MDSubroutineType *, static void writeMDSubroutineType(raw_ostream &, const MDSubroutineType *,
TypePrinting *, SlotTracker *, TypePrinting *, SlotTracker *,
const Module *) { const Module *) {

View File

@ -1,8 +1,8 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
; RUN: verify-uselistorder %s ; RUN: verify-uselistorder %s
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12} ; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23}
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14} !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25}
; CHECK: !0 = !MDSubrange(count: 3) ; CHECK: !0 = !MDSubrange(count: 3)
; CHECK-NEXT: !1 = !MDSubrange(count: 3, lowerBound: 4) ; CHECK-NEXT: !1 = !MDSubrange(count: 3, lowerBound: 4)
@ -36,3 +36,27 @@
!12 = !MDFile(filename: "path/to/file", directory: "/path/to/dir") !12 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
!13 = !{null, null} !13 = !{null, null}
!14 = !MDFile(filename: "", directory: "") !14 = !MDFile(filename: "", directory: "")
; CHECK-NEXT: !13 = !MDDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 32, align: 32)
!15 = !MDDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32)
; CHECK-NEXT: !14 = !MDCompositeType(tag: DW_TAG_structure_type, name: "MyType", file: !9, line: 2, size: 32, align: 32, identifier: "MangledMyType")
; CHECK-NEXT: !15 = distinct !MDCompositeType(tag: DW_TAG_structure_type, name: "Base", file: !9, line: 3, scope: !14, size: 128, align: 32, offset: 64, flags: 3, elements: !16, runtimeLang: 6, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
; CHECK-NEXT: !16 = !{!17}
; CHECK-NEXT: !17 = !MDDerivedType(tag: DW_TAG_member, name: "field", file: !9, line: 4, scope: !15, baseType: !6, size: 32, align: 32, offset: 32, flags: 3)
; CHECK-NEXT: !18 = !{!6}
; CHECK-NEXT: !19 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Derived", file: !9, line: 3, scope: !14, baseType: !15, size: 128, align: 32, offset: 64, flags: 3, elements: !20, runtimeLang: 6, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
; CHECK-NEXT: !20 = !{!21}
; CHECK-NEXT: !21 = !MDDerivedType(tag: DW_TAG_inheritance, scope: !19, baseType: !15)
; CHECK-NEXT: !22 = !MDDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !6, size: 32, align: 32, extraData: !15)
; CHECK-NEXT: !23 = !MDCompositeType(tag: DW_TAG_structure_type)
!16 = !MDCompositeType(tag: DW_TAG_structure_type, name: "MyType", file: !11, line: 2, size: 32, align: 32, identifier: "MangledMyType")
!17 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Base", file: !11, line: 3, scope: !16, size: 128, align: 32, offset: 64, flags: 3, elements: !18, runtimeLang: 6, vtableHolder: !17, templateParams: !20, identifier: "MangledBase")
!18 = !{!19}
!19 = !MDDerivedType(tag: DW_TAG_member, name: "field", file: !11, line: 4, scope: !17, baseType: !7, size: 32, align: 32, offset: 32, flags: 3)
!20 = !{!7}
!21 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Derived", file: !11, line: 3, scope: !16, baseType: !17, size: 128, align: 32, offset: 64, flags: 3, elements: !22, runtimeLang: 6, vtableHolder: !17, templateParams: !20, identifier: "MangledBase")
!22 = !{!23}
!23 = !MDDerivedType(tag: DW_TAG_inheritance, scope: !21, baseType: !17)
!24 = !MDDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !7, size: 32, align: 32, extraData: !17)
!25 = !MDCompositeType(tag: DW_TAG_structure_type)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:36: error: missing required field 'tag'
!25 = !MDCompositeType(name: "Type")

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:45: error: missing required field 'baseType'
!0 = !MDDerivedType(tag: DW_TAG_pointer_type)

View File

@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
; CHECK: [[@LINE+1]]:34: error: missing required field 'tag'
!0 = !MDDerivedType(baseType: !{})