Merge pull request #22 from apple/ns-error-domain-3.0

[API Notes] Add support for the ns_error_domain attribute.
diff --git a/include/clang/APINotes/Types.h b/include/clang/APINotes/Types.h
index 11a1e7a..5d5a347 100644
--- a/include/clang/APINotes/Types.h
+++ b/include/clang/APINotes/Types.h
@@ -129,24 +129,33 @@
   /// Reflects the swift_bridge attribute.
   std::string SwiftBridge;
 
+  /// The NS error domain for this type.
+  std::string NSErrorDomain;
+
 public:
   CommonTypeInfo() : CommonEntityInfo() { }
 
   const std::string &getSwiftBridge() const { return SwiftBridge; }
   void setSwiftBridge(const std::string &swiftType) { SwiftBridge = swiftType; }
 
+  const std::string &getNSErrorDomain() const { return NSErrorDomain; }
+  void setNSErrorDomain(const std::string &domain) { NSErrorDomain = domain; }
+
   friend CommonTypeInfo &operator|=(CommonTypeInfo &lhs,
                                     const CommonTypeInfo &rhs) {
     static_cast<CommonEntityInfo &>(lhs) |= rhs;
     if (lhs.SwiftBridge.empty() && !rhs.SwiftBridge.empty())
       lhs.SwiftBridge = rhs.SwiftBridge;
+    if (lhs.NSErrorDomain.empty() && !rhs.NSErrorDomain.empty())
+      lhs.NSErrorDomain = rhs.NSErrorDomain;
     return lhs;
   }
 
   friend bool operator==(const CommonTypeInfo &lhs,
                          const CommonTypeInfo &rhs) {
     return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
-      lhs.SwiftBridge == rhs.SwiftBridge;
+      lhs.SwiftBridge == rhs.SwiftBridge &&
+      lhs.NSErrorDomain == rhs.NSErrorDomain;
   }
 
   friend bool operator!=(const CommonTypeInfo &lhs,
diff --git a/lib/APINotes/APINotesReader.cpp b/lib/APINotes/APINotesReader.cpp
index 44c628b..297004e 100644
--- a/lib/APINotes/APINotesReader.cpp
+++ b/lib/APINotes/APINotesReader.cpp
@@ -58,6 +58,12 @@
     info.setSwiftBridge(
         StringRef(reinterpret_cast<const char *>(data), swiftBridgeLength));
     data += swiftBridgeLength;
+
+    unsigned errorDomainLength =
+      endian::readNext<uint16_t, little, unaligned>(data);
+    info.setNSErrorDomain(
+        StringRef(reinterpret_cast<const char *>(data), errorDomainLength));
+    data += errorDomainLength;
   }
 
   /// Used to deserialize the on-disk identifier table.
diff --git a/lib/APINotes/APINotesWriter.cpp b/lib/APINotes/APINotesWriter.cpp
index 758f660..511efd3 100644
--- a/lib/APINotes/APINotesWriter.cpp
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -309,7 +309,9 @@
   // Retrieve the serialized size of the given CommonTypeInfo, for use
   // in on-disk hash tables.
   static unsigned getCommonTypeInfoSize(const CommonTypeInfo &info) {
-    return 2 + info.getSwiftBridge().size() + getCommonEntityInfoSize(info);
+    return 2 + info.getSwiftBridge().size() +
+           2 + info.getNSErrorDomain().size() +
+           getCommonEntityInfoSize(info);
   }
 
   /// Emit a serialized representation of the common type information.
@@ -318,6 +320,8 @@
     endian::Writer<little> writer(out);
     writer.write<uint16_t>(info.getSwiftBridge().size());
     out.write(info.getSwiftBridge().c_str(), info.getSwiftBridge().size());
+    writer.write<uint16_t>(info.getNSErrorDomain().size());
+    out.write(info.getNSErrorDomain().c_str(), info.getNSErrorDomain().size());
   }
 
   /// Used to serialize the on-disk Objective-C context table.
diff --git a/lib/APINotes/APINotesYAMLCompiler.cpp b/lib/APINotes/APINotesYAMLCompiler.cpp
index 310aed8..3e645ba 100644
--- a/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -197,6 +197,7 @@
     bool SwiftPrivate = false;
     StringRef SwiftName;
     StringRef SwiftBridge;
+    StringRef NSErrorDomain;
     MethodsSeq Methods;
     PropertiesSeq Properties;
   };
@@ -235,6 +236,7 @@
     StringRef SwiftName;
     bool SwiftPrivate = false;
     StringRef SwiftBridge;
+    StringRef NSErrorDomain;
   };
   typedef std::vector<Tag> TagsSeq;
 
@@ -244,6 +246,7 @@
     StringRef SwiftName;
     bool SwiftPrivate = false;
     StringRef SwiftBridge;
+    StringRef NSErrorDomain;
   };
   typedef std::vector<Typedef> TypedefsSeq;
 
@@ -361,6 +364,7 @@
         io.mapOptional("SwiftPrivate",          c.SwiftPrivate);
         io.mapOptional("SwiftName",             c.SwiftName);
         io.mapOptional("SwiftBridge",           c.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         c.NSErrorDomain);
         io.mapOptional("Methods",               c.Methods);
         io.mapOptional("Properties",            c.Properties);
       }
@@ -413,6 +417,7 @@
         io.mapOptional("SwiftPrivate",          t.SwiftPrivate);
         io.mapOptional("SwiftName",             t.SwiftName);
         io.mapOptional("SwiftBridge",           t.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         t.NSErrorDomain);
       }
     };
 
@@ -425,6 +430,7 @@
         io.mapOptional("SwiftPrivate",          t.SwiftPrivate);
         io.mapOptional("SwiftName",             t.SwiftName);
         io.mapOptional("SwiftBridge",           t.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         t.NSErrorDomain);
       }
     };
 
@@ -570,6 +576,7 @@
         return true;
 
       info.setSwiftBridge(common.SwiftBridge);
+      info.setNSErrorDomain(common.NSErrorDomain);
       return false;
     }
 
@@ -888,6 +895,7 @@
     void handleCommonType(T &record, const CommonTypeInfo &info) {
       handleCommon(record, info);
       record.SwiftBridge = copyString(info.getSwiftBridge());      
+      record.NSErrorDomain = copyString(info.getNSErrorDomain());
     }
 
     /// Map Objective-C context info.
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
index 4468d22..0515be2 100644
--- a/lib/Sema/SemaAPINotes.cpp
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -151,6 +151,15 @@
                                                  Info.getSwiftBridge())));
   }
 
+  // ns_error_domain
+  if (!Info.getNSErrorDomain().empty() &&
+      !D->getAttr<NSErrorDomainAttr>()) {
+    D->addAttr(
+      NSErrorDomainAttr::CreateImplicit(
+        S.Context,
+        &S.Context.Idents.get(Info.getNSErrorDomain())));
+  }
+
   ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info));
 }
 
diff --git a/test/APINotes/Inputs/roundtrip.apinotes b/test/APINotes/Inputs/roundtrip.apinotes
index f02aa00..66f5ea7 100644
--- a/test/APINotes/Inputs/roundtrip.apinotes
+++ b/test/APINotes/Inputs/roundtrip.apinotes
@@ -10,6 +10,7 @@
     SwiftPrivate:    false
     SwiftName:       ''
     SwiftBridge:     ''
+    NSErrorDomain:   ''
     Methods:         
       - Selector:        init
         MethodKind:      Instance
@@ -54,6 +55,7 @@
     SwiftPrivate:    false
     SwiftName:       ''
     SwiftBridge:     View
+    NSErrorDomain:   ''
     Methods:         
       - Selector:        'addSubview:'
         MethodKind:      Instance
@@ -113,12 +115,20 @@
     SwiftPrivate:    false
     SwiftName:       Red
 Tags:            
+  - Name:            NSSomeEnum
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       SomeEnum
+    SwiftBridge:     ''
+    NSErrorDomain:   some_error_domain
   - Name:            NSSomeStruct
     Availability:    available
     AvailabilityMsg: ''
     SwiftPrivate:    false
     SwiftName:       SomeStruct
     SwiftBridge:     ''
+    NSErrorDomain:   ''
 Typedefs:        
   - Name:            NSTypedef
     Availability:    available
@@ -126,3 +136,4 @@
     SwiftPrivate:    false
     SwiftName:       Typedef
     SwiftBridge:     ''
+    NSErrorDomain:   ''