AsmWriter/Bitcode: MDObjCProperty
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 13 Feb 2015 01:43:22 +0000 (01:43 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 13 Feb 2015 01:43:22 +0000 (01:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229024 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/LLVMBitCodes.h
include/llvm/IR/DebugInfoMetadata.h
lib/AsmParser/LLParser.cpp
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/IR/AsmWriter.cpp
test/Assembler/invalid-mdobjcproperty-missing-name.ll [new file with mode: 0644]
test/Assembler/mdobjcproperty.ll [new file with mode: 0644]

index 98b40d2..f975c23 100644 (file)
@@ -164,7 +164,8 @@ namespace bitc {
     METADATA_TEMPLATE_VALUE= 26,  // [distinct, scope, name, type, value, ...]
     METADATA_GLOBAL_VAR    = 27,  // [distinct, ...]
     METADATA_LOCAL_VAR     = 28,  // [distinct, ...]
-    METADATA_EXPRESSION    = 29   // [distinct, n x element]
+    METADATA_EXPRESSION    = 29,  // [distinct, n x element]
+    METADATA_OBJC_PROPERTY = 30   // [distinct, name, file, line, ...]
   };
 
   // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
index c9b0da9..3ddadba 100644 (file)
@@ -1570,6 +1570,10 @@ public:
   StringRef getSetterName() const { return getStringOperand(3); }
   Metadata *getType() const { return getOperand(4); }
 
+  MDString *getRawName() const { return getOperandAs<MDString>(0); }
+  MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
+  MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
+
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == MDObjCPropertyKind;
   }
index dc8367c..360e8a4 100644 (file)
@@ -3637,9 +3637,27 @@ bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) {
   return false;
 }
 
+/// ParseMDObjCProperty:
+///   ::= !MDObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo",
+///                       getter: "getFoo", attributes: 7, type: !2)
 bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) {
-  return TokError("unimplemented parser");
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
+  REQUIRED(name, MDStringField, );                                             \
+  OPTIONAL(file, MDField, );                                                   \
+  OPTIONAL(line, LineField, );                                                 \
+  OPTIONAL(setter, MDStringField, );                                           \
+  OPTIONAL(getter, MDStringField, );                                           \
+  OPTIONAL(attributes, MDUnsignedField, (0, UINT32_MAX));                      \
+  OPTIONAL(type, MDField, );
+  PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+  Result = GET_OR_DISTINCT(MDObjCProperty,
+                           (Context, name.Val, file.Val, line.Val, setter.Val,
+                            getter.Val, attributes.Val, type.Val));
+  return false;
 }
+
 bool LLParser::ParseMDImportedEntity(MDNode *&Result, bool IsDistinct) {
   return TokError("unimplemented parser");
 }
index 98b4803..5430ebc 100644 (file)
@@ -1562,6 +1562,19 @@ std::error_code BitcodeReader::ParseMetadata() {
           NextMDValueNo++);
       break;
     }
+    case bitc::METADATA_OBJC_PROPERTY: {
+      if (Record.size() != 8)
+        return Error("Invalid record");
+
+      MDValueList.AssignValue(
+          GET_OR_DISTINCT(MDObjCProperty, Record[0],
+                          (Context, getMDString(Record[1]),
+                           getMDOrNull(Record[2]), Record[3],
+                           getMDString(Record[4]), getMDString(Record[5]),
+                           Record[6], getMDOrNull(Record[7]))),
+          NextMDValueNo++);
+      break;
+    }
     case bitc::METADATA_STRING: {
       std::string String(Record.begin(), Record.end());
       llvm::UpgradeMDStringConstant(String);
index 6683e3e..ee522c4 100644 (file)
@@ -1106,11 +1106,24 @@ static void WriteMDExpression(const MDExpression *N, const ValueEnumerator &,
   Record.clear();
 }
 
-static void WriteMDObjCProperty(const MDObjCProperty *, const ValueEnumerator &,
-                                BitstreamWriter &, SmallVectorImpl<uint64_t> &,
-                                unsigned) {
-  llvm_unreachable("write not implemented");
+static void WriteMDObjCProperty(const MDObjCProperty *N,
+                                 const ValueEnumerator &VE,
+                                 BitstreamWriter &Stream,
+                                 SmallVectorImpl<uint64_t> &Record,
+                                 unsigned Abbrev) {
+  Record.push_back(N->isDistinct());
+  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->getRawSetterName()));
+  Record.push_back(VE.getMetadataOrNullID(N->getRawGetterName()));
+  Record.push_back(N->getAttributes());
+  Record.push_back(VE.getMetadataOrNullID(N->getType()));
+
+  Stream.EmitRecord(bitc::METADATA_OBJC_PROPERTY, Record, Abbrev);
+  Record.clear();
 }
+
 static void WriteMDImportedEntity(const MDImportedEntity *,
                                   const ValueEnumerator &, BitstreamWriter &,
                                   SmallVectorImpl<uint64_t> &, unsigned) {
index 5bfbe78..c363da2 100644 (file)
@@ -1802,10 +1802,31 @@ static void writeMDExpression(raw_ostream &Out, const MDExpression *N,
   Out << ")";
 }
 
-static void writeMDObjCProperty(raw_ostream &, const MDObjCProperty *,
-                                TypePrinting *, SlotTracker *, const Module *) {
-  llvm_unreachable("write not implemented");
+static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
+                                TypePrinting *TypePrinter, SlotTracker *Machine,
+                                const Module *Context) {
+  Out << "!MDObjCProperty(";
+  FieldSeparator FS;
+  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->getSetterName().empty())
+    Out << FS << "setter: \"" << N->getSetterName() << "\"";
+  if (!N->getGetterName().empty())
+    Out << FS << "getter: \"" << N->getGetterName() << "\"";
+  if (N->getAttributes())
+    Out << FS << "attributes: " << N->getAttributes();
+  if (N->getType()) {
+    Out << FS << "type: ";
+    writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
+  }
+  Out << ")";
 }
+
 static void writeMDImportedEntity(raw_ostream &, const MDImportedEntity *,
                                   TypePrinting *, SlotTracker *,
                                   const Module *) {
diff --git a/test/Assembler/invalid-mdobjcproperty-missing-name.ll b/test/Assembler/invalid-mdobjcproperty-missing-name.ll
new file mode 100644 (file)
index 0000000..b55cfa8
--- /dev/null
@@ -0,0 +1,4 @@
+; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
+
+; CHECK: [[@LINE+1]]:38: error: missing required field 'name'
+!0 = !MDObjCProperty(setter: "setFoo")
diff --git a/test/Assembler/mdobjcproperty.ll b/test/Assembler/mdobjcproperty.ll
new file mode 100644 (file)
index 0000000..fb44fb1
--- /dev/null
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+
+; CHECK: !named = !{!0, !1, !2, !3, !4, !4}
+!named = !{!0, !1, !2, !3, !4, !5}
+
+!0 = !{!"path/to/file", !"/path/to/dir"}
+!1 = !MDFile(filename: "path/to/file", directory: "/path/to/dir")
+!2 = distinct !{}
+
+
+; CHECK: !2 = distinct !{}
+; CHECK-NEXT: !3 = !MDObjCProperty(name: "foo", file: !0, line: 7, setter: "setFoo", getter: "getFoo", attributes: 7, type: !2)
+!3 = !MDObjCProperty(name: "foo", file: !0, line: 7, setter: "setFoo",
+                     getter: "getFoo", attributes: 7, type: !2)
+
+; CHECK-NEXT: !4 = !MDObjCProperty(name: "foo")
+!4 = !MDObjCProperty(name: "foo", file: null, line: 0, setter: "", getter: "",
+                     attributes: 0, type: null)
+!5 = !MDObjCProperty(name: "foo")