r213167 - Objective-C. Introducing __attribute__((objc_runtime_name("runtimename"))
Fariborz Jahanian
fjahanian at apple.com
Wed Jul 16 09:16:08 PDT 2014
Author: fjahanian
Date: Wed Jul 16 11:16:04 2014
New Revision: 213167
URL: http://llvm.org/viewvc/llvm-project?rev=213167&view=rev
Log:
Objective-C. Introducing __attribute__((objc_runtime_name("runtimename"))
to be applied to class or protocols. This will direct IRGen
for Objective-C metadata to use the new name in various places
where class and protocol names are needed.
rdar:// 17631257
Added:
cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m
cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m
cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/AttributeList.h
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Jul 16 11:16:04 2014
@@ -955,6 +955,7 @@ public:
void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
unsigned Num,
ASTContext &C);
+ StringRef getObjCRuntimeNameAsString() const;
/// Returns the designated initializers for the interface.
///
@@ -1653,6 +1654,8 @@ public:
/// \brief Starts the definition of this Objective-C protocol.
void startDefinition();
+ StringRef getObjCRuntimeNameAsString() const;
+
SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -2100,6 +2103,8 @@ public:
std::string getNameAsString() const {
return getName();
}
+
+ StringRef getObjCRuntimeNameAsString() const;
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Jul 16 11:16:04 2014
@@ -989,6 +989,14 @@ def ObjCDesignatedInitializer : Attr {
let Documentation = [Undocumented];
}
+def ObjCRuntimeName : Attr {
+ let Spellings = [GNU<"objc_runtime_name">];
+ let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag,
+ "ExpectedObjectiveCInterfaceOrProtocol">;
+ let Args = [StringArgument<"MetadataName", 1>];
+ let Documentation = [Undocumented];
+}
+
def OptimizeNone : InheritableAttr {
let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 16 11:16:04 2014
@@ -2165,7 +2165,8 @@ def warn_attribute_wrong_decl_type : War
"struct or union|struct, union or class|types|"
"Objective-C instance methods|init methods of interface or class extension declarations|"
"variables, functions and classes|Objective-C protocols|"
- "functions and global variables|structs or typedefs}1">,
+ "functions and global variables|structs or typedefs|"
+ "interface or protocol declarations}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Wed Jul 16 11:16:04 2014
@@ -841,7 +841,8 @@ enum AttributeDeclKind {
ExpectedFunctionVariableOrClass,
ExpectedObjectiveCProtocol,
ExpectedFunctionGlobalVarMethodOrProperty,
- ExpectedStructOrTypedef
+ ExpectedStructOrTypedef,
+ ExpectedObjectiveCInterfaceOrProtocol
};
} // end namespace clang
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Jul 16 11:16:04 2014
@@ -1199,6 +1199,22 @@ bool ObjCInterfaceDecl::hasDesignatedIni
return data().HasDesignatedInitializers;
}
+StringRef
+ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
+ if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+ return ObjCRTName->getMetadataName();
+ return getName();
+}
+
+StringRef
+ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
+ if (ObjCInterfaceDecl *ID =
+ const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
+ return ID->getObjCRuntimeNameAsString();
+
+ return getName();
+}
+
ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
if (const ObjCInterfaceDecl *Def = getDefinition()) {
if (data().ExternallyCompleted)
@@ -1603,6 +1619,13 @@ void ObjCProtocolDecl::collectInheritedP
}
}
+StringRef
+ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
+ if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+ return ObjCRTName->getMetadataName();
+ return getName();
+}
+
//===----------------------------------------------------------------------===//
// ObjCCategoryDecl
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Jul 16 11:16:04 2014
@@ -855,7 +855,7 @@ protected:
llvm::SetVector<IdentifierInfo*> DefinedSymbols;
/// ClassNames - uniqued class names.
- llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
+ llvm::StringMap<llvm::GlobalVariable*> ClassNames;
/// MethodVarNames - uniqued method variable names.
llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
@@ -932,8 +932,9 @@ protected:
const Decl *Container);
/// GetClassName - Return a unique constant for the given selector's
- /// name. The return value has type char *.
- llvm::Constant *GetClassName(IdentifierInfo *Ident);
+ /// runtime name (which may change via use of objc_runtime_name attribute on
+ /// class or protocol definition. The return value has type char *.
+ llvm::Constant *GetClassName(StringRef RuntimeName);
llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
@@ -1312,7 +1313,7 @@ private:
unsigned InstanceStart,
unsigned InstanceSize,
const ObjCImplementationDecl *ID);
- llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
+ llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
llvm::Constant *IsAGV,
llvm::Constant *SuperClassGV,
llvm::Constant *ClassRoGV,
@@ -1377,7 +1378,8 @@ private:
const ObjCInterfaceDecl *ID);
llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
- IdentifierInfo *II, bool Weak);
+ IdentifierInfo *II, bool Weak,
+ const ObjCInterfaceDecl *ID);
llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
@@ -2624,7 +2626,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProt
llvm::Constant *Values[] = {
EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
MethodTypesExt),
- GetClassName(PD->getIdentifier()),
+ GetClassName(PD->getObjCRuntimeNameAsString()),
EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
PD->protocol_begin(),
PD->protocol_end()),
@@ -2936,8 +2938,8 @@ void CGObjCMac::GenerateCategory(const O
ClassMethods.push_back(GetMethodConstant(I));
llvm::Constant *Values[7];
- Values[0] = GetClassName(OCD->getIdentifier());
- Values[1] = GetClassName(Interface->getIdentifier());
+ Values[0] = GetClassName(OCD->getName());
+ Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
LazySymbols.insert(Interface->getIdentifier());
Values[2] =
EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
@@ -3080,12 +3082,12 @@ void CGObjCMac::GenerateClass(const ObjC
LazySymbols.insert(Super->getIdentifier());
Values[ 1] =
- llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+ llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
ObjCTypes.ClassPtrTy);
} else {
Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
}
- Values[ 2] = GetClassName(ID->getIdentifier());
+ Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
// Version is always 0.
Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
@@ -3138,19 +3140,19 @@ llvm::Constant *CGObjCMac::EmitMetaClass
while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
Root = Super;
Values[ 0] =
- llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
+ llvm::ConstantExpr::getBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
ObjCTypes.ClassPtrTy);
// The super class for the metaclass is emitted as the name of the
// super class. The runtime fixes this up to point to the
// *metaclass* for the super class.
if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
Values[ 1] =
- llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+ llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
ObjCTypes.ClassPtrTy);
} else {
Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
}
- Values[ 2] = GetClassName(ID->getIdentifier());
+ Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
// Version is always 0.
Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
@@ -4342,7 +4344,7 @@ void CGObjCMac::EmitModuleInfo() {
llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
// This used to be the filename, now it is unused. <rdr://4327263>
- GetClassName(&CGM.getContext().Idents.get("")),
+ GetClassName(StringRef("")),
EmitModuleSymbols()
};
CreateMetadataVar("\01L_OBJC_MODULES",
@@ -4406,7 +4408,7 @@ llvm::Value *CGObjCMac::EmitClassRefFrom
if (!Entry) {
llvm::Constant *Casted =
- llvm::ConstantExpr::getBitCast(GetClassName(II),
+ llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
ObjCTypes.ClassPtrTy);
Entry =
CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
@@ -4447,18 +4449,17 @@ llvm::Value *CGObjCMac::EmitSelector(Cod
return CGF.Builder.CreateLoad(Entry);
}
-llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
- llvm::GlobalVariable *&Entry = ClassNames[Ident];
-
- if (!Entry)
- Entry = CreateMetadataVar(
- "\01L_OBJC_CLASS_NAME_",
- llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
- ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
- : "__TEXT,__cstring,cstring_literals"),
- 1, true);
-
- return getConstantGEP(VMContext, Entry, 0, 0);
+llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
+ llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
+ if (!Entry)
+ Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
+ llvm::ConstantDataArray::getString(VMContext,
+ RuntimeName),
+ ((ObjCABI == 2) ?
+ "__TEXT,__objc_classname,cstring_literals" :
+ "__TEXT,__cstring,cstring_literals"),
+ 1, true);
+ return getConstantGEP(VMContext, Entry, 0, 0);
}
llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
@@ -4962,7 +4963,7 @@ void CGObjCMac::FinishModule() {
llvm::Constant *Values[5];
Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
- Values[1] = GetClassName(I->first);
+ Values[1] = GetClassName(I->first->getName());
Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
Values[3] = Values[4] =
llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
@@ -5628,7 +5629,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
unsigned InstanceStart,
unsigned InstanceSize,
const ObjCImplementationDecl *ID) {
- std::string ClassName = ID->getNameAsString();
+ std::string ClassName = ID->getObjCRuntimeNameAsString();
llvm::Constant *Values[10]; // 11 for 64bit targets!
if (CGM.getLangOpts().ObjCAutoRefCount)
@@ -5641,17 +5642,19 @@ llvm::GlobalVariable * CGObjCNonFragileA
Values[ 3] = (flags & NonFragileABI_Class_Meta)
? GetIvarLayoutName(nullptr, ObjCTypes)
: BuildIvarLayout(ID, true);
- Values[ 4] = GetClassName(ID->getIdentifier());
+ Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
// const struct _method_list_t * const baseMethods;
std::vector<llvm::Constant*> Methods;
std::string MethodListName("\01l_OBJC_$_");
if (flags & NonFragileABI_Class_Meta) {
- MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
+ MethodListName += "CLASS_METHODS_";
+ MethodListName += ID->getObjCRuntimeNameAsString();
for (const auto *I : ID->class_methods())
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(I));
} else {
- MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
+ MethodListName += "INSTANCE_METHODS_";
+ MethodListName += ID->getObjCRuntimeNameAsString();
for (const auto *I : ID->instance_methods())
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(I));
@@ -5675,7 +5678,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
const ObjCInterfaceDecl *OID = ID->getClassInterface();
assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
- + OID->getName(),
+ + OID->getObjCRuntimeNameAsString(),
OID->all_referenced_protocol_begin(),
OID->all_referenced_protocol_end());
@@ -5686,7 +5689,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
} else {
Values[ 7] = EmitIvarList(ID);
Values[ 8] = BuildIvarLayout(ID, false);
- Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
+ Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
ID, ID->getClassInterface(), ObjCTypes);
}
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
@@ -5717,7 +5720,7 @@ llvm::GlobalVariable * CGObjCNonFragileA
/// }
///
llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
- std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
+ const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
llvm::Constant *Values[] = {
IsAGV,
@@ -5765,7 +5768,7 @@ void CGObjCNonFragileABIMac::GetClassSiz
}
void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
- std::string ClassName = ID->getNameAsString();
+ std::string ClassName = ID->getObjCRuntimeNameAsString();
if (!ObjCEmptyCacheVar) {
ObjCEmptyCacheVar = new llvm::GlobalVariable(
CGM.getModule(),
@@ -5797,8 +5800,9 @@ void CGObjCNonFragileABIMac::GenerateCla
CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
uint32_t InstanceSize = InstanceStart;
uint32_t flags = NonFragileABI_Class_Meta;
- std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
- std::string ObjCClassName(getClassSymbolPrefix());
+ llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix());
+ llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix());
+ llvm::SmallString<64> TClassName;
llvm::GlobalVariable *SuperClassGV, *IsAGV;
@@ -5819,31 +5823,38 @@ void CGObjCNonFragileABIMac::GenerateCla
if (!ID->getClassInterface()->getSuperClass()) {
// class is root
flags |= NonFragileABI_Class_Root;
- SuperClassGV = GetClassGlobal(ObjCClassName + ClassName,
+ TClassName = ObjCClassName;
+ TClassName += ClassName;
+ SuperClassGV = GetClassGlobal(TClassName.str(),
ID->getClassInterface()->isWeakImported());
- IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName,
+ TClassName = ObjCMetaClassName;
+ TClassName += ClassName;
+ IsAGV = GetClassGlobal(TClassName.str(),
ID->getClassInterface()->isWeakImported());
} else {
// Has a root. Current class is not a root.
const ObjCInterfaceDecl *Root = ID->getClassInterface();
while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
Root = Super;
- IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString(),
+ TClassName = ObjCMetaClassName ;
+ TClassName += Root->getObjCRuntimeNameAsString();
+ IsAGV = GetClassGlobal(TClassName.str(),
Root->isWeakImported());
+
// work on super class metadata symbol.
- std::string SuperClassName =
- ObjCMetaClassName +
- ID->getClassInterface()->getSuperClass()->getNameAsString();
+ TClassName = ObjCMetaClassName;
+ TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
SuperClassGV = GetClassGlobal(
- SuperClassName,
- ID->getClassInterface()->getSuperClass()->isWeakImported());
+ TClassName.str(),
+ ID->getClassInterface()->getSuperClass()->isWeakImported());
}
llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
InstanceStart,
InstanceSize,ID);
- std::string TClassName = ObjCMetaClassName + ClassName;
+ TClassName = ObjCMetaClassName;
+ TClassName += ClassName;
llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
- TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
+ TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
ID->getClassInterface()->isWeakImported());
DefinedMetaClasses.push_back(MetaTClass);
@@ -5873,11 +5884,11 @@ void CGObjCNonFragileABIMac::GenerateCla
SuperClassGV = nullptr;
} else {
// Has a root. Current class is not a root.
- std::string RootClassName =
- ID->getClassInterface()->getSuperClass()->getNameAsString();
+ TClassName = ObjCClassName;
+ TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
SuperClassGV = GetClassGlobal(
- ObjCClassName + RootClassName,
- ID->getClassInterface()->getSuperClass()->isWeakImported());
+ TClassName.str(),
+ ID->getClassInterface()->getSuperClass()->isWeakImported());
}
GetClassSizeInfo(ID, InstanceStart, InstanceSize);
CLASS_RO_GV = BuildClassRoTInitializer(flags,
@@ -5885,9 +5896,10 @@ void CGObjCNonFragileABIMac::GenerateCla
InstanceSize,
ID);
- TClassName = ObjCClassName + ClassName;
+ TClassName = ObjCClassName;
+ TClassName += ClassName;
llvm::GlobalVariable *ClassMD =
- BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
+ BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
classIsHidden,
ID->getClassInterface()->isWeakImported());
DefinedClasses.push_back(ClassMD);
@@ -5923,7 +5935,7 @@ llvm::Value *CGObjCNonFragileABIMac::Gen
ObjCTypes.getExternalProtocolPtrTy());
std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
- ProtocolName += PD->getName();
+ ProtocolName += PD->getObjCRuntimeNameAsString();
llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
if (PTGV)
@@ -5953,53 +5965,63 @@ llvm::Value *CGObjCNonFragileABIMac::Gen
void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
const char *Prefix = "\01l_OBJC_$_CATEGORY_";
- std::string ExtCatName(Prefix + Interface->getNameAsString()+
- "_$_" + OCD->getNameAsString());
- std::string ExtClassName(getClassSymbolPrefix() +
- Interface->getNameAsString());
+
+ llvm::SmallString<64> ExtCatName(Prefix);
+ ExtCatName += Interface->getObjCRuntimeNameAsString();
+ ExtCatName += "_$_";
+ ExtCatName += OCD->getNameAsString();
+
+ llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
+ ExtClassName += Interface->getObjCRuntimeNameAsString();
llvm::Constant *Values[6];
- Values[0] = GetClassName(OCD->getIdentifier());
+ Values[0] = GetClassName(OCD->getIdentifier()->getName());
// meta-class entry symbol
llvm::GlobalVariable *ClassGV =
- GetClassGlobal(ExtClassName, Interface->isWeakImported());
+ GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
Values[1] = ClassGV;
std::vector<llvm::Constant*> Methods;
- std::string MethodListName(Prefix);
- MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
- "_$_" + OCD->getNameAsString();
+ llvm::SmallString<64> MethodListName(Prefix);
+
+ MethodListName += "INSTANCE_METHODS_";
+ MethodListName += Interface->getObjCRuntimeNameAsString();
+ MethodListName += "_$_";
+ MethodListName += OCD->getName();
for (const auto *I : OCD->instance_methods())
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(I));
- Values[2] = EmitMethodList(MethodListName,
+ Values[2] = EmitMethodList(MethodListName.str(),
"__DATA, __objc_const",
Methods);
MethodListName = Prefix;
- MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
- OCD->getNameAsString();
+ MethodListName += "CLASS_METHODS_";
+ MethodListName += Interface->getObjCRuntimeNameAsString();
+ MethodListName += "_$_";
+ MethodListName += OCD->getNameAsString();
+
Methods.clear();
for (const auto *I : OCD->class_methods())
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(I));
- Values[3] = EmitMethodList(MethodListName,
+ Values[3] = EmitMethodList(MethodListName.str(),
"__DATA, __objc_const",
Methods);
const ObjCCategoryDecl *Category =
Interface->FindCategoryDeclaration(OCD->getIdentifier());
if (Category) {
SmallString<256> ExtName;
- llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
+ llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
<< OCD->getName();
Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
- + Interface->getName() + "_$_"
- + Category->getName(),
- Category->protocol_begin(),
- Category->protocol_end());
+ + Interface->getObjCRuntimeNameAsString() + "_$_"
+ + Category->getName(),
+ Category->protocol_begin(),
+ Category->protocol_end());
Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
OCD, Category, ObjCTypes);
} else {
@@ -6015,7 +6037,7 @@ void CGObjCNonFragileABIMac::GenerateCat
false,
llvm::GlobalValue::PrivateLinkage,
Init,
- ExtCatName);
+ ExtCatName.str());
assertPrivateName(GCATV);
GCATV->setAlignment(
CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
@@ -6089,15 +6111,18 @@ CGObjCNonFragileABIMac::EmitMethodList(T
llvm::GlobalVariable *
CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar) {
+
const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
- std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
- '.' + Ivar->getNameAsString();
+ llvm::SmallString<64> Name("OBJC_IVAR_$_");
+ Name += Container->getObjCRuntimeNameAsString();
+ Name += ".";
+ Name += Ivar->getName();
llvm::GlobalVariable *IvarOffsetGV =
CGM.getModule().getGlobalVariable(Name);
if (!IvarOffsetGV)
IvarOffsetGV = new llvm::GlobalVariable(
- CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
- llvm::GlobalValue::ExternalLinkage, nullptr, Name);
+ CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
+ llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
return IvarOffsetGV;
}
@@ -6192,7 +6217,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
llvm::GlobalValue::PrivateLinkage,
Init,
- Prefix + OID->getName());
+ Prefix + OID->getObjCRuntimeNameAsString());
assertPrivateName(GV);
GV->setAlignment(
CGM.getDataLayout().getABITypeAlignment(Init->getType()));
@@ -6214,7 +6239,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
false, llvm::GlobalValue::WeakAnyLinkage,
nullptr,
- "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+ "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
Entry->setSection("__DATA,__datacoal_nt,coalesced");
}
@@ -6289,35 +6314,35 @@ llvm::Constant *CGObjCNonFragileABIMac::
llvm::Constant *Values[11];
// isa is NULL
Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
- Values[1] = GetClassName(PD->getIdentifier());
- Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
+ Values[1] = GetClassName(PD->getObjCRuntimeNameAsString());
+ Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
PD->protocol_begin(),
PD->protocol_end());
Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
- + PD->getName(),
+ + PD->getObjCRuntimeNameAsString(),
"__DATA, __objc_const",
InstanceMethods);
Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
- + PD->getName(),
+ + PD->getObjCRuntimeNameAsString(),
"__DATA, __objc_const",
ClassMethods);
Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
- + PD->getName(),
+ + PD->getObjCRuntimeNameAsString(),
"__DATA, __objc_const",
OptInstanceMethods);
Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
- + PD->getName(),
+ + PD->getObjCRuntimeNameAsString(),
"__DATA, __objc_const",
OptClassMethods);
- Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
+ Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
nullptr, PD, ObjCTypes);
uint32_t Size =
CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
- + PD->getName(),
+ + PD->getObjCRuntimeNameAsString(),
MethodTypesExt, ObjCTypes);
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
Values);
@@ -6330,7 +6355,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
Entry =
new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
false, llvm::GlobalValue::WeakAnyLinkage, Init,
- "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+ "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
Entry->setAlignment(
CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
Entry->setSection("__DATA,__datacoal_nt,coalesced");
@@ -6345,7 +6370,7 @@ llvm::Constant *CGObjCNonFragileABIMac::
llvm::GlobalVariable *PTGV =
new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
false, llvm::GlobalValue::WeakAnyLinkage, Entry,
- "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
+ "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
PTGV->setAlignment(
CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
@@ -6639,11 +6664,14 @@ CGObjCNonFragileABIMac::GetClassGlobal(c
llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
IdentifierInfo *II,
- bool Weak) {
+ bool Weak,
+ const ObjCInterfaceDecl *ID) {
llvm::GlobalVariable *&Entry = ClassReferences[II];
if (!Entry) {
- std::string ClassName(getClassSymbolPrefix() + II->getName().str());
+ std::string ClassName(
+ getClassSymbolPrefix() +
+ (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str());
llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
Entry =
new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
@@ -6662,13 +6690,13 @@ llvm::Value *CGObjCNonFragileABIMac::Emi
llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
- return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported());
+ return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
}
llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
- return EmitClassRefFromId(CGF, II, false);
+ return EmitClassRefFromId(CGF, II, false, 0);
}
llvm::Value *
@@ -6677,8 +6705,9 @@ CGObjCNonFragileABIMac::EmitSuperClassRe
llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
if (!Entry) {
- std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
- llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName,
+ llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+ ClassName += ID->getObjCRuntimeNameAsString();
+ llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
ID->isWeakImported());
Entry =
new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
@@ -6703,11 +6732,11 @@ llvm::Value *CGObjCNonFragileABIMac::Emi
bool Weak) {
llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
if (!Entry) {
-
- std::string MetaClassName(getMetaclassSymbolPrefix() +
- ID->getNameAsString());
+ llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
+ MetaClassName += ID->getObjCRuntimeNameAsString();
llvm::GlobalVariable *MetaClassGV =
- GetClassGlobal(MetaClassName, Weak);
+ GetClassGlobal(MetaClassName.str(), Weak);
+
Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
false, llvm::GlobalValue::PrivateLinkage,
MetaClassGV,
@@ -6728,8 +6757,9 @@ llvm::Value *CGObjCNonFragileABIMac::Emi
llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID) {
if (ID->isWeakImported()) {
- std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
- llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, true);
+ llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+ ClassName += ID->getObjCRuntimeNameAsString();
+ llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
(void)ClassGV;
assert(ClassGV->hasExternalWeakLinkage());
}
@@ -7004,17 +7034,18 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
// attribute, emit an external reference.
if (hasObjCExceptionAttribute(CGM.getContext(), ID))
return Entry =
- new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
- llvm::GlobalValue::ExternalLinkage,
- nullptr,
- ("OBJC_EHTYPE_$_" +
- ID->getIdentifier()->getName()));
+ new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
+ llvm::GlobalValue::ExternalLinkage,
+ nullptr,
+ ("OBJC_EHTYPE_$_" +
+ ID->getObjCRuntimeNameAsString()));
}
// Otherwise we need to either make a new entry or fill in the
// initializer.
assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
- std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+ llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+ ClassName += ID->getObjCRuntimeNameAsString();
std::string VTableName = "objc_ehtype_vtable";
llvm::GlobalVariable *VTableGV =
CGM.getModule().getGlobalVariable(VTableName);
@@ -7028,8 +7059,8 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
llvm::Constant *Values[] = {
llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
- GetClassName(ID->getIdentifier()),
- GetClassGlobal(ClassName)
+ GetClassName(ID->getObjCRuntimeNameAsString()),
+ GetClassGlobal(ClassName.str())
};
llvm::Constant *Init =
llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
@@ -7040,11 +7071,12 @@ CGObjCNonFragileABIMac::GetInterfaceEHTy
if (Entry) {
Entry->setInitializer(Init);
} else {
+ llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_");
+ EHTYPEName += ID->getObjCRuntimeNameAsString();
Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
L,
Init,
- ("OBJC_EHTYPE_$_" +
- ID->getIdentifier()->getName()));
+ EHTYPEName.str());
}
assert(Entry->getLinkage() == L);
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=213167&r1=213166&r2=213167&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jul 16 11:16:04 2014
@@ -3597,6 +3597,16 @@ static void handleObjCDesignatedInitiali
Attr.getAttributeSpellingListIndex()));
}
+static void handleObjCRuntimeName(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ StringRef MetaDataName;
+ if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName))
+ return;
+ D->addAttr(::new (S.Context)
+ ObjCRuntimeNameAttr(Attr.getRange(), S.Context,
+ MetaDataName, 0));
+}
+
static void handleObjCOwnershipAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
if (hasDeclarator(D)) return;
@@ -4246,6 +4256,10 @@ static void ProcessDeclAttribute(Sema &S
handleObjCDesignatedInitializer(S, D, Attr);
break;
+ case AttributeList::AT_ObjCRuntimeName:
+ handleObjCRuntimeName(S, D, Attr);
+ break;
+
case AttributeList::AT_CFAuditedTransfer:
handleCFAuditedTransferAttr(S, D, Attr);
break;
Added: cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m?rev=213167&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m (added)
+++ cfe/trunk/test/CodeGenObjC/exceptions-asm-attribute.m Wed Jul 16 11:16:04 2014
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s
+// RUN: FileCheck -check-prefix=CHECK-EHTYPE < %t %s
+// rdar://16462586
+
+// We need exactly 3 of these.
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE-NOT: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+
+// CHECK-X86_64: @"OBJC_CLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"OBJC_METACLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 8
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK-X86_64: define internal void @"\01-[A im0]"
+// CHECK-X86_64: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-exceptions -fvisibility hidden -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64-HIDDEN < %t %s
+
+// CHECK-X86_64-HIDDEN: @"OBJC_CLASS_$_MySecretNamespace.A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_METACLASS_$_MySecretNamespace.A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak hidden global {{.*}}, section "__DATA,__datacoal_nt,coalesced"
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = hidden global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A im0]"
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple armv6-apple-darwin10 -target-abi apcs-gnu -fobjc-exceptions -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-ARMV6 < %t %s
+
+// CHECK-ARMV6: @"OBJC_CLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"OBJC_METACLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 4
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = global {{.*}}, section "__DATA,__objc_const", align 4
+// CHECK-ARMV6: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 4
+// CHECK-ARMV6: define internal void @"\01-[A im0]"
+// CHECK-ARMV6: define internal void @"\01-[A(Cat) im1]"
+
+__attribute__((objc_runtime_name("MySecretNamespace.A")))
+ at interface A
+ at end
+
+ at implementation A
+-(void) im0 {
+}
+ at end
+
+ at implementation A (Cat)
+-(void) im1 {
+}
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH1")))
+ at interface EH1
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH2")))
+__attribute__((__objc_exception__))
+ at interface EH2
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH3")))
+__attribute__((__objc_exception__))
+ at interface EH3
+ at end
+
+void f1();
+
+void f0(id x) {
+ @try {
+ f1();
+ } @catch (EH1 *x) {
+ } @catch (EH2 *x) {
+ } @catch (EH3 *x) {
+ }
+}
+
+ at implementation EH3
+ at end
Added: cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m?rev=213167&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m (added)
+++ cfe/trunk/test/CodeGenObjC/objc-asm-attribute-neg-test.m Wed Jul 16 11:16:04 2014
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+ at protocol Protocol
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at interface Message <Protocol> {
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+ id MyIVAR;
+}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
+
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass")))
+ at class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol")))
+ at protocol ForwardProtocol;
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+- (id) MyMethod {
+ return MyIVAR;
+}
+ at end
Added: cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m?rev=213167&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m (added)
+++ cfe/trunk/test/CodeGenObjC/objc-asm-attribute-test.m Wed Jul 16 11:16:04 2014
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+ at protocol Protocol
+- (void) MethodP;
++ (void) ClsMethodP;
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol2")))
+ at protocol Protocol2
+- (void) MethodP2;
++ (void) ClsMethodP2;
+ at end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+ at interface Message <Protocol, Protocol2> {
+ id MyIVAR;
+}
+ at end
+
+ at implementation Message
+- (id) MyMethod {
+ return MyIVAR;
+}
+
++ (id) MyClsMethod {
+ return 0;
+}
+
+- (void) MethodP{}
+- (void) MethodP2{}
+
++ (void) ClsMethodP {}
++ (void) ClsMethodP2 {}
+ at end
+
+// rdar://16877359
+__attribute__((objc_runtime_name("foo")))
+ at interface SLREarth
+- (instancetype)init;
++ (instancetype)alloc;
+ at end
+
+id Test16877359() {
+ return [SLREarth alloc];
+}
+
+// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" = global i64
+// CHECK: @"OBJC_CLASS_$_MySecretNamespace.Message" = global %struct._class_t
+// CHECK: @"OBJC_METACLASS_$_MySecretNamespace.Message" = global %struct._class_t
+// CHECK: @"OBJC_CLASS_$_foo" = external global %struct._class_t
+// CHECK: define internal i8* @"\01-[Message MyMethod]"
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR"
More information about the cfe-commits
mailing list