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