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

Aaron Ballman aaron at aaronballman.com
Wed Jul 16 10:22:23 PDT 2014


Some comments below.

On Wed, Jul 16, 2014 at 12:16 PM, Fariborz Jahanian <fjahanian at apple.com> wrote:
> 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;

Comments as to why these new methods are interesting might be useful.

>
>    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">;

Do you think there will be more attributes appertaining to interfaces
and protocols in the future, or is that a rare combination?

> +    let Args = [StringArgument<"MetadataName", 1>];

This does not appear to be optional according to what's happen in
SemaDeclAttr.cpp (and the tests). Is that a bug here, or elsewhere?

> +    let Documentation = [Undocumented];

New attributes must be documented, so please add documentation for
this attribute.

> +}
> +
>  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();
> +}

The formatting for these function definitions does not match our style
guidelines.

> +
>  //===----------------------------------------------------------------------===//
>  // 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));

You need to pass Attr.getAttributeSpellingListIndex() as the last parameter.

> +}
> +
>  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"

You have some sema tests living in CodeGen, and are missing tests for
things like the attribute parameter. Are there restrictions on what
you can put in the parameter?

~Aaron



More information about the cfe-commits mailing list