]> granicus.if.org Git - llvm/commitdiff
[codeview] Add support for splitting field list records over 64KB
authorReid Kleckner <rnk@google.com>
Tue, 21 Jun 2016 18:33:01 +0000 (18:33 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 21 Jun 2016 18:33:01 +0000 (18:33 +0000)
The basic structure is that once a list record goes over 64K, the last
subrecord of the list is an LF_INDEX record that refers to the next
record. Because the type record graph must be toplogically sorted, this
means we have to emit them in reverse order. We build the type record in
order of declaration, so this means that if we don't want extra copies,
we need to detect when we were about to split a record, and leave space
for a continuation subrecord that will point to the eventual split
top-level record.

Also adds dumping support for these records.

Next we should make sure that large method overload lists work properly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273294 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h
include/llvm/DebugInfo/CodeView/ListRecordBuilder.h
include/llvm/DebugInfo/CodeView/TypeRecord.h
include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h
include/llvm/DebugInfo/CodeView/TypeRecords.def
lib/DebugInfo/CodeView/ListRecordBuilder.cpp
lib/DebugInfo/CodeView/TypeDumper.cpp
lib/DebugInfo/CodeView/TypeRecord.cpp
lib/DebugInfo/CodeView/TypeTableBuilder.cpp
test/DebugInfo/COFF/enum.ll
test/DebugInfo/COFF/types-data-members.ll
test/DebugInfo/COFF/types-non-virtual-methods.ll
test/DebugInfo/COFF/types-recursive-struct.ll
test/DebugInfo/PDB/pdbdump-headers.test

index 1fa20891608d95516924bb102663332200e9d7cc..75a075157d228a07ed00a9dc1773c2c9472a8d77 100644 (file)
@@ -47,7 +47,7 @@ private:
 public:
   FieldListRecordBuilder();
 
-  void reset() { ListRecordBuilder::reset(TypeRecordKind::FieldList); }
+  void reset() { ListRecordBuilder::reset(); }
 
   void writeBaseClass(const BaseClassRecord &Record);
   void writeEnumerator(const EnumeratorRecord &Record);
index 0e058d27bb0e77a522886bd4c137a74aaf598b6c..cc53b53fe50a9dd5b0f17a530ecfea2efc943c22 100644 (file)
@@ -14,6 +14,7 @@
 
 namespace llvm {
 namespace codeview {
+class TypeTableBuilder;
 
 class ListRecordBuilder {
 private:
@@ -28,13 +29,16 @@ protected:
 public:
   llvm::StringRef str() { return Builder.str(); }
 
-  void reset(TypeRecordKind K) {
-    Builder.reset(K);
+  void reset() {
+    Builder.reset(Kind);
     ContinuationOffsets.clear();
-    SubrecordCount = 0;
+    SubrecordStart = 0;
   }
 
-  unsigned getSubrecordCount() { return SubrecordCount; }
+  void writeListContinuation(const ListContinuationRecord &R);
+
+  /// Writes this list record as a possible sequence of records.
+  TypeIndex writeListRecord(TypeTableBuilder &Table);
 
 protected:
   void finishSubRecord();
@@ -42,9 +46,18 @@ protected:
   TypeRecordBuilder &getBuilder() { return Builder; }
 
 private:
+  size_t getLastContinuationStart() const {
+    return ContinuationOffsets.empty() ? 0 : ContinuationOffsets.back();
+  }
+  size_t getLastContinuationEnd() const { return Builder.size(); }
+  unsigned getLastContinuationSize() const {
+    return getLastContinuationEnd() - getLastContinuationStart();
+  }
+
+  TypeRecordKind Kind;
   TypeRecordBuilder Builder;
   SmallVector<size_t, 4> ContinuationOffsets;
-  unsigned SubrecordCount = 0;
+  size_t SubrecordStart = 0;
 };
 }
 }
index 17f31e12db1b492e839edfa982701f3ab2739ec1..1ec05292c3d60ae63d53f1a733cfad604b735aa8 100644 (file)
@@ -1169,6 +1169,29 @@ private:
   uint64_t VTableIndex;
 };
 
+/// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
+/// together. The first will end in an LF_INDEX record that points to the next.
+class ListContinuationRecord : public TypeRecord {
+public:
+  ListContinuationRecord(TypeIndex ContinuationIndex)
+      : TypeRecord(TypeRecordKind::ListContinuation),
+        ContinuationIndex(ContinuationIndex) {}
+
+  TypeIndex getContinuationIndex() const { return ContinuationIndex; }
+
+  bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
+
+  static ErrorOr<ListContinuationRecord> deserialize(TypeRecordKind Kind,
+                                                     ArrayRef<uint8_t> &Data);
+
+private:
+  struct Layout {
+    ulittle16_t Pad0;
+    TypeIndex ContinuationIndex;
+  };
+  TypeIndex ContinuationIndex;
+};
+
 typedef CVRecord<TypeLeafKind> CVType;
 typedef VarStreamArray<CVType> CVTypeArray;
 }
index 75a8c51ff2163f0f096a96562234388f6cfacffc..010d06e5e310ed006512420c21b3b2e8c905fdb6 100644 (file)
@@ -43,11 +43,18 @@ public:
   void writeNullTerminatedString(const char *Value);
   void writeNullTerminatedString(StringRef Value);
   void writeGuid(StringRef Guid);
+  void writeBytes(StringRef Value) { Stream << Value; }
 
   llvm::StringRef str();
 
   uint64_t size() const { return Stream.tell(); }
 
+  void truncate(uint64_t Size) {
+    // This works because raw_svector_ostream is not buffered.
+    assert(Size < Buffer.size());
+    Buffer.resize(Size);
+  }
+
   void reset(TypeRecordKind K) {
     Buffer.clear();
     writeTypeRecordKind(K);
index 41fbeaa5be6d8089eb3de7c6d5d5b4fdae96a431..0959f4bf19c7110ab5c84114f5cab34202f4a0e9 100644 (file)
@@ -71,6 +71,7 @@ MEMBER_RECORD(LF_MEMBER, 0x150d, DataMember)
 MEMBER_RECORD(LF_NESTTYPE, 0x1510, NestedType)
 MEMBER_RECORD(LF_ONEMETHOD, 0x1511, OneMethod)
 MEMBER_RECORD(LF_ENUMERATE, 0x1502, Enumerator)
+MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation)
 
 // ID leaf records. Subsequent leaf types may be referenced from .debug$S.
 TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId)
@@ -168,7 +169,6 @@ CV_TYPE(LF_DIMVARLU, 0x120a)
 // Member type records. These are generally not length prefixed, and appear
 // inside of a field list record.
 CV_TYPE(LF_FRIENDFCN_ST, 0x1403)
-CV_TYPE(LF_INDEX, 0x1404)
 CV_TYPE(LF_MEMBER_ST, 0x1405)
 CV_TYPE(LF_STMEMBER_ST, 0x1406)
 CV_TYPE(LF_METHOD_ST, 0x1407)
index 5bec65a36df86511416f7b636c7a9b08696ab03b..eab5add310ea42a00616fa9d2012b0367ccc8f12 100644 (file)
@@ -7,27 +7,92 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/DebugInfo/CodeView/ListRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
 
 using namespace llvm;
 using namespace codeview;
 
-ListRecordBuilder::ListRecordBuilder(TypeRecordKind Kind) : Builder(Kind) {}
+ListRecordBuilder::ListRecordBuilder(TypeRecordKind Kind)
+    : Kind(Kind), Builder(Kind) {}
 
-void ListRecordBuilder::finishSubRecord() {
-  SubrecordCount++;
+void ListRecordBuilder::writeListContinuation(const ListContinuationRecord &R) {
+  TypeRecordBuilder &Builder = getBuilder();
+
+  assert(getLastContinuationSize() < 65535 - 8 && "continuation won't fit");
+
+  Builder.writeTypeRecordKind(TypeRecordKind::ListContinuation);
+  Builder.writeUInt16(0);
+  Builder.writeTypeIndex(R.getContinuationIndex());
+
+  // End the current segment manually so that nothing comes after the
+  // continuation.
+  ContinuationOffsets.push_back(Builder.size());
+  SubrecordStart = Builder.size();
+}
 
+void ListRecordBuilder::finishSubRecord() {
   // The builder starts at offset 2 in the actual CodeView buffer, so add an
   // additional offset of 2 before computing the alignment.
   uint32_t Remainder = (Builder.size() + 2) % 4;
   if (Remainder != 0) {
     for (int32_t PaddingBytesLeft = 4 - Remainder; PaddingBytesLeft > 0;
          --PaddingBytesLeft) {
-      Builder.writeUInt8(0xf0 + PaddingBytesLeft);
+      Builder.writeUInt8(LF_PAD0 + PaddingBytesLeft);
     }
   }
 
-  // TODO: Split the list into multiple records if it's longer than 64KB, using
-  // a subrecord of TypeRecordKind::Index to chain the records together.
-  assert(Builder.size() < 65536);
+  // Check if this subrecord makes the current segment not fit in 64K minus the
+  // space for a continuation record (8 bytes). If the segment does not fit,
+  // back up and insert a continuation record, sliding the current subrecord
+  // down.
+  if (getLastContinuationSize() > 65535 - 8) {
+    SmallString<128> SubrecordCopy(Builder.str().slice(SubrecordStart, Builder.size()));
+    Builder.truncate(SubrecordStart);
+
+    // Write a placeholder continuation record.
+    Builder.writeTypeRecordKind(TypeRecordKind::ListContinuation);
+    Builder.writeUInt16(0);
+    Builder.writeUInt32(0);
+    ContinuationOffsets.push_back(Builder.size());
+    assert(Builder.size() == SubrecordStart + 8 && "wrong continuation size");
+    assert(getLastContinuationSize() < 65535 && "segment too big");
+
+    // Start a new list record of the appropriate kind, and copy the previous
+    // subrecord into place.
+    Builder.writeTypeRecordKind(Kind);
+    Builder.writeBytes(SubrecordCopy);
+  }
+
+  SubrecordStart = Builder.size();
+}
+
+TypeIndex ListRecordBuilder::writeListRecord(TypeTableBuilder &Table) {
+  // Get the continuation segments as a reversed vector of StringRefs for
+  // convenience.
+  SmallVector<StringRef, 1> Segments;
+  StringRef Data = str();
+  size_t LastEnd = 0;
+  for (size_t SegEnd : ContinuationOffsets) {
+    Segments.push_back(Data.slice(LastEnd, SegEnd));
+    LastEnd = SegEnd;
+  }
+  Segments.push_back(Data.slice(LastEnd, Builder.size()));
+
+  // Pop the last record off and emit it directly.
+  StringRef LastRec = Segments.pop_back_val();
+  TypeIndex ContinuationIndex = Table.writeRecord(LastRec);
+
+  // Emit each record with a continuation in reverse order, so that each one
+  // references the previous record.
+  for (StringRef Rec : reverse(Segments)) {
+    assert(*reinterpret_cast<const ulittle16_t *>(Rec.data()) ==
+           unsigned(Kind));
+    ulittle32_t *ContinuationPtr =
+        reinterpret_cast<ulittle32_t *>(const_cast<char *>(Rec.end())) - 1;
+    *ContinuationPtr = ContinuationIndex.getIndex();
+    ContinuationIndex = Table.writeRecord(Rec);
+  }
+  return ContinuationIndex;
 }
index 316bbb43a11a1f2791e8ff548c55361be4dd8093..2ff91e727eecd1ed8bb881633d7cb0314c325fdc 100644 (file)
@@ -195,6 +195,8 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
   case ename:                                                                  \
     return #name;
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
+  case LF_FIELDLIST:
+    return "FieldList";
   default:
     break;
   }
@@ -214,6 +216,9 @@ Error CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
 }
 
 Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+  if (Record.Type == LF_FIELDLIST)
+    Name = "<field list>";
+
   // Always record some name for every type, even if Name is empty. CVUDTNames
   // is indexed by type index, and must have one entry for every type.
   recordType(Name);
@@ -612,6 +617,12 @@ Error CVTypeDumper::visitVirtualBaseClass(VirtualBaseClassRecord &Base) {
   return Error::success();
 }
 
+Error CVTypeDumper::visitListContinuation(ListContinuationRecord &Cont) {
+  DictScope S(*W, "ListContinuation");
+  printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
+  return Error::success();
+}
+
 StringRef CVTypeDumper::getTypeName(TypeIndex TI) {
   if (TI.isNoneType())
     return "<no type>";
index cc09abcd988262bd1fe6909047b85f02ffa25e96..40f963fe25a845eb196b3b5507a590682dabdd08 100644 (file)
@@ -365,6 +365,14 @@ VirtualBaseClassRecord::deserialize(TypeRecordKind Kind,
                                 Offset, Index);
 }
 
+ErrorOr<ListContinuationRecord>
+ListContinuationRecord::deserialize(TypeRecordKind Kind,
+                                    ArrayRef<uint8_t> &Data) {
+  const Layout *L = nullptr;
+  CV_DESERIALIZE(Data, L);
+  return ListContinuationRecord(L->ContinuationIndex);
+}
+
 //===----------------------------------------------------------------------===//
 // Type index remapping
 //===----------------------------------------------------------------------===//
@@ -556,3 +564,7 @@ bool VirtualBaseClassRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
   Success &= remapIndex(IndexMap, VBPtrType);
   return Success;
 }
+
+bool ListContinuationRecord::remapTypeIndices(ArrayRef<TypeIndex> IndexMap) {
+  return remapIndex(IndexMap, ContinuationIndex);
+}
index 7ac9581db3f7860d0d68261639a5081687044d34..647538ee8ceb6efc2a9924db706fcc1021e86b6d 100644 (file)
@@ -267,9 +267,7 @@ TypeIndex TypeTableBuilder::writeRecord(TypeRecordBuilder &Builder) {
 }
 
 TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) {
-  // TODO: Split the list into multiple records if it's longer than 64KB, using
-  // a subrecord of TypeRecordKind::Index to chain the records together.
-  return writeRecord(FieldList.str());
+  return FieldList.writeListRecord(*this);
 }
 
 TypeIndex TypeTableBuilder::writeMethodOverloadList(
index ca177deb64dbe80d3d30f24bf79b51d6029b33c3..118aee1f8437b9169fdea3fabe8b18bb9103f671 100644 (file)
@@ -5,7 +5,7 @@
 ; E e;
 
 ; CHECK:     CodeViewTypes [
-; CHECK:       UnknownLeaf (0x1000) {
+; CHECK:       FieldList (0x1000) {
 ; CHECK-NEXT:    TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK-NEXT:    Enumerator {
 ; CHECK-NEXT:      AccessSpecifier: Public (0x3)
@@ -19,7 +19,7 @@
 ; CHECK-NEXT:    Properties [ (0x0)
 ; CHECK-NEXT:    ]
 ; CHECK-NEXT:    UnderlyingType: int (0x74)
-; CHECK-NEXT:    FieldListType: BLAH (0x1000)
+; CHECK-NEXT:    FieldListType: <field list> (0x1000)
 ; CHECK-NEXT:    Name: E
 ; CHECK-NEXT:  }
 
index 785d2b8905d1f02086cdc0c07d1c2571dc7c63b9..963c74454d50d287e4d0aa316f91d70541b2e1f3 100644 (file)
@@ -81,7 +81,7 @@
 ; CHECK:       Const (0x1)
 ; CHECK:     ]
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1005) {
+; CHECK:   FieldList (0x1005) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     Properties [ (0x200)
 ; CHECK:       HasUniqueName (0x200)
 ; CHECK:     ]
-; CHECK:     FieldList: sdm (0x1005)
+; CHECK:     FieldList: <field list> (0x1005)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 12
 ; CHECK:     Name: Union
 ; CHECK:     LinkageName: .?ATUnion@@
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1008) {
+; CHECK:   FieldList (0x1008) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     Properties [ (0x200)
 ; CHECK:       HasUniqueName (0x200)
 ; CHECK:     ]
-; CHECK:     FieldList: b (0x1008)
+; CHECK:     FieldList: <field list> (0x1008)
 ; CHECK:     SizeOf: 4
 ; CHECK:     Name: Union
 ; CHECK:     LinkageName: .?ATUnion@@
 ; CHECK:     SizeOf: 0
 ; CHECK:     Name: Class
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x100B) {
+; CHECK:   FieldList (0x100B) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     Properties [ (0x200)
 ; CHECK:       HasUniqueName (0x200)
 ; CHECK:     ]
-; CHECK:     FieldList: prot (0x100B)
+; CHECK:     FieldList: <field list> (0x100B)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 12
 ; CHECK:     IsVolatile: 0
 ; CHECK:     IsUnaligned: 0
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1011) {
+; CHECK:   FieldList (0x1011) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     Properties [ (0x200)
 ; CHECK:       HasUniqueName (0x200)
 ; CHECK:     ]
-; CHECK:     FieldList: d (0x1011)
+; CHECK:     FieldList: <field list> (0x1011)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 48
 ; CHECK:     Name: Nested
 ; CHECK:     LinkageName: .?AUNested@Class@@
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1014) {
+; CHECK:   FieldList (0x1014) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     Properties [ (0x200)
 ; CHECK:       HasUniqueName (0x200)
 ; CHECK:     ]
-; CHECK:     FieldList: n (0x1014)
+; CHECK:     FieldList: <field list> (0x1014)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 4
index b2fb6c59917ec4106c7953f280c7917990d36e78..f4d3b5431bc6bf4f6dcf15129b5ed88f30f7c906 100644 (file)
@@ -84,7 +84,7 @@
 ; CHECK:     ArgListType: () (0x1000)
 ; CHECK:     ThisAdjustment: 0
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1006) {
+; CHECK:   FieldList (0x1006) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     OneMethod {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     MemberCount: 4
 ; CHECK:     Properties [ (0x0)
 ; CHECK:     ]
-; CHECK:     FieldList: A::f_public (0x1006)
+; CHECK:     FieldList: <field list> (0x1006)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 1
 ; CHECK:       Type: void B::(int) (0x100E)
 ; CHECK:     ]
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1010) {
+; CHECK:   FieldList (0x1010) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     OneMethod {
 ; CHECK:       AccessSpecifier: Private (0x1)
 ; CHECK:     MemberCount: 3
 ; CHECK:     Properties [ (0x0)
 ; CHECK:     ]
-; CHECK:     FieldList: B::f (0x1010)
+; CHECK:     FieldList: <field list> (0x1010)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 1
index 5351a1666e0142ff19d37a62a95822f530694857..88bab35e20f583fc3f5c604802067f1187c1f02f 100644 (file)
@@ -77,7 +77,7 @@
 ; CHECK:     IsVolatile: 0
 ; CHECK:     IsUnaligned: 0
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1006) {
+; CHECK:   FieldList (0x1006) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     MemberCount: 1
 ; CHECK:     Properties [ (0x0)
 ; CHECK:     ]
-; CHECK:     FieldList: b (0x1006)
+; CHECK:     FieldList: <field list> (0x1006)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 8
 ; CHECK:     Name: A
 ; CHECK:   }
-; CHECK:   UnknownLeaf (0x1008) {
+; CHECK:   FieldList (0x1008) {
 ; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
 ; CHECK:     DataMember {
 ; CHECK:       AccessSpecifier: Public (0x3)
 ; CHECK:     MemberCount: 1
 ; CHECK:     Properties [ (0x0)
 ; CHECK:     ]
-; CHECK:     FieldList: a (0x1008)
+; CHECK:     FieldList: <field list> (0x1008)
 ; CHECK:     DerivedFrom: 0x0
 ; CHECK:     VShape: 0x0
 ; CHECK:     SizeOf: 8
index 2539f00505e84f1104a1ba9fd6716a7ed1a94785..c9c8d13eb3636dd71f24e3a8292855e043a560e7 100644 (file)
 ; EMPTY-NEXT:       )
 ; EMPTY-NEXT:     }
 ; EMPTY-NEXT:     {
-; EMPTY-NEXT:       UnknownLeaf (0x1002) {
+; EMPTY-NEXT:       FieldList (0x1002) {
 ; EMPTY-NEXT:         TypeLeafKind: LF_FIELDLIST (0x1203)
 ; EMPTY-NEXT:         Enumerator {
 ; EMPTY-NEXT:           AccessSpecifier: Public (0x3)
 ; ALL:     {
 ; ALL:       StringId (0x1058) {
 ; ALL:         TypeLeafKind: LF_STRING_ID (0x1605)
-; ALL:         Id: managed (0x100C)
+; ALL:         Id: <field list> (0x100C)
 ; ALL:         StringData:  Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TP -X
 ; ALL:       }
 ; ALL:     }
 ; ALL:           ArgType: void __vc_attributes::threadingAttribute::(__vc_attributes::threadingAttribute::threading_e) (0x1007)
 ; ALL:           ArgType: void __vc_attributes::threadingAttribute::() (0x1008)
 ; ALL:           ArgType: 0x1009
-; ALL:           ArgType: value (0x100A)
+; ALL:           ArgType: <field list> (0x100A)
 ; ALL:           ArgType: __vc_attributes::event_receiverAttribute::type_e (0x100D)
 ; ALL:         ]
 ; ALL:       }