r213167 - Objective-C. Introducing __attribute__((objc_runtime_name("runtimename"))

Fariborz Jahanian fjahanian at apple.com
Wed Jul 16 09:16:08 PDT 2014


Author: fjahanian
Date: Wed Jul 16 11:16:04 2014
New Revision: 213167

URL: http://llvm.org/viewvc/llvm-project?rev=213167&view=rev
Log:
Objective-C. Introducing __attribute__((objc_runtime_name("runtimename"))
to be applied to class or protocols. This will direct IRGen
for Objective-C metadata to use the new name in various places
where class and protocol names are needed.
rdar:// 17631257

Added:
    cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m
    cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m
    cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Jul 16 11:16:04 2014
@@ -955,6 +955,7 @@ public:
   void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
                                        unsigned Num,
                                        ASTContext &C);
+  StringRef getObjCRuntimeNameAsString() const;
 
   /// Returns the designated initializers for the interface.
   ///
@@ -1653,6 +1654,8 @@ public:
   /// \brief Starts the definition of this Objective-C protocol.
   void startDefinition();
 
+  StringRef getObjCRuntimeNameAsString() const;
+
   SourceRange getSourceRange() const override LLVM_READONLY {
     if (isThisDeclarationADefinition())
       return ObjCContainerDecl::getSourceRange();
@@ -2100,6 +2103,8 @@ public:
   std::string getNameAsString() const {
     return getName();
   }
+    
+  StringRef getObjCRuntimeNameAsString() const;
 
   const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
   ObjCInterfaceDecl *getSuperClass() { return SuperClass; }

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Jul 16 11:16:04 2014
@@ -989,6 +989,14 @@ def ObjCDesignatedInitializer : Attr {
   let Documentation = [Undocumented];
 }
 
+def ObjCRuntimeName : Attr {
+    let Spellings = [GNU<"objc_runtime_name">];
+    let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag,
+    "ExpectedObjectiveCInterfaceOrProtocol">;
+    let Args = [StringArgument<"MetadataName", 1>];
+    let Documentation = [Undocumented];
+}
+
 def OptimizeNone : InheritableAttr {
   let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 16 11:16:04 2014
@@ -2165,7 +2165,8 @@ def warn_attribute_wrong_decl_type : War
   "struct or union|struct, union or class|types|"
   "Objective-C instance methods|init methods of interface or class extension declarations|"
   "variables, functions and classes|Objective-C protocols|"
-  "functions and global variables|structs or typedefs}1">,
+  "functions and global variables|structs or typedefs|"
+  "interface or protocol declarations}1">,
   InGroup<IgnoredAttributes>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Wed Jul 16 11:16:04 2014
@@ -841,7 +841,8 @@ enum AttributeDeclKind {
   ExpectedFunctionVariableOrClass,
   ExpectedObjectiveCProtocol,
   ExpectedFunctionGlobalVarMethodOrProperty,
-  ExpectedStructOrTypedef
+  ExpectedStructOrTypedef,
+  ExpectedObjectiveCInterfaceOrProtocol
 };
 
 }  // end namespace clang

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Jul 16 11:16:04 2014
@@ -1199,6 +1199,22 @@ bool ObjCInterfaceDecl::hasDesignatedIni
   return data().HasDesignatedInitializers;
 }
 
+StringRef
+ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
+    if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+        return ObjCRTName->getMetadataName();
+    return getName();
+}
+
+StringRef
+ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
+    if (ObjCInterfaceDecl *ID =
+        const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
+        return ID->getObjCRuntimeNameAsString();
+    
+    return getName();
+}
+
 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
   if (const ObjCInterfaceDecl *Def = getDefinition()) {
     if (data().ExternallyCompleted)
@@ -1603,6 +1619,13 @@ void ObjCProtocolDecl::collectInheritedP
   }
 }
 
+StringRef
+ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
+    if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+        return ObjCRTName->getMetadataName();
+    return getName();
+}
+
 //===----------------------------------------------------------------------===//
 // ObjCCategoryDecl
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Jul 16 11:16:04 2014
@@ -855,7 +855,7 @@ protected:
   llvm::SetVector<IdentifierInfo*> DefinedSymbols;
 
   /// ClassNames - uniqued class names.
-  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
+  llvm::StringMap<llvm::GlobalVariable*> ClassNames;
 
   /// MethodVarNames - uniqued method variable names.
   llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
@@ -932,8 +932,9 @@ protected:
                                         const Decl *Container);
 
   /// GetClassName - Return a unique constant for the given selector's
-  /// name. The return value has type char *.
-  llvm::Constant *GetClassName(IdentifierInfo *Ident);
+  /// runtime name (which may change via use of objc_runtime_name attribute on
+  /// class or protocol definition. The return value has type char *.
+  llvm::Constant *GetClassName(StringRef RuntimeName);
 
   llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
 
@@ -1312,7 +1313,7 @@ private:
                                               unsigned InstanceStart,
                                               unsigned InstanceSize,
                                               const ObjCImplementationDecl *ID);
-  llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
+  llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
                                             llvm::Constant *IsAGV,
                                             llvm::Constant *SuperClassGV,
                                             llvm::Constant *ClassRoGV,
@@ -1377,7 +1378,8 @@ private:
                             const ObjCInterfaceDecl *ID);
   
   llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
-                                  IdentifierInfo *II, bool Weak);
+                                  IdentifierInfo *II, bool Weak,
+                                  const ObjCInterfaceDecl *ID);
 
   llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
 
@@ -2624,7 +2626,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProt
   llvm::Constant *Values[] = {
     EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods, 
                           MethodTypesExt),
-    GetClassName(PD->getIdentifier()),
+    GetClassName(PD->getObjCRuntimeNameAsString()),
     EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
                      PD->protocol_begin(),
                      PD->protocol_end()),
@@ -2936,8 +2938,8 @@ void CGObjCMac::GenerateCategory(const O
     ClassMethods.push_back(GetMethodConstant(I));
 
   llvm::Constant *Values[7];
-  Values[0] = GetClassName(OCD->getIdentifier());
-  Values[1] = GetClassName(Interface->getIdentifier());
+  Values[0] = GetClassName(OCD->getName());
+  Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
   LazySymbols.insert(Interface->getIdentifier());
   Values[2] =
     EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
@@ -3080,12 +3082,12 @@ void CGObjCMac::GenerateClass(const ObjC
     LazySymbols.insert(Super->getIdentifier());
 
     Values[ 1] =
-      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+      llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
                                      ObjCTypes.ClassPtrTy);
   } else {
     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
   }
-  Values[ 2] = GetClassName(ID->getIdentifier());
+  Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
   // Version is always 0.
   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
@@ -3138,19 +3140,19 @@ llvm::Constant *CGObjCMac::EmitMetaClass
   while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
     Root = Super;
   Values[ 0] =
-    llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
+    llvm::ConstantExpr::getBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
                                    ObjCTypes.ClassPtrTy);
   // The super class for the metaclass is emitted as the name of the
   // super class. The runtime fixes this up to point to the
   // *metaclass* for the super class.
   if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
     Values[ 1] =
-      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+      llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
                                      ObjCTypes.ClassPtrTy);
   } else {
     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
   }
-  Values[ 2] = GetClassName(ID->getIdentifier());
+  Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
   // Version is always 0.
   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
@@ -4342,7 +4344,7 @@ void CGObjCMac::EmitModuleInfo() {
     llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
     llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
     // This used to be the filename, now it is unused. <rdr://4327263>
-    GetClassName(&CGM.getContext().Idents.get("")),
+    GetClassName(StringRef("")),
     EmitModuleSymbols()
   };
   CreateMetadataVar("\01L_OBJC_MODULES",
@@ -4406,7 +4408,7 @@ llvm::Value *CGObjCMac::EmitClassRefFrom
   
   if (!Entry) {
     llvm::Constant *Casted =
-    llvm::ConstantExpr::getBitCast(GetClassName(II),
+    llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
                                    ObjCTypes.ClassPtrTy);
     Entry =
     CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
@@ -4447,18 +4449,17 @@ llvm::Value *CGObjCMac::EmitSelector(Cod
   return CGF.Builder.CreateLoad(Entry);
 }
 
-llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
-  llvm::GlobalVariable *&Entry = ClassNames[Ident];
-
-  if (!Entry)
-    Entry = CreateMetadataVar(
-        "\01L_OBJC_CLASS_NAME_",
-        llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
-        ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
-                        : "__TEXT,__cstring,cstring_literals"),
-        1, true);
-
-  return getConstantGEP(VMContext, Entry, 0, 0);
+llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
+    llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
+    if (!Entry)
+        Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
+                                  llvm::ConstantDataArray::getString(VMContext,
+                                                                     RuntimeName),
+                                  ((ObjCABI == 2) ?
+                                   "__TEXT,__objc_classname,cstring_literals" :
+                                   "__TEXT,__cstring,cstring_literals"),
+                                  1, true);
+    return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
@@ -4962,7 +4963,7 @@ void CGObjCMac::FinishModule() {
 
     llvm::Constant *Values[5];
     Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
-    Values[1] = GetClassName(I->first);
+    Values[1] = GetClassName(I->first->getName());
     Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
     Values[3] = Values[4] =
       llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
@@ -5628,7 +5629,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
   unsigned InstanceStart,
   unsigned InstanceSize,
   const ObjCImplementationDecl *ID) {
-  std::string ClassName = ID->getNameAsString();
+  std::string ClassName = ID->getObjCRuntimeNameAsString();
   llvm::Constant *Values[10]; // 11 for 64bit targets!
 
   if (CGM.getLangOpts().ObjCAutoRefCount)
@@ -5641,17 +5642,19 @@ llvm::GlobalVariable * CGObjCNonFragileA
   Values[ 3] = (flags & NonFragileABI_Class_Meta)
     ? GetIvarLayoutName(nullptr, ObjCTypes)
     : BuildIvarLayout(ID, true);
-  Values[ 4] = GetClassName(ID->getIdentifier());
+  Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
   // const struct _method_list_t * const baseMethods;
   std::vector<llvm::Constant*> Methods;
   std::string MethodListName("\01l_OBJC_$_");
   if (flags & NonFragileABI_Class_Meta) {
-    MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
+    MethodListName += "CLASS_METHODS_";
+    MethodListName += ID->getObjCRuntimeNameAsString();
     for (const auto *I : ID->class_methods())
       // Class methods should always be defined.
       Methods.push_back(GetMethodConstant(I));
   } else {
-    MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
+    MethodListName += "INSTANCE_METHODS_";
+    MethodListName += ID->getObjCRuntimeNameAsString();
     for (const auto *I : ID->instance_methods())
       // Instance methods should always be defined.
       Methods.push_back(GetMethodConstant(I));
@@ -5675,7 +5678,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
   const ObjCInterfaceDecl *OID = ID->getClassInterface();
   assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
   Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
-                                + OID->getName(),
+                                + OID->getObjCRuntimeNameAsString(),
                                 OID->all_referenced_protocol_begin(),
                                 OID->all_referenced_protocol_end());
 
@@ -5686,7 +5689,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
   } else {
     Values[ 7] = EmitIvarList(ID);
     Values[ 8] = BuildIvarLayout(ID, false);
-    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
+    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
                                   ID, ID->getClassInterface(), ObjCTypes);
   }
   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
@@ -5717,7 +5720,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
 /// }
 ///
 llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
-    std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
+    const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
     llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
   llvm::Constant *Values[] = {
     IsAGV,
@@ -5765,7 +5768,7 @@ void CGObjCNonFragileABIMac::GetClassSiz
 }
 
 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
-  std::string ClassName = ID->getNameAsString();
+  std::string ClassName = ID->getObjCRuntimeNameAsString();
   if (!ObjCEmptyCacheVar) {
     ObjCEmptyCacheVar = new llvm::GlobalVariable(
       CGM.getModule(),
@@ -5797,8 +5800,9 @@ void CGObjCNonFragileABIMac::GenerateCla
     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
   uint32_t InstanceSize = InstanceStart;
   uint32_t flags = NonFragileABI_Class_Meta;
-  std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
-  std::string ObjCClassName(getClassSymbolPrefix());
+  llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix());
+  llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix());
+  llvm::SmallString<64> TClassName;
 
   llvm::GlobalVariable *SuperClassGV, *IsAGV;
 
@@ -5819,31 +5823,38 @@ void CGObjCNonFragileABIMac::GenerateCla
   if (!ID->getClassInterface()->getSuperClass()) {
     // class is root
     flags |= NonFragileABI_Class_Root;
-    SuperClassGV = GetClassGlobal(ObjCClassName + ClassName,
+    TClassName = ObjCClassName;
+    TClassName += ClassName;
+    SuperClassGV = GetClassGlobal(TClassName.str(),
                                   ID->getClassInterface()->isWeakImported());
-    IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName,
+    TClassName = ObjCMetaClassName;
+    TClassName += ClassName;
+    IsAGV = GetClassGlobal(TClassName.str(),
                            ID->getClassInterface()->isWeakImported());
   } else {
     // Has a root. Current class is not a root.
     const ObjCInterfaceDecl *Root = ID->getClassInterface();
     while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
       Root = Super;
-    IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString(),
+    TClassName = ObjCMetaClassName ;
+    TClassName += Root->getObjCRuntimeNameAsString();
+    IsAGV = GetClassGlobal(TClassName.str(),
                            Root->isWeakImported());
+
     // work on super class metadata symbol.
-    std::string SuperClassName =
-      ObjCMetaClassName + 
-        ID->getClassInterface()->getSuperClass()->getNameAsString();
+    TClassName = ObjCMetaClassName;
+    TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
     SuperClassGV = GetClassGlobal(
-        SuperClassName,
-        ID->getClassInterface()->getSuperClass()->isWeakImported());
+                                  TClassName.str(),
+                                  ID->getClassInterface()->getSuperClass()->isWeakImported());
   }
   llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
                                                                InstanceStart,
                                                                InstanceSize,ID);
-  std::string TClassName = ObjCMetaClassName + ClassName;
+  TClassName = ObjCMetaClassName;
+  TClassName += ClassName;
   llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
-      TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
+      TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
       ID->getClassInterface()->isWeakImported());
   DefinedMetaClasses.push_back(MetaTClass);
 
@@ -5873,11 +5884,11 @@ void CGObjCNonFragileABIMac::GenerateCla
     SuperClassGV = nullptr;
   } else {
     // Has a root. Current class is not a root.
-    std::string RootClassName =
-      ID->getClassInterface()->getSuperClass()->getNameAsString();
+    TClassName = ObjCClassName;
+    TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
     SuperClassGV = GetClassGlobal(
-        ObjCClassName + RootClassName,
-        ID->getClassInterface()->getSuperClass()->isWeakImported());
+                                  TClassName.str(),
+                                  ID->getClassInterface()->getSuperClass()->isWeakImported());
   }
   GetClassSizeInfo(ID, InstanceStart, InstanceSize);
   CLASS_RO_GV = BuildClassRoTInitializer(flags,
@@ -5885,9 +5896,10 @@ void CGObjCNonFragileABIMac::GenerateCla
                                          InstanceSize,
                                          ID);
 
-  TClassName = ObjCClassName + ClassName;
+  TClassName = ObjCClassName;
+  TClassName += ClassName;
   llvm::GlobalVariable *ClassMD =
-    BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
+    BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
                        classIsHidden,
                        ID->getClassInterface()->isWeakImported());
   DefinedClasses.push_back(ClassMD);
@@ -5923,7 +5935,7 @@ llvm::Value *CGObjCNonFragileABIMac::Gen
                                    ObjCTypes.getExternalProtocolPtrTy());
 
   std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
-  ProtocolName += PD->getName();
+  ProtocolName += PD->getObjCRuntimeNameAsString();
 
   llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
   if (PTGV)
@@ -5953,53 +5965,63 @@ llvm::Value *CGObjCNonFragileABIMac::Gen
 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
   const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
   const char *Prefix = "\01l_OBJC_$_CATEGORY_";
-  std::string ExtCatName(Prefix + Interface->getNameAsString()+
-                         "_$_" + OCD->getNameAsString());
-  std::string ExtClassName(getClassSymbolPrefix() +
-                           Interface->getNameAsString());
+    
+  llvm::SmallString<64> ExtCatName(Prefix);
+  ExtCatName += Interface->getObjCRuntimeNameAsString();
+  ExtCatName += "_$_";
+  ExtCatName += OCD->getNameAsString();
+    
+  llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
+  ExtClassName += Interface->getObjCRuntimeNameAsString();
 
   llvm::Constant *Values[6];
-  Values[0] = GetClassName(OCD->getIdentifier());
+  Values[0] = GetClassName(OCD->getIdentifier()->getName());
   // meta-class entry symbol
   llvm::GlobalVariable *ClassGV =
-      GetClassGlobal(ExtClassName, Interface->isWeakImported());
+      GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
 
   Values[1] = ClassGV;
   std::vector<llvm::Constant*> Methods;
-  std::string MethodListName(Prefix);
-  MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
-    "_$_" + OCD->getNameAsString();
+  llvm::SmallString<64> MethodListName(Prefix);
+    
+  MethodListName += "INSTANCE_METHODS_";
+  MethodListName += Interface->getObjCRuntimeNameAsString();
+  MethodListName += "_$_";
+  MethodListName += OCD->getName();
 
   for (const auto *I : OCD->instance_methods())
     // Instance methods should always be defined.
     Methods.push_back(GetMethodConstant(I));
 
-  Values[2] = EmitMethodList(MethodListName,
+  Values[2] = EmitMethodList(MethodListName.str(),
                              "__DATA, __objc_const",
                              Methods);
 
   MethodListName = Prefix;
-  MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
-    OCD->getNameAsString();
+  MethodListName += "CLASS_METHODS_";
+  MethodListName += Interface->getObjCRuntimeNameAsString();
+  MethodListName += "_$_";
+  MethodListName += OCD->getNameAsString();
+    
   Methods.clear();
   for (const auto *I : OCD->class_methods())
     // Class methods should always be defined.
     Methods.push_back(GetMethodConstant(I));
 
-  Values[3] = EmitMethodList(MethodListName,
+  Values[3] = EmitMethodList(MethodListName.str(),
                              "__DATA, __objc_const",
                              Methods);
   const ObjCCategoryDecl *Category =
     Interface->FindCategoryDeclaration(OCD->getIdentifier());
   if (Category) {
     SmallString<256> ExtName;
-    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
+    llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
                                        << OCD->getName();
     Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
-                                 + Interface->getName() + "_$_"
-                                 + Category->getName(),
-                                 Category->protocol_begin(),
-                                 Category->protocol_end());
+                                   + Interface->getObjCRuntimeNameAsString() + "_$_"
+                                   + Category->getName(),
+                                   Category->protocol_begin(),
+                                   Category->protocol_end());
     Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
                                  OCD, Category, ObjCTypes);
   } else {
@@ -6015,7 +6037,7 @@ void CGObjCNonFragileABIMac::GenerateCat
                                false,
                                llvm::GlobalValue::PrivateLinkage,
                                Init,
-                               ExtCatName);
+                               ExtCatName.str());
   assertPrivateName(GCATV);
   GCATV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
@@ -6089,15 +6111,18 @@ CGObjCNonFragileABIMac::EmitMethodList(T
 llvm::GlobalVariable *
 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
                                                const ObjCIvarDecl *Ivar) {
+    
   const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
-  std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
-    '.' + Ivar->getNameAsString();
+  llvm::SmallString<64> Name("OBJC_IVAR_$_");
+  Name += Container->getObjCRuntimeNameAsString();
+  Name += ".";
+  Name += Ivar->getName();
   llvm::GlobalVariable *IvarOffsetGV =
     CGM.getModule().getGlobalVariable(Name);
   if (!IvarOffsetGV)
     IvarOffsetGV = new llvm::GlobalVariable(
-        CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
-        llvm::GlobalValue::ExternalLinkage, nullptr, Name);
+      CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
+      llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
   return IvarOffsetGV;
 }
 
@@ -6192,7 +6217,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
                              llvm::GlobalValue::PrivateLinkage,
                              Init,
-                             Prefix + OID->getName());
+                             Prefix + OID->getObjCRuntimeNameAsString());
   assertPrivateName(GV);
   GV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(Init->getType()));
@@ -6214,7 +6239,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
         new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
                                  false, llvm::GlobalValue::WeakAnyLinkage,
                                  nullptr,
-                                 "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+                                 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
     Entry->setSection("__DATA,__datacoal_nt,coalesced");
   }
 
@@ -6289,35 +6314,35 @@ llvm::Constant *CGObjCNonFragileABIMac::
   llvm::Constant *Values[11];
   // isa is NULL
   Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
-  Values[1] = GetClassName(PD->getIdentifier());
-  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
+  Values[1] = GetClassName(PD->getObjCRuntimeNameAsString());
+  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
                                PD->protocol_begin(),
                                PD->protocol_end());
 
   Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              InstanceMethods);
   Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              ClassMethods);
   Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              OptInstanceMethods);
   Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              OptClassMethods);
-  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
+  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
                                nullptr, PD, ObjCTypes);
   uint32_t Size =
     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
   Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
   Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
   Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
-                                       + PD->getName(),
+                                       + PD->getObjCRuntimeNameAsString(),
                                        MethodTypesExt, ObjCTypes);
   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
                                                    Values);
@@ -6330,7 +6355,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
                                false, llvm::GlobalValue::WeakAnyLinkage, Init,
-                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+                               "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
     Entry->setAlignment(
       CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
     Entry->setSection("__DATA,__datacoal_nt,coalesced");
@@ -6345,7 +6370,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
   llvm::GlobalVariable *PTGV =
     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
                              false, llvm::GlobalValue::WeakAnyLinkage, Entry,
-                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
+                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
   PTGV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
   PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
@@ -6639,11 +6664,14 @@ CGObjCNonFragileABIMac::GetClassGlobal(c
 
 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
                                                         IdentifierInfo *II,
-                                                        bool Weak) {
+                                                        bool Weak,
+                                                        const ObjCInterfaceDecl *ID) {
   llvm::GlobalVariable *&Entry = ClassReferences[II];
   
   if (!Entry) {
-    std::string ClassName(getClassSymbolPrefix() + II->getName().str());
+    std::string ClassName(
+      getClassSymbolPrefix() +
+      (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str());
     llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
     Entry =
     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
@@ -6662,13 +6690,13 @@ llvm::Value *CGObjCNonFragileABIMac::Emi
 
 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
                                                   const ObjCInterfaceDecl *ID) {
-  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported());
+  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
                                                     CodeGenFunction &CGF) {
   IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
-  return EmitClassRefFromId(CGF, II, false);
+  return EmitClassRefFromId(CGF, II, false, 0);
 }
 
 llvm::Value *
@@ -6677,8 +6705,9 @@ CGObjCNonFragileABIMac::EmitSuperClassRe
   llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
 
   if (!Entry) {
-    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName,
+    llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+    ClassName += ID->getObjCRuntimeNameAsString();
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
                                                    ID->isWeakImported());
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
@@ -6703,11 +6732,11 @@ llvm::Value *CGObjCNonFragileABIMac::Emi
                                                       bool Weak) {
   llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
   if (!Entry) {
-
-    std::string MetaClassName(getMetaclassSymbolPrefix() +
-                              ID->getNameAsString());
+    llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
+    MetaClassName += ID->getObjCRuntimeNameAsString();
     llvm::GlobalVariable *MetaClassGV =
-      GetClassGlobal(MetaClassName, Weak);
+      GetClassGlobal(MetaClassName.str(), Weak);
+      
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
                                      false, llvm::GlobalValue::PrivateLinkage,
                                      MetaClassGV,
@@ -6728,8 +6757,9 @@ llvm::Value *CGObjCNonFragileABIMac::Emi
 llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
                                               const ObjCInterfaceDecl *ID) {
   if (ID->isWeakImported()) {
-    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, true);
+    llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+    ClassName += ID->getObjCRuntimeNameAsString();
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
     (void)ClassGV;
     assert(ClassGV->hasExternalWeakLinkage());
   }
@@ -7004,17 +7034,18 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
     // attribute, emit an external reference.
     if (hasObjCExceptionAttribute(CGM.getContext(), ID))
       return Entry =
-        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
-                                 llvm::GlobalValue::ExternalLinkage,
-                                 nullptr,
-                                 ("OBJC_EHTYPE_$_" +
-                                  ID->getIdentifier()->getName()));
+          new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
+                                   llvm::GlobalValue::ExternalLinkage,
+                                   nullptr,
+                                   ("OBJC_EHTYPE_$_" +
+                                    ID->getObjCRuntimeNameAsString()));
   }
 
   // Otherwise we need to either make a new entry or fill in the
   // initializer.
   assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
-  std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+  llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+  ClassName += ID->getObjCRuntimeNameAsString();
   std::string VTableName = "objc_ehtype_vtable";
   llvm::GlobalVariable *VTableGV =
     CGM.getModule().getGlobalVariable(VTableName);
@@ -7028,8 +7059,8 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
 
   llvm::Constant *Values[] = {
     llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
-    GetClassName(ID->getIdentifier()),
-    GetClassGlobal(ClassName)
+    GetClassName(ID->getObjCRuntimeNameAsString()),
+    GetClassGlobal(ClassName.str())
   };
   llvm::Constant *Init =
     llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
@@ -7040,11 +7071,12 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
   if (Entry) {
     Entry->setInitializer(Init);
   } else {
+    llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_");
+    EHTYPEName += ID->getObjCRuntimeNameAsString();
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
                                      L,
                                      Init,
-                                     ("OBJC_EHTYPE_$_" +
-                                      ID->getIdentifier()->getName()));
+                                     EHTYPEName.str());
   }
   assert(Entry->getLinkage() == L);
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jul 16 11:16:04 2014
@@ -3597,6 +3597,16 @@ static void handleObjCDesignatedInitiali
                                          Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleObjCRuntimeName(Sema &S, Decl *D,
+                                  const AttributeList &Attr) {
+    StringRef MetaDataName;
+    if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName))
+        return;
+    D->addAttr(::new (S.Context)
+               ObjCRuntimeNameAttr(Attr.getRange(), S.Context,
+                                   MetaDataName, 0));
+}
+
 static void handleObjCOwnershipAttr(Sema &S, Decl *D,
                                     const AttributeList &Attr) {
   if (hasDeclarator(D)) return;
@@ -4246,6 +4256,10 @@ static void ProcessDeclAttribute(Sema &S
     handleObjCDesignatedInitializer(S, D, Attr);
     break;
 
+  case AttributeList::AT_ObjCRuntimeName:
+    handleObjCRuntimeName(S, D, Attr);
+    break;
+          
   case AttributeList::AT_CFAuditedTransfer:
     handleCFAuditedTransferAttr(S, D, Attr);
     break;

Added: cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m?rev=213167&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m (added)
+++ cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m Wed Jul 16 11:16:04 2014
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s
+// RUN: FileCheck -check-prefix=CHECK-EHTYPE < %t %s
+// rdar://16462586
+
+// We need exactly 3 of these.
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE-NOT: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+
+// CHECK-X86_64: @"OBJC_CLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"OBJC_METACLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 8
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK-X86_64: define internal void @"\01-[A im0]"
+// CHECK-X86_64: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-exceptions -fvisibility hidden -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64-HIDDEN < %t %s
+
+// CHECK-X86_64-HIDDEN: @"OBJC_CLASS_$_MySecretNamespace.A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_METACLASS_$_MySecretNamespace.A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak hidden global {{.*}}, section "__DATA,__datacoal_nt,coalesced"
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = hidden global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A im0]"
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple armv6-apple-darwin10 -target-abi apcs-gnu -fobjc-exceptions -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-ARMV6 < %t %s
+
+// CHECK-ARMV6: @"OBJC_CLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"OBJC_METACLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 4
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = global {{.*}}, section "__DATA,__objc_const", align 4
+// CHECK-ARMV6: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 4
+// CHECK-ARMV6: define internal void @"\01-[A im0]"
+// CHECK-ARMV6: define internal void @"\01-[A(Cat) im1]"
+
+__attribute__((objc_runtime_name("MySecretNamespace.A")))
+ at interface A
+ at end
+
+ at implementation A
+-(void) im0 {
+}
+ at end
+
+ at implementation A (Cat)
+-(void) im1 {
+}
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH1")))
+ at interface EH1
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH2")))
+__attribute__((__objc_exception__))
+ at interface EH2
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH3")))
+__attribute__((__objc_exception__))
+ at interface EH3
+ at end
+
+void f1();
+
+void f0(id x) {
+  @try {
+    f1();
+  } @catch (EH1 *x) {
+  } @catch (EH2 *x) {
+  } @catch (EH3 *x) {
+  }
+}
+
+ at implementation EH3
+ at end

Added: cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m?rev=213167&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m (added)
+++ cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m Wed Jul 16 11:16:04 2014
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+ at protocol Protocol
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at interface Message <Protocol> { 
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+  id MyIVAR;
+}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
+
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass")))
+ at class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol")))
+ at protocol ForwardProtocol;
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+- (id) MyMethod {
+  return MyIVAR;
+}
+ at end

Added: cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m?rev=213167&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m (added)
+++ cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m Wed Jul 16 11:16:04 2014
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+ at protocol Protocol
+- (void) MethodP;
++ (void) ClsMethodP;
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol2")))
+ at protocol Protocol2
+- (void) MethodP2;
++ (void) ClsMethodP2;
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at interface Message <Protocol, Protocol2> {
+  id MyIVAR;
+}
+ at end
+
+ at implementation Message
+- (id) MyMethod {
+  return MyIVAR;
+}
+
++ (id) MyClsMethod {
+  return 0;
+}
+
+- (void) MethodP{}
+- (void) MethodP2{}
+
++ (void) ClsMethodP {}
++ (void) ClsMethodP2 {}
+ at end
+
+// rdar://16877359
+__attribute__((objc_runtime_name("foo")))
+ at interface SLREarth
+- (instancetype)init;
++ (instancetype)alloc;
+ at end
+
+id Test16877359() {
+    return [SLREarth alloc];
+}
+
+// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" = global i64
+// CHECK: @"OBJC_CLASS_$_MySecretNamespace.Message" = global %struct._class_t
+// CHECK: @"OBJC_METACLASS_$_MySecretNamespace.Message" = global %struct._class_t
+// CHECK: @"OBJC_CLASS_$_foo" = external global %struct._class_t
+// CHECK: define internal i8* @"\01-[Message MyMethod]"
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR"





More information about the cfe-commits mailing list