---
include/clang/AST/ASTContext.h | 5 +
include/clang/AST/DeclObjC.h | 5 +-
lib/AST/ASTContext.cpp | 12 ++
lib/CodeGen/CGObjCGNU.cpp | 314 +++++++++++++++++++++++++++++------------
lib/Driver/Tools.cpp | 2 +-
lib/Lex/PPMacroExpansion.cpp | 1 +
6 files changed, 243 insertions(+), 96 deletions(-)
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 0e8f2b6..8f2772d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1295,6 +1295,11 @@ public:
void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
const Decl *Container,
std::string &S) const;
+
+ /// getObjCEncodingForPropertyTypeDecl - Return the encoded type for
+ /// this property declaration.
+ void getObjCEncodingForPropertyTypeDecl(const ObjCPropertyDecl *PD,
+ std::string &S) const;
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 5464957..fb9cb5a 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1924,13 +1924,14 @@ public:
OBJC_PR_atomic = 0x100,
OBJC_PR_weak = 0x200,
OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800
+ OBJC_PR_unsafe_unretained = 0x800,
+ OBJC_PR_dynamic = 0x1000
// Adding a property should change NumPropertyAttrsBits
};
enum {
/// \brief Number of bits fitting all the property attributes.
- NumPropertyAttrsBits = 12
+ NumPropertyAttrsBits = 13
};
enum SetterKind { Assign, Retain, Copy, Weak };
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index bdb464c..0758b3c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4855,6 +4855,18 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
// FIXME: OBJCGC: weak & strong
}
+/// getObjCEncodingForPropertyTypeDecl - Return the encoded type for
+/// this property declaration.
+void ASTContext::getObjCEncodingForPropertyTypeDecl(const ObjCPropertyDecl *PD,
+ std::string& S) const {
+ // Encode result type.
+ // GCC has some special rules regarding encoding of properties which
+ // closely resembles encoding of ivars.
+ getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0,
+ true /* outermost type */,
+ true /* encoding for property */);
+}
+
/// getLegacyIntegralTypeEncoding -
/// Another legacy compatibility encoding: 32-bit longs are encoded as
/// 'l' or 'L' , but not always. For typedefs, we need to use
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 5693451..d0c6aee 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -1781,61 +1781,125 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
GenerateProtocolMethodList(OptionalClassMethodNames,
OptionalClassMethodTypes);
- // Property metadata: name, attributes, isSynthesized, setter name, setter
- // types, getter name, getter types.
- // The isSynthesized value is always set to 0 in a protocol. It exists to
- // simplify the runtime library by allowing it to use the same data
- // structures for protocol metadata everywhere.
- llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
- PtrToInt8Ty, IntTy, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
- PtrToInt8Ty, NULL);
std::vector<llvm::Constant*> Properties;
std::vector<llvm::Constant*> OptionalProperties;
-
- // Add all of the property methods need adding to the method list and to the
- // property metadata list.
- for (ObjCContainerDecl::prop_iterator
+ llvm::Constant *PropertyArray = 0;
+ llvm::Constant *OptionalPropertyArray = 0;
+ ObjCRuntime R = CGM.getLangOpts().ObjCRuntime;
+ if ((R.getKind() == ObjCRuntime::GNUstep) &&
+ (R.getVersion() >= VersionTuple(1, 8))) {
+ // Property metadata: name, type encoding, getter name, setter name,
+ // ivar name, attributes as string, attributes.
+ llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
+ PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
+ IntTy, NULL);
+
+ // Add all of the property methods need adding to the method list and to the
+ // property metadata list.
+ for (ObjCContainerDecl::prop_iterator
iter = PD->prop_begin(), endIter = PD->prop_end();
- iter != endIter ; iter++) {
- std::vector<llvm::Constant*> Fields;
- ObjCPropertyDecl *property = *iter;
+ iter != endIter ; iter++) {
+ std::vector<llvm::Constant*> Fields;
+ ObjCPropertyDecl *property = *iter;
- Fields.push_back(MakePropertyEncodingString(property, PD));
-
- Fields.push_back(llvm::ConstantInt::get(IntTy,
- property->getPropertyAttributes()));
- Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
- if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
- std::string TypeStr;
- Context.getObjCEncodingForMethodDecl(getter,TypeStr);
- llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
- InstanceMethodTypes.push_back(TypeEncoding);
- Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
- Fields.push_back(TypeEncoding);
- } else {
- Fields.push_back(NULLPtr);
- Fields.push_back(NULLPtr);
- }
- if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+ Fields.push_back(MakeConstantString(property->getNameAsString()));
std::string TypeStr;
- Context.getObjCEncodingForMethodDecl(setter,TypeStr);
- llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
- InstanceMethodTypes.push_back(TypeEncoding);
- Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
- Fields.push_back(TypeEncoding);
- } else {
- Fields.push_back(NULLPtr);
+ Context.getObjCEncodingForPropertyTypeDecl(property, TypeStr);
+ Fields.push_back(MakeConstantString(TypeStr));
+ if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+ // FIXME: do we really need to update InstanceMethodTypes?
+ std::string GetterStr;
+ Context.getObjCEncodingForMethodDecl(getter,GetterStr);
+ InstanceMethodTypes.push_back(MakeConstantString(GetterStr));
+ Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
+ } else {
+ Fields.push_back(NULLPtr);
+ }
+ if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+ // FIXME: do we really need to update InstanceMethodTypes?
+ std::string SetterStr;
+ Context.getObjCEncodingForMethodDecl(setter,SetterStr);
+ InstanceMethodTypes.push_back(MakeConstantString(SetterStr));
+ Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
+ } else {
+ Fields.push_back(NULLPtr);
+ }
Fields.push_back(NULLPtr);
+ std::string AttrsStr;
+ Context.getObjCEncodingForPropertyDecl(property, NULL, AttrsStr);
+ Fields.push_back(MakeConstantString(AttrsStr));
+ Fields.push_back(llvm::ConstantInt::get(IntTy,
+ property->getPropertyAttributes()));
+ if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
+ OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+ } else {
+ Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+ }
}
- if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
- OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
- } else {
- Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+ PropertyArray = llvm::ConstantArray::get(
+ llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
+ OptionalPropertyArray =
+ llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
+ OptionalProperties.size()) , OptionalProperties);
+ } else {
+ // Property metadata: name, attributes, isSynthesized, setter name, setter
+ // types, getter name, getter types.
+ // The isSynthesized value is always set to 0 in a protocol. It exists to
+ // simplify the runtime library by allowing it to use the same data
+ // structures for protocol metadata everywhere.
+ llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
+ PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
+ PtrToInt8Ty, NULL);
+
+ // Add all of the property methods need adding to the method list and to the
+ // property metadata list.
+ for (ObjCContainerDecl::prop_iterator
+ iter = PD->prop_begin(), endIter = PD->prop_end();
+ iter != endIter ; iter++) {
+ std::vector<llvm::Constant*> Fields;
+ ObjCPropertyDecl *property = *iter;
+
+
+ Fields.push_back(MakePropertyEncodingString(property, PD));
+
+ Fields.push_back(llvm::ConstantInt::get(Int8Ty,
+ property->getPropertyAttributes()));
+ Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
+ if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+ std::string TypeStr;
+ Context.getObjCEncodingForMethodDecl(getter,TypeStr);
+ llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+ InstanceMethodTypes.push_back(TypeEncoding);
+ Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
+ Fields.push_back(TypeEncoding);
+ } else {
+ Fields.push_back(NULLPtr);
+ Fields.push_back(NULLPtr);
+ }
+ if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+ std::string TypeStr;
+ Context.getObjCEncodingForMethodDecl(setter,TypeStr);
+ llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+ InstanceMethodTypes.push_back(TypeEncoding);
+ Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
+ Fields.push_back(TypeEncoding);
+ } else {
+ Fields.push_back(NULLPtr);
+ Fields.push_back(NULLPtr);
+ }
+ if (property->getPropertyImplementation() == ObjCPropertyDecl::Optional) {
+ OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+ } else {
+ Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+ }
}
+ PropertyArray = llvm::ConstantArray::get(
+ llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
+ OptionalPropertyArray =
+ llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
+ OptionalProperties.size()) , OptionalProperties);
}
- llvm::Constant *PropertyArray = llvm::ConstantArray::get(
- llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
llvm::Constant* PropertyListInitFields[] =
{llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
@@ -1845,9 +1909,6 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
PropertyListInit->getType(), false, llvm::GlobalValue::InternalLinkage,
PropertyListInit, ".objc_property_list");
- llvm::Constant *OptionalPropertyArray =
- llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
- OptionalProperties.size()) , OptionalProperties);
llvm::Constant* OptionalPropertyListInitFields[] = {
llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
OptionalPropertyArray };
@@ -2035,62 +2096,129 @@ llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OI
SmallVectorImpl<Selector> &InstanceMethodSels,
SmallVectorImpl<llvm::Constant*> &InstanceMethodTypes) {
ASTContext &Context = CGM.getContext();
- //
- // Property metadata: name, attributes, isSynthesized, setter name, setter
- // types, getter name, getter types.
- llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
- PtrToInt8Ty, IntTy, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
- PtrToInt8Ty, NULL);
std::vector<llvm::Constant*> Properties;
-
+ llvm::ArrayType *PropertyArrayTy = 0;
// Add all of the property methods need adding to the method list and to the
// property metadata list.
- for (ObjCImplDecl::propimpl_iterator
+ ObjCRuntime R = CGM.getLangOpts().ObjCRuntime;
+ if ((R.getKind() == ObjCRuntime::GNUstep) &&
+ (R.getVersion() >= VersionTuple(1, 8))) {
+ // Property metadata: name, type encoding, getter name, setter name,
+ // ivar name, attributes as string, attributes.
+ llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
+ PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
+ IntTy, NULL);
+
+ // Add all of the property methods need adding to the method list and to the
+ // property metadata list.
+ for (ObjCImplDecl::propimpl_iterator
iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
- iter != endIter ; iter++) {
- std::vector<llvm::Constant*> Fields;
- ObjCPropertyDecl *property = iter->getPropertyDecl();
- ObjCPropertyImplDecl *propertyImpl = *iter;
- bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
- ObjCPropertyImplDecl::Synthesize);
-
- Fields.push_back(MakePropertyEncodingString(property, OID));
- Fields.push_back(llvm::ConstantInt::get(IntTy,
- property->getPropertyAttributes()));
- Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized));
- if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+ iter != endIter ; iter++) {
+ std::vector<llvm::Constant*> Fields;
+ ObjCPropertyDecl *property = iter->getPropertyDecl();
+ ObjCPropertyImplDecl *propertyImpl = *iter;
+ bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
+ ObjCPropertyImplDecl::Synthesize);
+
+ Fields.push_back(MakeConstantString(property->getNameAsString()));
std::string TypeStr;
- Context.getObjCEncodingForMethodDecl(getter,TypeStr);
- llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
- if (isSynthesized) {
- InstanceMethodTypes.push_back(TypeEncoding);
- InstanceMethodSels.push_back(getter->getSelector());
+ Context.getObjCEncodingForPropertyTypeDecl(property, TypeStr);
+ Fields.push_back(MakeConstantString(TypeStr));
+ if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+ if (isSynthesized) {
+ std::string GetterStr;
+ Context.getObjCEncodingForMethodDecl(getter,GetterStr);
+ InstanceMethodTypes.push_back(MakeConstantString(GetterStr));
+ InstanceMethodSels.push_back(getter->getSelector());
+ }
+ Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
+ } else {
+ Fields.push_back(NULLPtr);
}
- Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
- Fields.push_back(TypeEncoding);
- } else {
- Fields.push_back(NULLPtr);
- Fields.push_back(NULLPtr);
+ if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+ if (isSynthesized) {
+ std::string SetterStr;
+ Context.getObjCEncodingForMethodDecl(setter,SetterStr);
+ InstanceMethodTypes.push_back(MakeConstantString(SetterStr));
+ InstanceMethodSels.push_back(setter->getSelector());
+ }
+ Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
+ } else {
+ Fields.push_back(NULLPtr);
+ }
+ if (propertyImpl->getPropertyImplementation()!=ObjCPropertyImplDecl::Dynamic) {
+ const ObjCIvarDecl *IID = propertyImpl->getPropertyIvarDecl();
+ Fields.push_back(MakeConstantString(IID->getNameAsString()));
+ } else {
+ Fields.push_back(NULLPtr);
+ }
+ std::string AttrsStr;
+ Context.getObjCEncodingForPropertyDecl(property, OID, AttrsStr);
+ Fields.push_back(MakeConstantString(AttrsStr));
+ unsigned int Attrs = property->getPropertyAttributes();
+ if (propertyImpl->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+ Attrs |= ObjCPropertyDecl::OBJC_PR_dynamic;
+ }
+ Fields.push_back(llvm::ConstantInt::get(IntTy, Attrs));
+ Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
}
- if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
- std::string TypeStr;
- Context.getObjCEncodingForMethodDecl(setter,TypeStr);
- llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
- if (isSynthesized) {
- InstanceMethodTypes.push_back(TypeEncoding);
- InstanceMethodSels.push_back(setter->getSelector());
+ PropertyArrayTy =
+ llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
+ } else {
+ //
+ // Property metadata: name, attributes, isSynthesized, setter name, setter
+ // types, getter name, getter types.
+ llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
+ PtrToInt8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
+ PtrToInt8Ty, NULL);
+
+ for (ObjCImplDecl::propimpl_iterator
+ iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
+ iter != endIter ; iter++) {
+ std::vector<llvm::Constant*> Fields;
+ ObjCPropertyDecl *property = iter->getPropertyDecl();
+ ObjCPropertyImplDecl *propertyImpl = *iter;
+ bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
+ ObjCPropertyImplDecl::Synthesize);
+
+ Fields.push_back(MakePropertyEncodingString(property, OID));
+ Fields.push_back(llvm::ConstantInt::get(Int8Ty,
+ property->getPropertyAttributes()));
+ Fields.push_back(llvm::ConstantInt::get(Int8Ty, isSynthesized));
+ if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+ std::string TypeStr;
+ Context.getObjCEncodingForMethodDecl(getter,TypeStr);
+ llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+ if (isSynthesized) {
+ InstanceMethodTypes.push_back(TypeEncoding);
+ InstanceMethodSels.push_back(getter->getSelector());
+ }
+ Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
+ Fields.push_back(TypeEncoding);
+ } else {
+ Fields.push_back(NULLPtr);
+ Fields.push_back(NULLPtr);
}
- Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
- Fields.push_back(TypeEncoding);
- } else {
- Fields.push_back(NULLPtr);
- Fields.push_back(NULLPtr);
+ if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+ std::string TypeStr;
+ Context.getObjCEncodingForMethodDecl(setter,TypeStr);
+ llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
+ if (isSynthesized) {
+ InstanceMethodTypes.push_back(TypeEncoding);
+ InstanceMethodSels.push_back(setter->getSelector());
+ }
+ Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
+ Fields.push_back(TypeEncoding);
+ } else {
+ Fields.push_back(NULLPtr);
+ Fields.push_back(NULLPtr);
+ }
+ Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
}
- Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
+ PropertyArrayTy =
+ llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
}
- llvm::ArrayType *PropertyArrayTy =
- llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
Properties);
llvm::Constant* PropertyListInitFields[] =
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 77c7d22..b595d87 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -3344,7 +3344,7 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
// Legacy behaviour is to target the gnustep runtime if we are i
// non-fragile mode or the GCC runtime in fragile mode.
if (isNonFragile)
- runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6));
+ runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,8));
else
runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index bda31ed..26088a3 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -826,6 +826,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
.Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
.Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword?
+ .Case("objc_property_clean_abi", true) // Does clang support the new ABI for properties?
.Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
.Case("ownership_holds", true)
.Case("ownership_returns", true)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits