diff options
| -rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 5 | ||||
| -rw-r--r-- | clang/include/clang/Basic/Attr.td | 8 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
| -rw-r--r-- | clang/include/clang/Sema/AttributeList.h | 3 | ||||
| -rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 23 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 256 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/exceptions-asm-attribute.m | 86 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/objc-asm-attribute-neg-test.m | 34 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/objc-asm-attribute-test.m | 54 | 
10 files changed, 372 insertions, 114 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 520f523a6da..de5252601aa 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -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; } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f34034e3255..964e502716b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -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]>; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6388ffe5eb4..4e77ec7dd20 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2165,7 +2165,8 @@ def warn_attribute_wrong_decl_type : Warning<    "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< diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h index 24e4cd41f99..c21c19fd55c 100644 --- a/clang/include/clang/Sema/AttributeList.h +++ b/clang/include/clang/Sema/AttributeList.h @@ -841,7 +841,8 @@ enum AttributeDeclKind {    ExpectedFunctionVariableOrClass,    ExpectedObjectiveCProtocol,    ExpectedFunctionGlobalVarMethodOrProperty, -  ExpectedStructOrTypedef +  ExpectedStructOrTypedef, +  ExpectedObjectiveCInterfaceOrProtocol  };  }  // end namespace clang diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 186a7417b65..f01383a083e 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -1199,6 +1199,22 @@ bool ObjCInterfaceDecl::hasDesignatedInitializers() const {    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::collectInheritedProtocolProperties(    }  } +StringRef +ObjCProtocolDecl::getObjCRuntimeNameAsString() const { +    if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>()) +        return ObjCRTName->getMetadataName(); +    return getName(); +} +  //===----------------------------------------------------------------------===//  // ObjCCategoryDecl  //===----------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index de760c8eca0..6f0979d06c5 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -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::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {    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 ObjCCategoryImplDecl *OCD) {      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 ObjCImplementationDecl *ID) {      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(const ObjCImplementationDecl *ID,    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::EmitClassRefFromId(CodeGenFunction &CGF,    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(CodeGenFunction &CGF, Selector Sel,    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 * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    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 * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    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 * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    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 * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    } 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 * CGObjCNonFragileABIMac::BuildClassRoTInitializer(  /// }  ///  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::GetClassSizeInfo(const ObjCImplementationDecl *OID,  }  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::GenerateClass(const ObjCImplementationDecl *ID) {      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::GenerateClass(const ObjCImplementationDecl *ID) {    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::GenerateClass(const ObjCImplementationDecl *ID) {      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::GenerateClass(const ObjCImplementationDecl *ID) {                                           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::GenerateProtocolRef(CodeGenFunction &CGF,                                     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::GenerateProtocolRef(CodeGenFunction &CGF,  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::GenerateCategory(const ObjCCategoryImplDecl *OCD) {                                 false,                                 llvm::GlobalValue::PrivateLinkage,                                 Init, -                               ExtCatName); +                               ExtCatName.str());    assertPrivateName(GCATV);    GCATV->setAlignment(      CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy)); @@ -6089,15 +6111,18 @@ CGObjCNonFragileABIMac::EmitMethodList(Twine Name,  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::EmitIvarList(      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::GetOrEmitProtocolRef(          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::GetOrEmitProtocol(    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::GetOrEmitProtocol(      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::GetOrEmitProtocol(    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(const std::string &Name, bool Weak) {  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::EmitClassRefFromId(CodeGenFunction &CGF,  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::EmitSuperClassRef(CodeGenFunction &CGF,    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::EmitMetaClassRef(CodeGenFunction &CGF,                                                        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::EmitMetaClassRef(CodeGenFunction &CGF,  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::GetInterfaceEHType(const ObjCInterfaceDecl *ID,      // 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::GetInterfaceEHType(const ObjCInterfaceDecl *ID,    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::GetInterfaceEHType(const ObjCInterfaceDecl *ID,    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); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c87942d0331..29be7033202 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3597,6 +3597,16 @@ static void handleObjCDesignatedInitializer(Sema &S, Decl *D,                                           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, Scope *scope, Decl *D,      handleObjCDesignatedInitializer(S, D, Attr);      break; +  case AttributeList::AT_ObjCRuntimeName: +    handleObjCRuntimeName(S, D, Attr); +    break; +              case AttributeList::AT_CFAuditedTransfer:      handleCFAuditedTransferAttr(S, D, Attr);      break; diff --git a/clang/test/CodeGenObjC/exceptions-asm-attribute.m b/clang/test/CodeGenObjC/exceptions-asm-attribute.m new file mode 100644 index 00000000000..eb369902a3c --- /dev/null +++ b/clang/test/CodeGenObjC/exceptions-asm-attribute.m @@ -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"))) +@interface A +@end + +@implementation A +-(void) im0 { +} +@end + +@implementation A (Cat) +-(void) im1 { +} +@end + +__attribute__((objc_runtime_name("MySecretNamespace.EH1"))) +@interface EH1 +@end + +__attribute__((objc_runtime_name("MySecretNamespace.EH2"))) +__attribute__((__objc_exception__)) +@interface EH2 +@end + +__attribute__((objc_runtime_name("MySecretNamespace.EH3"))) +__attribute__((__objc_exception__)) +@interface EH3 +@end + +void f1(); + +void f0(id x) { +  @try { +    f1(); +  } @catch (EH1 *x) { +  } @catch (EH2 *x) { +  } @catch (EH3 *x) { +  } +} + +@implementation EH3 +@end diff --git a/clang/test/CodeGenObjC/objc-asm-attribute-neg-test.m b/clang/test/CodeGenObjC/objc-asm-attribute-neg-test.m new file mode 100644 index 00000000000..e9bef4cdb76 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-asm-attribute-neg-test.m @@ -0,0 +1,34 @@ +// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://16462586 + +__attribute__((objc_runtime_name("MySecretNamespace.Protocol"))) +@protocol Protocol +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@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"))) +@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}} + +@end + +__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass"))) +@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}} + +__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol"))) +@protocol ForwardProtocol; + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}} +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +- (id) MyMethod { +  return MyIVAR; +} +@end diff --git a/clang/test/CodeGenObjC/objc-asm-attribute-test.m b/clang/test/CodeGenObjC/objc-asm-attribute-test.m new file mode 100644 index 00000000000..12903b522e5 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-asm-attribute-test.m @@ -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"))) +@protocol Protocol +- (void) MethodP; ++ (void) ClsMethodP; +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Protocol2"))) +@protocol Protocol2 +- (void) MethodP2; ++ (void) ClsMethodP2; +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@interface Message <Protocol, Protocol2> { +  id MyIVAR; +} +@end + +@implementation Message +- (id) MyMethod { +  return MyIVAR; +} + ++ (id) MyClsMethod { +  return 0; +} + +- (void) MethodP{} +- (void) MethodP2{} + ++ (void) ClsMethodP {} ++ (void) ClsMethodP2 {} +@end + +// rdar://16877359 +__attribute__((objc_runtime_name("foo"))) +@interface SLREarth +- (instancetype)init; ++ (instancetype)alloc; +@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"  | 

