mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 01:46:05 +00:00
[NFC] Refactoring PropertyAttributeKind for ObjCPropertyDecl and ObjCDeclSpec.
This is a code clean up of the PropertyAttributeKind and ObjCPropertyAttributeKind enums in ObjCPropertyDecl and ObjCDeclSpec that are exactly identical. This non-functional change consolidates these enums into one. The changes are to many files across clang (and comments in LLVM) so that everything refers to the new consolidated enum in DeclObjCCommon.h. 2nd Landing Attempt... Differential Revision: https://reviews.llvm.org/D77233
This commit is contained in:
parent
b53fd70b9e
commit
9721fbf85b
@ -15,6 +15,7 @@
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclObjCCommon.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/Redeclarable.h"
|
||||
#include "clang/AST/SelectorLocationsKind.h"
|
||||
@ -742,34 +743,6 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
void anchor() override;
|
||||
|
||||
public:
|
||||
enum PropertyAttributeKind {
|
||||
OBJC_PR_noattr = 0x00,
|
||||
OBJC_PR_readonly = 0x01,
|
||||
OBJC_PR_getter = 0x02,
|
||||
OBJC_PR_assign = 0x04,
|
||||
OBJC_PR_readwrite = 0x08,
|
||||
OBJC_PR_retain = 0x10,
|
||||
OBJC_PR_copy = 0x20,
|
||||
OBJC_PR_nonatomic = 0x40,
|
||||
OBJC_PR_setter = 0x80,
|
||||
OBJC_PR_atomic = 0x100,
|
||||
OBJC_PR_weak = 0x200,
|
||||
OBJC_PR_strong = 0x400,
|
||||
OBJC_PR_unsafe_unretained = 0x800,
|
||||
/// Indicates that the nullability of the type was spelled with a
|
||||
/// property attribute rather than a type qualifier.
|
||||
OBJC_PR_nullability = 0x1000,
|
||||
OBJC_PR_null_resettable = 0x2000,
|
||||
OBJC_PR_class = 0x4000,
|
||||
OBJC_PR_direct = 0x8000
|
||||
// Adding a property should change NumPropertyAttrsBits
|
||||
};
|
||||
|
||||
enum {
|
||||
/// Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 16
|
||||
};
|
||||
|
||||
enum SetterKind { Assign, Retain, Copy, Weak };
|
||||
enum PropertyControl { None, Required, Optional };
|
||||
|
||||
@ -782,8 +755,8 @@ private:
|
||||
|
||||
QualType DeclType;
|
||||
TypeSourceInfo *DeclTypeSourceInfo;
|
||||
unsigned PropertyAttributes : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributes : NumObjCPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits;
|
||||
|
||||
// \@required/\@optional
|
||||
unsigned PropertyImplementation : 2;
|
||||
@ -811,12 +784,11 @@ private:
|
||||
|
||||
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
||||
SourceLocation AtLocation, SourceLocation LParenLocation,
|
||||
QualType T, TypeSourceInfo *TSI,
|
||||
PropertyControl propControl)
|
||||
QualType T, TypeSourceInfo *TSI, PropertyControl propControl)
|
||||
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
|
||||
LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
|
||||
PropertyAttributes(OBJC_PR_noattr),
|
||||
PropertyAttributesAsWritten(OBJC_PR_noattr),
|
||||
PropertyAttributes(ObjCPropertyAttribute::kind_noattr),
|
||||
PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr),
|
||||
PropertyImplementation(propControl), GetterName(Selector()),
|
||||
SetterName(Selector()) {}
|
||||
|
||||
@ -850,11 +822,11 @@ public:
|
||||
/// type.
|
||||
QualType getUsageType(QualType objectType) const;
|
||||
|
||||
PropertyAttributeKind getPropertyAttributes() const {
|
||||
return PropertyAttributeKind(PropertyAttributes);
|
||||
ObjCPropertyAttribute::Kind getPropertyAttributes() const {
|
||||
return ObjCPropertyAttribute::Kind(PropertyAttributes);
|
||||
}
|
||||
|
||||
void setPropertyAttributes(PropertyAttributeKind PRVal) {
|
||||
void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) {
|
||||
PropertyAttributes |= PRVal;
|
||||
}
|
||||
|
||||
@ -862,11 +834,11 @@ public:
|
||||
PropertyAttributes = PRVal;
|
||||
}
|
||||
|
||||
PropertyAttributeKind getPropertyAttributesAsWritten() const {
|
||||
return PropertyAttributeKind(PropertyAttributesAsWritten);
|
||||
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const {
|
||||
return ObjCPropertyAttribute::Kind(PropertyAttributesAsWritten);
|
||||
}
|
||||
|
||||
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
|
||||
void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal) {
|
||||
PropertyAttributesAsWritten = PRVal;
|
||||
}
|
||||
|
||||
@ -874,23 +846,28 @@ public:
|
||||
|
||||
/// isReadOnly - Return true iff the property has a setter.
|
||||
bool isReadOnly() const {
|
||||
return (PropertyAttributes & OBJC_PR_readonly);
|
||||
return (PropertyAttributes & ObjCPropertyAttribute::kind_readonly);
|
||||
}
|
||||
|
||||
/// isAtomic - Return true if the property is atomic.
|
||||
bool isAtomic() const {
|
||||
return (PropertyAttributes & OBJC_PR_atomic);
|
||||
return (PropertyAttributes & ObjCPropertyAttribute::kind_atomic);
|
||||
}
|
||||
|
||||
/// isRetaining - Return true if the property retains its value.
|
||||
bool isRetaining() const {
|
||||
return (PropertyAttributes &
|
||||
(OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
|
||||
return (PropertyAttributes & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong |
|
||||
ObjCPropertyAttribute::kind_copy));
|
||||
}
|
||||
|
||||
bool isInstanceProperty() const { return !isClassProperty(); }
|
||||
bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; }
|
||||
bool isDirectProperty() const { return PropertyAttributes & OBJC_PR_direct; }
|
||||
bool isClassProperty() const {
|
||||
return PropertyAttributes & ObjCPropertyAttribute::kind_class;
|
||||
}
|
||||
bool isDirectProperty() const {
|
||||
return PropertyAttributes & ObjCPropertyAttribute::kind_direct;
|
||||
}
|
||||
|
||||
ObjCPropertyQueryKind getQueryKind() const {
|
||||
return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class :
|
||||
@ -906,13 +883,13 @@ public:
|
||||
/// the property setter. This is only valid if the property has been
|
||||
/// defined to have a setter.
|
||||
SetterKind getSetterKind() const {
|
||||
if (PropertyAttributes & OBJC_PR_strong)
|
||||
if (PropertyAttributes & ObjCPropertyAttribute::kind_strong)
|
||||
return getType()->isBlockPointerType() ? Copy : Retain;
|
||||
if (PropertyAttributes & OBJC_PR_retain)
|
||||
if (PropertyAttributes & ObjCPropertyAttribute::kind_retain)
|
||||
return Retain;
|
||||
if (PropertyAttributes & OBJC_PR_copy)
|
||||
if (PropertyAttributes & ObjCPropertyAttribute::kind_copy)
|
||||
return Copy;
|
||||
if (PropertyAttributes & OBJC_PR_weak)
|
||||
if (PropertyAttributes & ObjCPropertyAttribute::kind_weak)
|
||||
return Weak;
|
||||
return Assign;
|
||||
}
|
||||
|
55
clang/include/clang/AST/DeclObjCCommon.h
Normal file
55
clang/include/clang/AST/DeclObjCCommon.h
Normal file
@ -0,0 +1,55 @@
|
||||
//===- DeclObjCCommon.h - Classes for representing declarations -*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains common ObjC enums and classes used in AST and
|
||||
// Sema.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H
|
||||
#define LLVM_CLANG_AST_DECLOBJC_COMMON_H
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// ObjCPropertyAttribute::Kind - list of property attributes.
|
||||
/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes.s
|
||||
namespace ObjCPropertyAttribute {
|
||||
enum Kind {
|
||||
kind_noattr = 0x00,
|
||||
kind_readonly = 0x01,
|
||||
kind_getter = 0x02,
|
||||
kind_assign = 0x04,
|
||||
kind_readwrite = 0x08,
|
||||
kind_retain = 0x10,
|
||||
kind_copy = 0x20,
|
||||
kind_nonatomic = 0x40,
|
||||
kind_setter = 0x80,
|
||||
kind_atomic = 0x100,
|
||||
kind_weak = 0x200,
|
||||
kind_strong = 0x400,
|
||||
kind_unsafe_unretained = 0x800,
|
||||
/// Indicates that the nullability of the type was spelled with a
|
||||
/// property attribute rather than a type qualifier.
|
||||
kind_nullability = 0x1000,
|
||||
kind_null_resettable = 0x2000,
|
||||
kind_class = 0x4000,
|
||||
kind_direct = 0x8000,
|
||||
// Adding a property should change NumObjCPropertyAttrsBits
|
||||
// Also, don't forget to update the Clang C API at CXObjCPropertyAttrKind and
|
||||
// clang_Cursor_getObjCPropertyAttributes.
|
||||
};
|
||||
} // namespace ObjCPropertyAttribute::Kind
|
||||
|
||||
enum {
|
||||
/// Number of bits fitting all the property attributes.
|
||||
NumObjCPropertyAttrsBits = 16
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H
|
@ -23,6 +23,7 @@
|
||||
#define LLVM_CLANG_SEMA_DECLSPEC_H
|
||||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjCCommon.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/Basic/ExceptionSpecificationType.h"
|
||||
#include "clang/Basic/Lambda.h"
|
||||
@ -841,31 +842,10 @@ public:
|
||||
DQ_CSNullability = 0x40
|
||||
};
|
||||
|
||||
/// PropertyAttributeKind - list of property attributes.
|
||||
/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes.
|
||||
enum ObjCPropertyAttributeKind {
|
||||
DQ_PR_noattr = 0x0,
|
||||
DQ_PR_readonly = 0x01,
|
||||
DQ_PR_getter = 0x02,
|
||||
DQ_PR_assign = 0x04,
|
||||
DQ_PR_readwrite = 0x08,
|
||||
DQ_PR_retain = 0x10,
|
||||
DQ_PR_copy = 0x20,
|
||||
DQ_PR_nonatomic = 0x40,
|
||||
DQ_PR_setter = 0x80,
|
||||
DQ_PR_atomic = 0x100,
|
||||
DQ_PR_weak = 0x200,
|
||||
DQ_PR_strong = 0x400,
|
||||
DQ_PR_unsafe_unretained = 0x800,
|
||||
DQ_PR_nullability = 0x1000,
|
||||
DQ_PR_null_resettable = 0x2000,
|
||||
DQ_PR_class = 0x4000,
|
||||
DQ_PR_direct = 0x8000,
|
||||
};
|
||||
|
||||
ObjCDeclSpec()
|
||||
: objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
|
||||
Nullability(0), GetterName(nullptr), SetterName(nullptr) { }
|
||||
: objcDeclQualifier(DQ_None),
|
||||
PropertyAttributes(ObjCPropertyAttribute::kind_noattr), Nullability(0),
|
||||
GetterName(nullptr), SetterName(nullptr) {}
|
||||
|
||||
ObjCDeclQualifier getObjCDeclQualifier() const {
|
||||
return (ObjCDeclQualifier)objcDeclQualifier;
|
||||
@ -877,31 +857,34 @@ public:
|
||||
objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal);
|
||||
}
|
||||
|
||||
ObjCPropertyAttributeKind getPropertyAttributes() const {
|
||||
return ObjCPropertyAttributeKind(PropertyAttributes);
|
||||
ObjCPropertyAttribute::Kind getPropertyAttributes() const {
|
||||
return ObjCPropertyAttribute::Kind(PropertyAttributes);
|
||||
}
|
||||
void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) {
|
||||
void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) {
|
||||
PropertyAttributes =
|
||||
(ObjCPropertyAttributeKind)(PropertyAttributes | PRVal);
|
||||
(ObjCPropertyAttribute::Kind)(PropertyAttributes | PRVal);
|
||||
}
|
||||
|
||||
NullabilityKind getNullability() const {
|
||||
assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
|
||||
(getPropertyAttributes() & DQ_PR_nullability)) &&
|
||||
assert(
|
||||
((getObjCDeclQualifier() & DQ_CSNullability) ||
|
||||
(getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) &&
|
||||
"Objective-C declspec doesn't have nullability");
|
||||
return static_cast<NullabilityKind>(Nullability);
|
||||
}
|
||||
|
||||
SourceLocation getNullabilityLoc() const {
|
||||
assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
|
||||
(getPropertyAttributes() & DQ_PR_nullability)) &&
|
||||
assert(
|
||||
((getObjCDeclQualifier() & DQ_CSNullability) ||
|
||||
(getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) &&
|
||||
"Objective-C declspec doesn't have nullability");
|
||||
return NullabilityLoc;
|
||||
}
|
||||
|
||||
void setNullability(SourceLocation loc, NullabilityKind kind) {
|
||||
assert(((getObjCDeclQualifier() & DQ_CSNullability) ||
|
||||
(getPropertyAttributes() & DQ_PR_nullability)) &&
|
||||
assert(
|
||||
((getObjCDeclQualifier() & DQ_CSNullability) ||
|
||||
(getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) &&
|
||||
"Set the nullability declspec or property attribute first");
|
||||
Nullability = static_cast<unsigned>(kind);
|
||||
NullabilityLoc = loc;
|
||||
@ -929,8 +912,8 @@ private:
|
||||
// (space saving is negligible).
|
||||
unsigned objcDeclQualifier : 7;
|
||||
|
||||
// NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
|
||||
unsigned PropertyAttributes : 16;
|
||||
// NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttribute::Kind
|
||||
unsigned PropertyAttributes : NumObjCPropertyAttrsBits;
|
||||
|
||||
unsigned Nullability : 2;
|
||||
|
||||
|
@ -231,8 +231,7 @@ static void checkAllAtProps(MigrationContext &MigrateCtx,
|
||||
|
||||
SmallVector<std::pair<AttributedTypeLoc, ObjCPropertyDecl *>, 4> ATLs;
|
||||
bool hasWeak = false, hasStrong = false;
|
||||
ObjCPropertyDecl::PropertyAttributeKind
|
||||
Attrs = ObjCPropertyDecl::OBJC_PR_noattr;
|
||||
ObjCPropertyAttribute::Kind Attrs = ObjCPropertyAttribute::kind_noattr;
|
||||
for (IndivPropsTy::iterator
|
||||
PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) {
|
||||
ObjCPropertyDecl *PD = *PI;
|
||||
@ -274,7 +273,7 @@ static void checkAllAtProps(MigrationContext &MigrateCtx,
|
||||
else
|
||||
toAttr = "unsafe_unretained";
|
||||
}
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_assign)
|
||||
MigrateCtx.rewritePropertyAttribute("assign", toAttr, AtLoc);
|
||||
else
|
||||
MigrateCtx.addPropertyAttribute(toAttr, AtLoc);
|
||||
@ -302,8 +301,8 @@ static void checkAllProps(MigrationContext &MigrateCtx,
|
||||
for (unsigned i = 0, e = AllProps.size(); i != e; ++i) {
|
||||
ObjCPropertyDecl *PD = AllProps[i];
|
||||
if (PD->getPropertyAttributesAsWritten() &
|
||||
(ObjCPropertyDecl::OBJC_PR_assign |
|
||||
ObjCPropertyDecl::OBJC_PR_readonly)) {
|
||||
(ObjCPropertyAttribute::kind_assign |
|
||||
ObjCPropertyAttribute::kind_readonly)) {
|
||||
SourceLocation AtLoc = PD->getAtLoc();
|
||||
if (AtLoc.isInvalid())
|
||||
continue;
|
||||
|
@ -168,22 +168,22 @@ private:
|
||||
}
|
||||
|
||||
void rewriteProperty(PropsTy &props, SourceLocation atLoc) {
|
||||
ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props);
|
||||
ObjCPropertyAttribute::Kind propAttrs = getPropertyAttrs(props);
|
||||
|
||||
if (propAttrs & (ObjCPropertyDecl::OBJC_PR_copy |
|
||||
ObjCPropertyDecl::OBJC_PR_unsafe_unretained |
|
||||
ObjCPropertyDecl::OBJC_PR_strong |
|
||||
ObjCPropertyDecl::OBJC_PR_weak))
|
||||
if (propAttrs &
|
||||
(ObjCPropertyAttribute::kind_copy |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained |
|
||||
ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak))
|
||||
return;
|
||||
|
||||
if (propAttrs & ObjCPropertyDecl::OBJC_PR_retain) {
|
||||
if (propAttrs & ObjCPropertyAttribute::kind_retain) {
|
||||
// strong is the default.
|
||||
return doPropAction(PropAction_RetainReplacedWithStrong, props, atLoc);
|
||||
}
|
||||
|
||||
bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props);
|
||||
|
||||
if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) {
|
||||
if (propAttrs & ObjCPropertyAttribute::kind_assign) {
|
||||
if (HasIvarAssignedAPlusOneObject)
|
||||
return doPropAction(PropAction_AssignRemoved, props, atLoc);
|
||||
return doPropAction(PropAction_AssignRewritten, props, atLoc);
|
||||
@ -354,11 +354,10 @@ private:
|
||||
return ty;
|
||||
}
|
||||
|
||||
ObjCPropertyDecl::PropertyAttributeKind
|
||||
getPropertyAttrs(PropsTy &props) const {
|
||||
ObjCPropertyAttribute::Kind getPropertyAttrs(PropsTy &props) const {
|
||||
assert(!props.empty());
|
||||
ObjCPropertyDecl::PropertyAttributeKind
|
||||
attrs = props[0].PropD->getPropertyAttributesAsWritten();
|
||||
ObjCPropertyAttribute::Kind attrs =
|
||||
props[0].PropD->getPropertyAttributesAsWritten();
|
||||
|
||||
#ifndef NDEBUG
|
||||
for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
|
||||
|
@ -118,12 +118,10 @@ public:
|
||||
ObjCPropertyDecl *PD = PID->getPropertyDecl();
|
||||
ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
|
||||
if (!(setterM && setterM->isDefined())) {
|
||||
ObjCPropertyDecl::PropertyAttributeKind AttrKind =
|
||||
PD->getPropertyAttributes();
|
||||
if (AttrKind &
|
||||
(ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_copy |
|
||||
ObjCPropertyDecl::OBJC_PR_strong))
|
||||
ObjCPropertyAttribute::Kind AttrKind = PD->getPropertyAttributes();
|
||||
if (AttrKind & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_copy |
|
||||
ObjCPropertyAttribute::kind_strong))
|
||||
SynthesizedProperties[PD] = PID;
|
||||
}
|
||||
}
|
||||
|
@ -6770,11 +6770,11 @@ ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
|
||||
|
||||
if (PD->isReadOnly()) {
|
||||
S += ",R";
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy)
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_copy)
|
||||
S += ",C";
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain)
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_retain)
|
||||
S += ",&";
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak)
|
||||
S += ",W";
|
||||
} else {
|
||||
switch (PD->getSetterKind()) {
|
||||
@ -6790,15 +6790,15 @@ ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
|
||||
if (Dynamic)
|
||||
S += ",D";
|
||||
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_nonatomic)
|
||||
S += ",N";
|
||||
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_getter) {
|
||||
S += ",G";
|
||||
S += PD->getGetterName().getAsString();
|
||||
}
|
||||
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
|
||||
if (PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_setter) {
|
||||
S += ",S";
|
||||
S += PD->getSetterName().getAsString();
|
||||
}
|
||||
|
@ -146,7 +146,8 @@ bool ObjCContainerDecl::HasUserDeclaredSetterMethod(
|
||||
// auto-synthesized).
|
||||
for (const auto *P : Cat->properties())
|
||||
if (P->getIdentifier() == Property->getIdentifier()) {
|
||||
if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
|
||||
if (P->getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_readwrite)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
@ -1428,85 +1428,83 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
|
||||
QualType T = PDecl->getType();
|
||||
|
||||
Out << "@property";
|
||||
if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
|
||||
if (PDecl->getPropertyAttributes() != ObjCPropertyAttribute::kind_noattr) {
|
||||
bool first = true;
|
||||
Out << "(";
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_class) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_class) {
|
||||
Out << (first ? "" : ", ") << "class";
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_direct) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_direct) {
|
||||
Out << (first ? "" : ", ") << "direct";
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_nonatomic) {
|
||||
ObjCPropertyAttribute::kind_nonatomic) {
|
||||
Out << (first ? "" : ", ") << "nonatomic";
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_atomic) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic) {
|
||||
Out << (first ? "" : ", ") << "atomic";
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_assign) {
|
||||
Out << (first ? "" : ", ") << "assign";
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_retain) {
|
||||
Out << (first ? "" : ", ") << "retain";
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_strong) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_strong) {
|
||||
Out << (first ? "" : ", ") << "strong";
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_copy) {
|
||||
Out << (first ? "" : ", ") << "copy";
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak) {
|
||||
Out << (first ? "" : ", ") << "weak";
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes()
|
||||
& ObjCPropertyDecl::OBJC_PR_unsafe_unretained) {
|
||||
if (PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained) {
|
||||
Out << (first ? "" : ", ") << "unsafe_unretained";
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_readwrite) {
|
||||
ObjCPropertyAttribute::kind_readwrite) {
|
||||
Out << (first ? "" : ", ") << "readwrite";
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_readonly) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_readonly) {
|
||||
Out << (first ? "" : ", ") << "readonly";
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_getter) {
|
||||
Out << (first ? "" : ", ") << "getter = ";
|
||||
PDecl->getGetterName().print(Out);
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
|
||||
if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_setter) {
|
||||
Out << (first ? "" : ", ") << "setter = ";
|
||||
PDecl->getSetterName().print(Out);
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_nullability) {
|
||||
ObjCPropertyAttribute::kind_nullability) {
|
||||
if (auto nullability = AttributedType::stripOuterNullability(T)) {
|
||||
if (*nullability == NullabilityKind::Unspecified &&
|
||||
(PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_null_resettable)) {
|
||||
ObjCPropertyAttribute::kind_null_resettable)) {
|
||||
Out << (first ? "" : ", ") << "null_resettable";
|
||||
} else {
|
||||
Out << (first ? "" : ", ")
|
||||
|
@ -999,31 +999,32 @@ void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
|
||||
case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break;
|
||||
}
|
||||
|
||||
ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
|
||||
if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
|
||||
ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
|
||||
if (Attrs != ObjCPropertyAttribute::kind_noattr) {
|
||||
if (Attrs & ObjCPropertyAttribute::kind_getter)
|
||||
JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_setter)
|
||||
JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));
|
||||
attributeOnlyIfTrue("readonly", Attrs & ObjCPropertyDecl::OBJC_PR_readonly);
|
||||
attributeOnlyIfTrue("assign", Attrs & ObjCPropertyDecl::OBJC_PR_assign);
|
||||
attributeOnlyIfTrue("readonly",
|
||||
Attrs & ObjCPropertyAttribute::kind_readonly);
|
||||
attributeOnlyIfTrue("assign", Attrs & ObjCPropertyAttribute::kind_assign);
|
||||
attributeOnlyIfTrue("readwrite",
|
||||
Attrs & ObjCPropertyDecl::OBJC_PR_readwrite);
|
||||
attributeOnlyIfTrue("retain", Attrs & ObjCPropertyDecl::OBJC_PR_retain);
|
||||
attributeOnlyIfTrue("copy", Attrs & ObjCPropertyDecl::OBJC_PR_copy);
|
||||
Attrs & ObjCPropertyAttribute::kind_readwrite);
|
||||
attributeOnlyIfTrue("retain", Attrs & ObjCPropertyAttribute::kind_retain);
|
||||
attributeOnlyIfTrue("copy", Attrs & ObjCPropertyAttribute::kind_copy);
|
||||
attributeOnlyIfTrue("nonatomic",
|
||||
Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic);
|
||||
attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyDecl::OBJC_PR_atomic);
|
||||
attributeOnlyIfTrue("weak", Attrs & ObjCPropertyDecl::OBJC_PR_weak);
|
||||
attributeOnlyIfTrue("strong", Attrs & ObjCPropertyDecl::OBJC_PR_strong);
|
||||
Attrs & ObjCPropertyAttribute::kind_nonatomic);
|
||||
attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyAttribute::kind_atomic);
|
||||
attributeOnlyIfTrue("weak", Attrs & ObjCPropertyAttribute::kind_weak);
|
||||
attributeOnlyIfTrue("strong", Attrs & ObjCPropertyAttribute::kind_strong);
|
||||
attributeOnlyIfTrue("unsafe_unretained",
|
||||
Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
|
||||
attributeOnlyIfTrue("class", Attrs & ObjCPropertyDecl::OBJC_PR_class);
|
||||
attributeOnlyIfTrue("direct", Attrs & ObjCPropertyDecl::OBJC_PR_direct);
|
||||
Attrs & ObjCPropertyAttribute::kind_unsafe_unretained);
|
||||
attributeOnlyIfTrue("class", Attrs & ObjCPropertyAttribute::kind_class);
|
||||
attributeOnlyIfTrue("direct", Attrs & ObjCPropertyAttribute::kind_direct);
|
||||
attributeOnlyIfTrue("nullability",
|
||||
Attrs & ObjCPropertyDecl::OBJC_PR_nullability);
|
||||
Attrs & ObjCPropertyAttribute::kind_nullability);
|
||||
attributeOnlyIfTrue("null_resettable",
|
||||
Attrs & ObjCPropertyDecl::OBJC_PR_null_resettable);
|
||||
Attrs & ObjCPropertyAttribute::kind_null_resettable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1958,35 +1958,35 @@ void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
|
||||
else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
|
||||
OS << " optional";
|
||||
|
||||
ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
|
||||
if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
|
||||
ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
|
||||
if (Attrs != ObjCPropertyAttribute::kind_noattr) {
|
||||
if (Attrs & ObjCPropertyAttribute::kind_readonly)
|
||||
OS << " readonly";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_assign)
|
||||
OS << " assign";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_readwrite)
|
||||
OS << " readwrite";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_retain)
|
||||
OS << " retain";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_copy)
|
||||
OS << " copy";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
|
||||
OS << " nonatomic";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_atomic)
|
||||
OS << " atomic";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_weak)
|
||||
OS << " weak";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_strong)
|
||||
OS << " strong";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
|
||||
OS << " unsafe_unretained";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_class)
|
||||
OS << " class";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_direct)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_direct)
|
||||
OS << " direct";
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_getter)
|
||||
dumpDeclRef(D->getGetterMethodDecl(), "getter");
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
|
||||
if (Attrs & ObjCPropertyAttribute::kind_setter)
|
||||
dumpDeclRef(D->getSetterMethodDecl(), "setter");
|
||||
}
|
||||
}
|
||||
|
@ -762,7 +762,7 @@ static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
|
||||
return nullptr;
|
||||
|
||||
// Ignore weak variables, which have special behavior.
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak)
|
||||
return nullptr;
|
||||
|
||||
// Look to see if Sema has synthesized a body for us. This happens in
|
||||
|
@ -3505,7 +3505,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
|
||||
if (!Ty->isRecordType())
|
||||
return nullptr;
|
||||
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
|
||||
if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
|
||||
if ((!(PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic)))
|
||||
return nullptr;
|
||||
llvm::Constant *HelperFn = nullptr;
|
||||
if (hasTrivialSetExpr(PID))
|
||||
@ -3589,7 +3589,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
|
||||
QualType Ty = PD->getType();
|
||||
if (!Ty->isRecordType())
|
||||
return nullptr;
|
||||
if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
|
||||
if ((!(PD->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic)))
|
||||
return nullptr;
|
||||
llvm::Constant *HelperFn = nullptr;
|
||||
if (hasTrivialGetExpr(PID))
|
||||
|
@ -255,11 +255,11 @@ protected:
|
||||
isDynamic=true) {
|
||||
int attrs = property->getPropertyAttributes();
|
||||
// For read-only properties, clear the copy and retain flags
|
||||
if (attrs & ObjCPropertyDecl::OBJC_PR_readonly) {
|
||||
attrs &= ~ObjCPropertyDecl::OBJC_PR_copy;
|
||||
attrs &= ~ObjCPropertyDecl::OBJC_PR_retain;
|
||||
attrs &= ~ObjCPropertyDecl::OBJC_PR_weak;
|
||||
attrs &= ~ObjCPropertyDecl::OBJC_PR_strong;
|
||||
if (attrs & ObjCPropertyAttribute::kind_readonly) {
|
||||
attrs &= ~ObjCPropertyAttribute::kind_copy;
|
||||
attrs &= ~ObjCPropertyAttribute::kind_retain;
|
||||
attrs &= ~ObjCPropertyAttribute::kind_weak;
|
||||
attrs &= ~ObjCPropertyAttribute::kind_strong;
|
||||
}
|
||||
// The first flags field has the same attribute values as clang uses internally
|
||||
Fields.addInt(Int8Ty, attrs & 0xff);
|
||||
|
@ -941,9 +941,10 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||
|
||||
unsigned Attributes = PD->getPropertyAttributes();
|
||||
if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
|
||||
bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
|
||||
(Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_copy));
|
||||
bool GenGetProperty =
|
||||
!(Attributes & ObjCPropertyAttribute::kind_nonatomic) &&
|
||||
(Attributes & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_copy));
|
||||
std::string Getr;
|
||||
if (GenGetProperty && !objcGetPropertyDefined) {
|
||||
objcGetPropertyDefined = true;
|
||||
@ -1002,8 +1003,8 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||
|
||||
// Generate the 'setter' function.
|
||||
std::string Setr;
|
||||
bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_copy);
|
||||
bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_copy);
|
||||
if (GenSetProperty && !objcSetPropertyDefined) {
|
||||
objcSetPropertyDefined = true;
|
||||
// FIXME. Is this attribute correct in all cases?
|
||||
@ -1022,11 +1023,11 @@ void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||
Setr += ", (id)";
|
||||
Setr += PD->getName();
|
||||
Setr += ", ";
|
||||
if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
|
||||
Setr += "0, ";
|
||||
else
|
||||
Setr += "1, ";
|
||||
if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
|
||||
if (Attributes & ObjCPropertyAttribute::kind_copy)
|
||||
Setr += "1)";
|
||||
else
|
||||
Setr += "0)";
|
||||
|
@ -789,9 +789,10 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||
|
||||
unsigned Attributes = PD->getPropertyAttributes();
|
||||
if (PID->getGetterMethodDecl() && !PID->getGetterMethodDecl()->isDefined()) {
|
||||
bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
|
||||
(Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_copy));
|
||||
bool GenGetProperty =
|
||||
!(Attributes & ObjCPropertyAttribute::kind_nonatomic) &&
|
||||
(Attributes & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_copy));
|
||||
std::string Getr;
|
||||
if (GenGetProperty && !objcGetPropertyDefined) {
|
||||
objcGetPropertyDefined = true;
|
||||
@ -850,8 +851,8 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||
|
||||
// Generate the 'setter' function.
|
||||
std::string Setr;
|
||||
bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_copy);
|
||||
bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_copy);
|
||||
if (GenSetProperty && !objcSetPropertyDefined) {
|
||||
objcSetPropertyDefined = true;
|
||||
// FIXME. Is this attribute correct in all cases?
|
||||
@ -870,11 +871,11 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
|
||||
Setr += ", (id)";
|
||||
Setr += PD->getName();
|
||||
Setr += ", ";
|
||||
if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
|
||||
Setr += "0, ";
|
||||
else
|
||||
Setr += "1, ";
|
||||
if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
|
||||
if (Attributes & ObjCPropertyAttribute::kind_copy)
|
||||
Setr += "1)";
|
||||
else
|
||||
Setr += "0)";
|
||||
|
@ -740,7 +740,8 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
|
||||
|
||||
// Map a nullability property attribute to a context-sensitive keyword
|
||||
// attribute.
|
||||
if (OCDS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
|
||||
if (OCDS.getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_nullability)
|
||||
addContextSensitiveTypeNullability(*this, FD.D, OCDS.getNullability(),
|
||||
OCDS.getNullabilityLoc(),
|
||||
addedToDeclSpec);
|
||||
@ -860,25 +861,25 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||
SourceLocation AttrName = ConsumeToken(); // consume last attribute name
|
||||
|
||||
if (II->isStr("readonly"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);
|
||||
else if (II->isStr("assign"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
|
||||
else if (II->isStr("unsafe_unretained"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_unsafe_unretained);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_unsafe_unretained);
|
||||
else if (II->isStr("readwrite"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite);
|
||||
else if (II->isStr("retain"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_retain);
|
||||
else if (II->isStr("strong"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_strong);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_strong);
|
||||
else if (II->isStr("copy"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_copy);
|
||||
else if (II->isStr("nonatomic"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic);
|
||||
else if (II->isStr("atomic"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_atomic);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_atomic);
|
||||
else if (II->isStr("weak"))
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_weak);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_weak);
|
||||
else if (II->isStr("getter") || II->isStr("setter")) {
|
||||
bool IsSetter = II->getNameStart()[0] == 's';
|
||||
|
||||
@ -910,7 +911,7 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||
}
|
||||
|
||||
if (IsSetter) {
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_setter);
|
||||
DS.setSetterName(SelIdent, SelLoc);
|
||||
|
||||
if (ExpectAndConsume(tok::colon,
|
||||
@ -919,44 +920,44 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_getter);
|
||||
DS.setGetterName(SelIdent, SelLoc);
|
||||
}
|
||||
} else if (II->isStr("nonnull")) {
|
||||
if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
|
||||
if (DS.getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)
|
||||
diagnoseRedundantPropertyNullability(*this, DS,
|
||||
NullabilityKind::NonNull,
|
||||
Tok.getLocation());
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_nullability);
|
||||
DS.setNullability(Tok.getLocation(), NullabilityKind::NonNull);
|
||||
} else if (II->isStr("nullable")) {
|
||||
if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
|
||||
if (DS.getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)
|
||||
diagnoseRedundantPropertyNullability(*this, DS,
|
||||
NullabilityKind::Nullable,
|
||||
Tok.getLocation());
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_nullability);
|
||||
DS.setNullability(Tok.getLocation(), NullabilityKind::Nullable);
|
||||
} else if (II->isStr("null_unspecified")) {
|
||||
if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
|
||||
if (DS.getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)
|
||||
diagnoseRedundantPropertyNullability(*this, DS,
|
||||
NullabilityKind::Unspecified,
|
||||
Tok.getLocation());
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_nullability);
|
||||
DS.setNullability(Tok.getLocation(), NullabilityKind::Unspecified);
|
||||
} else if (II->isStr("null_resettable")) {
|
||||
if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
|
||||
if (DS.getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)
|
||||
diagnoseRedundantPropertyNullability(*this, DS,
|
||||
NullabilityKind::Unspecified,
|
||||
Tok.getLocation());
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_nullability);
|
||||
DS.setNullability(Tok.getLocation(), NullabilityKind::Unspecified);
|
||||
|
||||
// Also set the null_resettable bit.
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_null_resettable);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_null_resettable);
|
||||
} else if (II->isStr("class")) {
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_class);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_class);
|
||||
} else if (II->isStr("direct")) {
|
||||
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_direct);
|
||||
DS.setPropertyAttributes(ObjCPropertyAttribute::kind_direct);
|
||||
} else {
|
||||
Diag(AttrName, diag::err_objc_expected_property_attr) << II;
|
||||
SkipUntil(tok::r_paren, StopAtSemi);
|
||||
|
@ -13917,12 +13917,12 @@ void Sema::checkUnsafeExprAssigns(SourceLocation Loc,
|
||||
return;
|
||||
|
||||
unsigned Attributes = PD->getPropertyAttributes();
|
||||
if (Attributes & ObjCPropertyDecl::OBJC_PR_assign) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_assign) {
|
||||
// when 'assign' attribute was not explicitly specified
|
||||
// by user, ignore it and rely on property type itself
|
||||
// for lifetime info.
|
||||
unsigned AsWrittenAttr = PD->getPropertyAttributesAsWritten();
|
||||
if (!(AsWrittenAttr & ObjCPropertyDecl::OBJC_PR_assign) &&
|
||||
if (!(AsWrittenAttr & ObjCPropertyAttribute::kind_assign) &&
|
||||
LHSType->isObjCRetainableType())
|
||||
return;
|
||||
|
||||
@ -13934,8 +13934,7 @@ void Sema::checkUnsafeExprAssigns(SourceLocation Loc,
|
||||
}
|
||||
RHS = cast->getSubExpr();
|
||||
}
|
||||
}
|
||||
else if (Attributes & ObjCPropertyDecl::OBJC_PR_weak) {
|
||||
} else if (Attributes & ObjCPropertyAttribute::kind_weak) {
|
||||
if (checkUnsafeAssignObject(*this, Loc, Qualifiers::OCL_Weak, RHS, true))
|
||||
return;
|
||||
}
|
||||
|
@ -6513,22 +6513,24 @@ static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
|
||||
Attributes |= NewFlag;
|
||||
|
||||
// Check for collisions with "readonly".
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_readwrite))
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_readonly) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_readwrite))
|
||||
return true;
|
||||
|
||||
// Check for more than one of { assign, copy, retain, strong, weak }.
|
||||
unsigned AssignCopyRetMask =
|
||||
Attributes &
|
||||
(ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_unsafe_unretained |
|
||||
ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain |
|
||||
ObjCDeclSpec::DQ_PR_strong | ObjCDeclSpec::DQ_PR_weak);
|
||||
if (AssignCopyRetMask && AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
|
||||
(ObjCPropertyAttribute::kind_assign |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained |
|
||||
ObjCPropertyAttribute::kind_copy | ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak);
|
||||
if (AssignCopyRetMask &&
|
||||
AssignCopyRetMask != ObjCPropertyAttribute::kind_assign &&
|
||||
AssignCopyRetMask != ObjCPropertyAttribute::kind_unsafe_unretained &&
|
||||
AssignCopyRetMask != ObjCPropertyAttribute::kind_copy &&
|
||||
AssignCopyRetMask != ObjCPropertyAttribute::kind_retain &&
|
||||
AssignCopyRetMask != ObjCPropertyAttribute::kind_strong &&
|
||||
AssignCopyRetMask != ObjCPropertyAttribute::kind_weak)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -6544,32 +6546,41 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
|
||||
CodeCompleter->getCodeCompletionTUInfo(),
|
||||
CodeCompletionContext::CCC_Other);
|
||||
Results.EnterNewScope();
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_readonly))
|
||||
Results.AddResult(CodeCompletionResult("readonly"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_assign))
|
||||
Results.AddResult(CodeCompletionResult("assign"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCDeclSpec::DQ_PR_unsafe_unretained))
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained))
|
||||
Results.AddResult(CodeCompletionResult("unsafe_unretained"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_readwrite))
|
||||
Results.AddResult(CodeCompletionResult("readwrite"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_retain))
|
||||
Results.AddResult(CodeCompletionResult("retain"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_strong))
|
||||
Results.AddResult(CodeCompletionResult("strong"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCPropertyAttribute::kind_copy))
|
||||
Results.AddResult(CodeCompletionResult("copy"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_nonatomic))
|
||||
Results.AddResult(CodeCompletionResult("nonatomic"));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_atomic))
|
||||
Results.AddResult(CodeCompletionResult("atomic"));
|
||||
|
||||
// Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
|
||||
if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_weak))
|
||||
Results.AddResult(CodeCompletionResult("weak"));
|
||||
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_setter)) {
|
||||
CodeCompletionBuilder Setter(Results.getAllocator(),
|
||||
Results.getCodeCompletionTUInfo());
|
||||
Setter.AddTypedTextChunk("setter");
|
||||
@ -6577,7 +6588,8 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
|
||||
Setter.AddPlaceholderChunk("method");
|
||||
Results.AddResult(CodeCompletionResult(Setter.TakeString()));
|
||||
}
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_getter)) {
|
||||
CodeCompletionBuilder Getter(Results.getAllocator(),
|
||||
Results.getCodeCompletionTUInfo());
|
||||
Getter.AddTypedTextChunk("getter");
|
||||
@ -6585,7 +6597,8 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
|
||||
Getter.AddPlaceholderChunk("method");
|
||||
Results.AddResult(CodeCompletionResult(Getter.TakeString()));
|
||||
}
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nullability)) {
|
||||
if (!ObjCPropertyFlagConflicts(Attributes,
|
||||
ObjCPropertyAttribute::kind_nullability)) {
|
||||
Results.AddResult(CodeCompletionResult("nonnull"));
|
||||
Results.AddResult(CodeCompletionResult("nullable"));
|
||||
Results.AddResult(CodeCompletionResult("null_unspecified"));
|
||||
|
@ -1953,7 +1953,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
|
||||
if (const ObjCPropertyDecl *PDecl = Setter->findPropertyDecl()) {
|
||||
// Do not warn if user is using property-dot syntax to make call to
|
||||
// user named setter.
|
||||
if (!(PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter))
|
||||
if (!(PDecl->getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_setter))
|
||||
Diag(MemberLoc,
|
||||
diag::warn_property_access_suggest)
|
||||
<< MemberName << QualType(OPT, 0) << PDecl->getName()
|
||||
@ -3258,7 +3259,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
||||
if (!isImplicit && Method) {
|
||||
if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
|
||||
bool IsWeak =
|
||||
Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak;
|
||||
Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak;
|
||||
if (!IsWeak && Sel.isUnarySelector())
|
||||
IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
|
||||
if (IsWeak && !isUnevaluatedContext() &&
|
||||
|
@ -35,24 +35,23 @@ using namespace clang;
|
||||
///
|
||||
/// Returns OCL_None if the attributes as stated do not imply an ownership.
|
||||
/// Never returns OCL_Autoreleasing.
|
||||
static Qualifiers::ObjCLifetime getImpliedARCOwnership(
|
||||
ObjCPropertyDecl::PropertyAttributeKind attrs,
|
||||
QualType type) {
|
||||
static Qualifiers::ObjCLifetime
|
||||
getImpliedARCOwnership(ObjCPropertyAttribute::Kind attrs, QualType type) {
|
||||
// retain, strong, copy, weak, and unsafe_unretained are only legal
|
||||
// on properties of retainable pointer type.
|
||||
if (attrs & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_strong |
|
||||
ObjCPropertyDecl::OBJC_PR_copy)) {
|
||||
if (attrs &
|
||||
(ObjCPropertyAttribute::kind_retain | ObjCPropertyAttribute::kind_strong |
|
||||
ObjCPropertyAttribute::kind_copy)) {
|
||||
return Qualifiers::OCL_Strong;
|
||||
} else if (attrs & ObjCPropertyDecl::OBJC_PR_weak) {
|
||||
} else if (attrs & ObjCPropertyAttribute::kind_weak) {
|
||||
return Qualifiers::OCL_Weak;
|
||||
} else if (attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) {
|
||||
} else if (attrs & ObjCPropertyAttribute::kind_unsafe_unretained) {
|
||||
return Qualifiers::OCL_ExplicitNone;
|
||||
}
|
||||
|
||||
// assign can appear on other types, so we have to check the
|
||||
// property type.
|
||||
if (attrs & ObjCPropertyDecl::OBJC_PR_assign &&
|
||||
if (attrs & ObjCPropertyAttribute::kind_assign &&
|
||||
type->isObjCRetainableType()) {
|
||||
return Qualifiers::OCL_ExplicitNone;
|
||||
}
|
||||
@ -66,8 +65,7 @@ static void checkPropertyDeclWithOwnership(Sema &S,
|
||||
ObjCPropertyDecl *property) {
|
||||
if (property->isInvalidDecl()) return;
|
||||
|
||||
ObjCPropertyDecl::PropertyAttributeKind propertyKind
|
||||
= property->getPropertyAttributes();
|
||||
ObjCPropertyAttribute::Kind propertyKind = property->getPropertyAttributes();
|
||||
Qualifiers::ObjCLifetime propertyLifetime
|
||||
= property->getType().getObjCLifetime();
|
||||
|
||||
@ -80,14 +78,14 @@ static void checkPropertyDeclWithOwnership(Sema &S,
|
||||
// attribute. That's okay, but restore reasonable invariants by
|
||||
// setting the property attribute according to the lifetime
|
||||
// qualifier.
|
||||
ObjCPropertyDecl::PropertyAttributeKind attr;
|
||||
ObjCPropertyAttribute::Kind attr;
|
||||
if (propertyLifetime == Qualifiers::OCL_Strong) {
|
||||
attr = ObjCPropertyDecl::OBJC_PR_strong;
|
||||
attr = ObjCPropertyAttribute::kind_strong;
|
||||
} else if (propertyLifetime == Qualifiers::OCL_Weak) {
|
||||
attr = ObjCPropertyDecl::OBJC_PR_weak;
|
||||
attr = ObjCPropertyAttribute::kind_weak;
|
||||
} else {
|
||||
assert(propertyLifetime == Qualifiers::OCL_ExplicitNone);
|
||||
attr = ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
|
||||
attr = ObjCPropertyAttribute::kind_unsafe_unretained;
|
||||
}
|
||||
property->setPropertyAttributes(attr);
|
||||
return;
|
||||
@ -130,18 +128,19 @@ CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop,
|
||||
static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T) {
|
||||
// In GC mode, just look for the __weak qualifier.
|
||||
if (S.getLangOpts().getGC() != LangOptions::NonGC) {
|
||||
if (T.isObjCGCWeak()) return ObjCDeclSpec::DQ_PR_weak;
|
||||
if (T.isObjCGCWeak())
|
||||
return ObjCPropertyAttribute::kind_weak;
|
||||
|
||||
// In ARC/MRC, look for an explicit ownership qualifier.
|
||||
// For some reason, this only applies to __weak.
|
||||
} else if (auto ownership = T.getObjCLifetime()) {
|
||||
switch (ownership) {
|
||||
case Qualifiers::OCL_Weak:
|
||||
return ObjCDeclSpec::DQ_PR_weak;
|
||||
return ObjCPropertyAttribute::kind_weak;
|
||||
case Qualifiers::OCL_Strong:
|
||||
return ObjCDeclSpec::DQ_PR_strong;
|
||||
return ObjCPropertyAttribute::kind_strong;
|
||||
case Qualifiers::OCL_ExplicitNone:
|
||||
return ObjCDeclSpec::DQ_PR_unsafe_unretained;
|
||||
return ObjCPropertyAttribute::kind_unsafe_unretained;
|
||||
case Qualifiers::OCL_Autoreleasing:
|
||||
case Qualifiers::OCL_None:
|
||||
return 0;
|
||||
@ -153,22 +152,20 @@ static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T) {
|
||||
}
|
||||
|
||||
static const unsigned OwnershipMask =
|
||||
(ObjCPropertyDecl::OBJC_PR_assign |
|
||||
ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_copy |
|
||||
ObjCPropertyDecl::OBJC_PR_weak |
|
||||
ObjCPropertyDecl::OBJC_PR_strong |
|
||||
ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
|
||||
(ObjCPropertyAttribute::kind_assign | ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_copy | ObjCPropertyAttribute::kind_weak |
|
||||
ObjCPropertyAttribute::kind_strong |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained);
|
||||
|
||||
static unsigned getOwnershipRule(unsigned attr) {
|
||||
unsigned result = attr & OwnershipMask;
|
||||
|
||||
// From an ownership perspective, assign and unsafe_unretained are
|
||||
// identical; make sure one also implies the other.
|
||||
if (result & (ObjCPropertyDecl::OBJC_PR_assign |
|
||||
ObjCPropertyDecl::OBJC_PR_unsafe_unretained)) {
|
||||
result |= ObjCPropertyDecl::OBJC_PR_assign |
|
||||
ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
|
||||
if (result & (ObjCPropertyAttribute::kind_assign |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained)) {
|
||||
result |= ObjCPropertyAttribute::kind_assign |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -183,15 +180,16 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
|
||||
tok::ObjCKeywordKind MethodImplKind,
|
||||
DeclContext *lexicalDC) {
|
||||
unsigned Attributes = ODS.getPropertyAttributes();
|
||||
FD.D.setObjCWeakProperty((Attributes & ObjCDeclSpec::DQ_PR_weak) != 0);
|
||||
FD.D.setObjCWeakProperty((Attributes & ObjCPropertyAttribute::kind_weak) !=
|
||||
0);
|
||||
TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
|
||||
QualType T = TSI->getType();
|
||||
if (!getOwnershipRule(Attributes)) {
|
||||
Attributes |= deducePropertyOwnershipFromType(*this, T);
|
||||
}
|
||||
bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
|
||||
bool isReadWrite = ((Attributes & ObjCPropertyAttribute::kind_readwrite) ||
|
||||
// default is readwrite!
|
||||
!(Attributes & ObjCDeclSpec::DQ_PR_readonly));
|
||||
!(Attributes & ObjCPropertyAttribute::kind_readonly));
|
||||
|
||||
// Proceed with constructing the ObjCPropertyDecls.
|
||||
ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
|
||||
@ -277,39 +275,39 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
|
||||
return Res;
|
||||
}
|
||||
|
||||
static ObjCPropertyDecl::PropertyAttributeKind
|
||||
static ObjCPropertyAttribute::Kind
|
||||
makePropertyAttributesAsWritten(unsigned Attributes) {
|
||||
unsigned attributesAsWritten = 0;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_getter)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_setter)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_assign)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_retain)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_strong)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_weak)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_copy)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_class)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_class;
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_direct)
|
||||
attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_direct;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_readonly)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_readonly;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_readwrite)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_readwrite;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_getter)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_getter;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_setter)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_setter;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_assign)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_assign;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_retain)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_retain;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_strong)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_strong;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_weak)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_weak;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_copy)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_copy;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_unsafe_unretained)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_unsafe_unretained;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_nonatomic;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_atomic)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_atomic;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_class)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_class;
|
||||
if (Attributes & ObjCPropertyAttribute::kind_direct)
|
||||
attributesAsWritten |= ObjCPropertyAttribute::kind_direct;
|
||||
|
||||
return (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten;
|
||||
return (ObjCPropertyAttribute::Kind)attributesAsWritten;
|
||||
}
|
||||
|
||||
static bool LocPropertyAttribute( ASTContext &Context, const char *attrName,
|
||||
@ -347,12 +345,10 @@ static void checkAtomicPropertyMismatch(Sema &S,
|
||||
ObjCPropertyDecl *NewProperty,
|
||||
bool PropagateAtomicity) {
|
||||
// If the atomicity of both matches, we're done.
|
||||
bool OldIsAtomic =
|
||||
(OldProperty->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
== 0;
|
||||
bool NewIsAtomic =
|
||||
(NewProperty->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic)
|
||||
== 0;
|
||||
bool OldIsAtomic = (OldProperty->getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_nonatomic) == 0;
|
||||
bool NewIsAtomic = (NewProperty->getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_nonatomic) == 0;
|
||||
if (OldIsAtomic == NewIsAtomic) return;
|
||||
|
||||
// Determine whether the given property is readonly and implicitly
|
||||
@ -360,14 +356,16 @@ static void checkAtomicPropertyMismatch(Sema &S,
|
||||
auto isImplicitlyReadonlyAtomic = [](ObjCPropertyDecl *Property) -> bool {
|
||||
// Is it readonly?
|
||||
auto Attrs = Property->getPropertyAttributes();
|
||||
if ((Attrs & ObjCPropertyDecl::OBJC_PR_readonly) == 0) return false;
|
||||
if ((Attrs & ObjCPropertyAttribute::kind_readonly) == 0)
|
||||
return false;
|
||||
|
||||
// Is it nonatomic?
|
||||
if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) return false;
|
||||
if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
|
||||
return false;
|
||||
|
||||
// Was 'atomic' specified directly?
|
||||
if (Property->getPropertyAttributesAsWritten() &
|
||||
ObjCPropertyDecl::OBJC_PR_atomic)
|
||||
ObjCPropertyAttribute::kind_atomic)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -375,16 +373,16 @@ static void checkAtomicPropertyMismatch(Sema &S,
|
||||
|
||||
// If we're allowed to propagate atomicity, and the new property did
|
||||
// not specify atomicity at all, propagate.
|
||||
const unsigned AtomicityMask =
|
||||
(ObjCPropertyDecl::OBJC_PR_atomic | ObjCPropertyDecl::OBJC_PR_nonatomic);
|
||||
const unsigned AtomicityMask = (ObjCPropertyAttribute::kind_atomic |
|
||||
ObjCPropertyAttribute::kind_nonatomic);
|
||||
if (PropagateAtomicity &&
|
||||
((NewProperty->getPropertyAttributesAsWritten() & AtomicityMask) == 0)) {
|
||||
unsigned Attrs = NewProperty->getPropertyAttributes();
|
||||
Attrs = Attrs & ~AtomicityMask;
|
||||
if (OldIsAtomic)
|
||||
Attrs |= ObjCPropertyDecl::OBJC_PR_atomic;
|
||||
Attrs |= ObjCPropertyAttribute::kind_atomic;
|
||||
else
|
||||
Attrs |= ObjCPropertyDecl::OBJC_PR_nonatomic;
|
||||
Attrs |= ObjCPropertyAttribute::kind_nonatomic;
|
||||
|
||||
NewProperty->overwritePropertyAttributes(Attrs);
|
||||
return;
|
||||
@ -438,8 +436,9 @@ Sema::HandlePropertyInClassExtension(Scope *S,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isClassProperty = (AttributesAsWritten & ObjCDeclSpec::DQ_PR_class) ||
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_class);
|
||||
bool isClassProperty =
|
||||
(AttributesAsWritten & ObjCPropertyAttribute::kind_class) ||
|
||||
(Attributes & ObjCPropertyAttribute::kind_class);
|
||||
|
||||
// Find the property in the extended class's primary class or
|
||||
// extensions.
|
||||
@ -464,9 +463,9 @@ Sema::HandlePropertyInClassExtension(Scope *S,
|
||||
// This is a common error where the user often intended the original
|
||||
// declaration to be readonly.
|
||||
unsigned diag =
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_readwrite) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_readwrite) &&
|
||||
(PIDecl->getPropertyAttributesAsWritten() &
|
||||
ObjCPropertyDecl::OBJC_PR_readwrite)
|
||||
ObjCPropertyAttribute::kind_readwrite)
|
||||
? diag::err_use_continuation_class_redeclaration_readwrite
|
||||
: diag::err_use_continuation_class;
|
||||
Diag(AtLoc, diag)
|
||||
@ -478,7 +477,7 @@ Sema::HandlePropertyInClassExtension(Scope *S,
|
||||
// Check for consistency of getters.
|
||||
if (PIDecl->getGetterName() != GetterSel) {
|
||||
// If the getter was written explicitly, complain.
|
||||
if (AttributesAsWritten & ObjCDeclSpec::DQ_PR_getter) {
|
||||
if (AttributesAsWritten & ObjCPropertyAttribute::kind_getter) {
|
||||
Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
|
||||
<< PIDecl->getGetterName() << GetterSel;
|
||||
Diag(PIDecl->getLocation(), diag::note_property_declare);
|
||||
@ -486,7 +485,7 @@ Sema::HandlePropertyInClassExtension(Scope *S,
|
||||
|
||||
// Always adopt the getter from the original declaration.
|
||||
GetterSel = PIDecl->getGetterName();
|
||||
Attributes |= ObjCDeclSpec::DQ_PR_getter;
|
||||
Attributes |= ObjCPropertyAttribute::kind_getter;
|
||||
}
|
||||
|
||||
// Check consistency of ownership.
|
||||
@ -505,9 +504,9 @@ Sema::HandlePropertyInClassExtension(Scope *S,
|
||||
}
|
||||
|
||||
// If the redeclaration is 'weak' but the original property is not,
|
||||
if ((Attributes & ObjCPropertyDecl::OBJC_PR_weak) &&
|
||||
!(PIDecl->getPropertyAttributesAsWritten()
|
||||
& ObjCPropertyDecl::OBJC_PR_weak) &&
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_weak) &&
|
||||
!(PIDecl->getPropertyAttributesAsWritten() &
|
||||
ObjCPropertyAttribute::kind_weak) &&
|
||||
PIDecl->getType()->getAs<ObjCObjectPointerType>() &&
|
||||
PIDecl->getType().getObjCLifetime() == Qualifiers::OCL_None) {
|
||||
Diag(AtLoc, diag::warn_property_implicitly_mismatched);
|
||||
@ -584,8 +583,8 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
|
||||
// Property defaults to 'assign' if it is readwrite, unless this is ARC
|
||||
// and the type is retainable.
|
||||
bool isAssign;
|
||||
if (Attributes & (ObjCDeclSpec::DQ_PR_assign |
|
||||
ObjCDeclSpec::DQ_PR_unsafe_unretained)) {
|
||||
if (Attributes & (ObjCPropertyAttribute::kind_assign |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained)) {
|
||||
isAssign = true;
|
||||
} else if (getOwnershipRule(Attributes) || !isReadWrite) {
|
||||
isAssign = false;
|
||||
@ -596,8 +595,8 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
|
||||
|
||||
// Issue a warning if property is 'assign' as default and its
|
||||
// object, which is gc'able conforms to NSCopying protocol
|
||||
if (getLangOpts().getGC() != LangOptions::NonGC &&
|
||||
isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) {
|
||||
if (getLangOpts().getGC() != LangOptions::NonGC && isAssign &&
|
||||
!(Attributes & ObjCPropertyAttribute::kind_assign)) {
|
||||
if (const ObjCObjectPointerType *ObjPtrTy =
|
||||
T->getAs<ObjCObjectPointerType>()) {
|
||||
ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
|
||||
@ -625,8 +624,9 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
|
||||
PropertyId, AtLoc,
|
||||
LParenLoc, T, TInfo);
|
||||
|
||||
bool isClassProperty = (AttributesAsWritten & ObjCDeclSpec::DQ_PR_class) ||
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_class);
|
||||
bool isClassProperty =
|
||||
(AttributesAsWritten & ObjCPropertyAttribute::kind_class) ||
|
||||
(Attributes & ObjCPropertyAttribute::kind_class);
|
||||
// Class property and instance property can have the same name.
|
||||
if (ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
|
||||
DC, PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty))) {
|
||||
@ -654,68 +654,68 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
|
||||
PDecl->setPropertyAttributesAsWritten(
|
||||
makePropertyAttributesAsWritten(AttributesAsWritten));
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_readonly)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_getter)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_getter)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_setter)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_setter)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter);
|
||||
|
||||
if (isReadWrite)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_retain)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_retain)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_strong)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_strong)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_strong);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_weak)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_weak)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_weak);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_copy)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_copy)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_unsafe_unretained)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_unsafe_unretained);
|
||||
|
||||
if (isAssign)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
|
||||
|
||||
// In the semantic attributes, one of nonatomic or atomic is always set.
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic);
|
||||
else
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic);
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_atomic);
|
||||
|
||||
// 'unsafe_unretained' is alias for 'assign'.
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_unsafe_unretained)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
|
||||
if (isAssign)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_unsafe_unretained);
|
||||
|
||||
if (MethodImplKind == tok::objc_required)
|
||||
PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
|
||||
else if (MethodImplKind == tok::objc_optional)
|
||||
PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_nullability)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nullability);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_nullability)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_nullability);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_null_resettable)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_null_resettable);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_null_resettable)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_null_resettable);
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_class)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_class);
|
||||
if (Attributes & ObjCPropertyAttribute::kind_class)
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_class);
|
||||
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_direct) ||
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_direct) ||
|
||||
CDecl->hasAttr<ObjCDirectMembersAttr>()) {
|
||||
if (isa<ObjCProtocolDecl>(CDecl)) {
|
||||
Diag(PDecl->getLocation(), diag::err_objc_direct_on_protocol) << true;
|
||||
} else if (getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
|
||||
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_direct);
|
||||
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_direct);
|
||||
} else {
|
||||
Diag(PDecl->getLocation(), diag::warn_objc_direct_property_ignored)
|
||||
<< PDecl->getDeclName();
|
||||
@ -781,10 +781,9 @@ static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc,
|
||||
|
||||
case Qualifiers::OCL_ExplicitNone:
|
||||
S.Diag(ivar->getLocation(), diag::err_arc_assign_property_ownership)
|
||||
<< property->getDeclName()
|
||||
<< ivar->getDeclName()
|
||||
<< ((property->getPropertyAttributesAsWritten()
|
||||
& ObjCPropertyDecl::OBJC_PR_assign) != 0);
|
||||
<< property->getDeclName() << ivar->getDeclName()
|
||||
<< ((property->getPropertyAttributesAsWritten() &
|
||||
ObjCPropertyAttribute::kind_assign) != 0);
|
||||
break;
|
||||
|
||||
case Qualifiers::OCL_Autoreleasing:
|
||||
@ -815,21 +814,20 @@ static void setImpliedPropertyAttributeForReadOnlyProperty(
|
||||
|
||||
if (!ivar) {
|
||||
// if no backing ivar, make property 'strong'.
|
||||
property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
|
||||
property->setPropertyAttributes(ObjCPropertyAttribute::kind_strong);
|
||||
return;
|
||||
}
|
||||
// property assumes owenership of backing ivar.
|
||||
QualType ivarType = ivar->getType();
|
||||
Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime();
|
||||
if (ivarLifetime == Qualifiers::OCL_Strong)
|
||||
property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
|
||||
property->setPropertyAttributes(ObjCPropertyAttribute::kind_strong);
|
||||
else if (ivarLifetime == Qualifiers::OCL_Weak)
|
||||
property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
|
||||
property->setPropertyAttributes(ObjCPropertyAttribute::kind_weak);
|
||||
}
|
||||
|
||||
static bool
|
||||
isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2,
|
||||
ObjCPropertyDecl::PropertyAttributeKind Kind) {
|
||||
static bool isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2,
|
||||
ObjCPropertyAttribute::Kind Kind) {
|
||||
return (Attr1 & Kind) != (Attr2 & Kind);
|
||||
}
|
||||
|
||||
@ -912,30 +910,31 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
|
||||
};
|
||||
// The ownership might be incompatible unless the property has no explicit
|
||||
// ownership.
|
||||
bool HasOwnership = (Attr & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_strong |
|
||||
ObjCPropertyDecl::OBJC_PR_copy |
|
||||
ObjCPropertyDecl::OBJC_PR_assign |
|
||||
ObjCPropertyDecl::OBJC_PR_unsafe_unretained |
|
||||
ObjCPropertyDecl::OBJC_PR_weak)) != 0;
|
||||
bool HasOwnership =
|
||||
(Attr & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong |
|
||||
ObjCPropertyAttribute::kind_copy |
|
||||
ObjCPropertyAttribute::kind_assign |
|
||||
ObjCPropertyAttribute::kind_unsafe_unretained |
|
||||
ObjCPropertyAttribute::kind_weak)) != 0;
|
||||
if (HasOwnership &&
|
||||
isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
|
||||
ObjCPropertyDecl::OBJC_PR_copy)) {
|
||||
Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_copy, "copy");
|
||||
ObjCPropertyAttribute::kind_copy)) {
|
||||
Diag(OriginalAttributes & ObjCPropertyAttribute::kind_copy, "copy");
|
||||
continue;
|
||||
}
|
||||
if (HasOwnership && areIncompatiblePropertyAttributes(
|
||||
OriginalAttributes, Attr,
|
||||
ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_strong)) {
|
||||
Diag(OriginalAttributes & (ObjCPropertyDecl::OBJC_PR_retain |
|
||||
ObjCPropertyDecl::OBJC_PR_strong),
|
||||
ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong)) {
|
||||
Diag(OriginalAttributes & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong),
|
||||
"retain (or strong)");
|
||||
continue;
|
||||
}
|
||||
if (isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
|
||||
ObjCPropertyDecl::OBJC_PR_atomic)) {
|
||||
Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_atomic, "atomic");
|
||||
ObjCPropertyAttribute::kind_atomic)) {
|
||||
Diag(OriginalAttributes & ObjCPropertyAttribute::kind_atomic, "atomic");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1126,8 +1125,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
||||
return nullptr;
|
||||
}
|
||||
unsigned PIkind = property->getPropertyAttributesAsWritten();
|
||||
if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic |
|
||||
ObjCPropertyDecl::OBJC_PR_nonatomic) ) == 0) {
|
||||
if ((PIkind & (ObjCPropertyAttribute::kind_atomic |
|
||||
ObjCPropertyAttribute::kind_nonatomic)) == 0) {
|
||||
if (AtLoc.isValid())
|
||||
Diag(AtLoc, diag::warn_implicit_atomic_property);
|
||||
else
|
||||
@ -1143,10 +1142,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (Synthesize&&
|
||||
(PIkind & ObjCPropertyDecl::OBJC_PR_readonly) &&
|
||||
property->hasAttr<IBOutletAttr>() &&
|
||||
!AtLoc.isValid()) {
|
||||
if (Synthesize && (PIkind & ObjCPropertyAttribute::kind_readonly) &&
|
||||
property->hasAttr<IBOutletAttr>() && !AtLoc.isValid()) {
|
||||
bool ReadWriteProperty = false;
|
||||
// Search into the class extensions and see if 'readonly property is
|
||||
// redeclared 'readwrite', then no warning is to be issued.
|
||||
@ -1155,7 +1152,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
||||
if (!R.empty())
|
||||
if (ObjCPropertyDecl *ExtProp = dyn_cast<ObjCPropertyDecl>(R[0])) {
|
||||
PIkind = ExtProp->getPropertyAttributesAsWritten();
|
||||
if (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite) {
|
||||
if (PIkind & ObjCPropertyAttribute::kind_readwrite) {
|
||||
ReadWriteProperty = true;
|
||||
break;
|
||||
}
|
||||
@ -1232,16 +1229,15 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
||||
|
||||
if (getLangOpts().ObjCAutoRefCount &&
|
||||
(property->getPropertyAttributesAsWritten() &
|
||||
ObjCPropertyDecl::OBJC_PR_readonly) &&
|
||||
ObjCPropertyAttribute::kind_readonly) &&
|
||||
PropertyIvarType->isObjCRetainableType()) {
|
||||
setImpliedPropertyAttributeForReadOnlyProperty(property, Ivar);
|
||||
}
|
||||
|
||||
ObjCPropertyDecl::PropertyAttributeKind kind
|
||||
= property->getPropertyAttributes();
|
||||
ObjCPropertyAttribute::Kind kind = property->getPropertyAttributes();
|
||||
|
||||
bool isARCWeak = false;
|
||||
if (kind & ObjCPropertyDecl::OBJC_PR_weak) {
|
||||
if (kind & ObjCPropertyAttribute::kind_weak) {
|
||||
// Add GC __weak to the ivar type if the property is weak.
|
||||
if (getLangOpts().getGC() != LangOptions::NonGC) {
|
||||
assert(!getLangOpts().ObjCAutoRefCount);
|
||||
@ -1312,7 +1308,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
||||
// It's an error if we have to do this and the user didn't
|
||||
// explicitly write an ownership attribute on the property.
|
||||
if (!hasWrittenStorageAttribute(property, QueryKind) &&
|
||||
!(kind & ObjCPropertyDecl::OBJC_PR_strong)) {
|
||||
!(kind & ObjCPropertyAttribute::kind_strong)) {
|
||||
Diag(PropertyDiagLoc,
|
||||
diag::err_arc_objc_property_default_assign_on_object);
|
||||
Diag(property->getLocation(), diag::note_property_declare);
|
||||
@ -1551,7 +1547,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
||||
ExprResult Res = BuildBinOp(S, PropertyDiagLoc,
|
||||
BO_Assign, lhs, rhs);
|
||||
if (property->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_atomic) {
|
||||
ObjCPropertyAttribute::kind_atomic) {
|
||||
Expr *callExpr = Res.getAs<Expr>();
|
||||
if (const CXXOperatorCallExpr *CXXCE =
|
||||
dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
|
||||
@ -1651,10 +1647,8 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
|
||||
ObjCPropertyDecl *SuperProperty,
|
||||
const IdentifierInfo *inheritedName,
|
||||
bool OverridingProtocolProperty) {
|
||||
ObjCPropertyDecl::PropertyAttributeKind CAttr =
|
||||
Property->getPropertyAttributes();
|
||||
ObjCPropertyDecl::PropertyAttributeKind SAttr =
|
||||
SuperProperty->getPropertyAttributes();
|
||||
ObjCPropertyAttribute::Kind CAttr = Property->getPropertyAttributes();
|
||||
ObjCPropertyAttribute::Kind SAttr = SuperProperty->getPropertyAttributes();
|
||||
|
||||
// We allow readonly properties without an explicit ownership
|
||||
// (assign/unsafe_unretained/weak/retain/strong/copy) in super class
|
||||
@ -1663,21 +1657,19 @@ Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
|
||||
!getOwnershipRule(SAttr) && getOwnershipRule(CAttr))
|
||||
;
|
||||
else {
|
||||
if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
|
||||
&& (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
|
||||
if ((CAttr & ObjCPropertyAttribute::kind_readonly) &&
|
||||
(SAttr & ObjCPropertyAttribute::kind_readwrite))
|
||||
Diag(Property->getLocation(), diag::warn_readonly_property)
|
||||
<< Property->getDeclName() << inheritedName;
|
||||
if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
|
||||
!= (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
|
||||
if ((CAttr & ObjCPropertyAttribute::kind_copy) !=
|
||||
(SAttr & ObjCPropertyAttribute::kind_copy))
|
||||
Diag(Property->getLocation(), diag::warn_property_attribute)
|
||||
<< Property->getDeclName() << "copy" << inheritedName;
|
||||
else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){
|
||||
unsigned CAttrRetain =
|
||||
(CAttr &
|
||||
(ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
|
||||
unsigned SAttrRetain =
|
||||
(SAttr &
|
||||
(ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong));
|
||||
else if (!(SAttr & ObjCPropertyAttribute::kind_readonly)) {
|
||||
unsigned CAttrRetain = (CAttr & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong));
|
||||
unsigned SAttrRetain = (SAttr & (ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong));
|
||||
bool CStrong = (CAttrRetain != 0);
|
||||
bool SStrong = (SAttrRetain != 0);
|
||||
if (CStrong != SStrong)
|
||||
@ -1885,7 +1877,7 @@ static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl,
|
||||
ObjCPropertyDecl *Prop) {
|
||||
bool SuperClassImplementsGetter = false;
|
||||
bool SuperClassImplementsSetter = false;
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_readonly)
|
||||
SuperClassImplementsSetter = true;
|
||||
|
||||
while (IDecl->getSuperClass()) {
|
||||
@ -1928,7 +1920,7 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl,
|
||||
continue;
|
||||
ObjCMethodDecl *ImpMethod = IMPDecl->getInstanceMethod(Prop->getGetterName());
|
||||
if (ImpMethod && !ImpMethod->getBody()) {
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_readonly)
|
||||
continue;
|
||||
ImpMethod = IMPDecl->getInstanceMethod(Prop->getSetterName());
|
||||
if (ImpMethod && !ImpMethod->getBody())
|
||||
@ -1965,16 +1957,16 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl,
|
||||
}
|
||||
// If property to be implemented in the super class, ignore.
|
||||
if (PropInSuperClass) {
|
||||
if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) &&
|
||||
if ((Prop->getPropertyAttributes() &
|
||||
ObjCPropertyAttribute::kind_readwrite) &&
|
||||
(PropInSuperClass->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_readonly) &&
|
||||
ObjCPropertyAttribute::kind_readonly) &&
|
||||
!IMPDecl->getInstanceMethod(Prop->getSetterName()) &&
|
||||
!IDecl->HasUserDeclaredSetterMethod(Prop)) {
|
||||
Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
|
||||
<< Prop->getIdentifier();
|
||||
Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)
|
||||
<< Prop->getIdentifier();
|
||||
Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
|
||||
@ -2161,12 +2153,11 @@ void Sema::diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
|
||||
const auto *property = propertyImpl->getPropertyDecl();
|
||||
// Warn about null_resettable properties with synthesized setters,
|
||||
// because the setter won't properly handle nil.
|
||||
if (propertyImpl->getPropertyImplementation()
|
||||
== ObjCPropertyImplDecl::Synthesize &&
|
||||
if (propertyImpl->getPropertyImplementation() ==
|
||||
ObjCPropertyImplDecl::Synthesize &&
|
||||
(property->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_null_resettable) &&
|
||||
property->getGetterMethodDecl() &&
|
||||
property->getSetterMethodDecl()) {
|
||||
ObjCPropertyAttribute::kind_null_resettable) &&
|
||||
property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
|
||||
auto *getterImpl = propertyImpl->getGetterMethodDecl();
|
||||
auto *setterImpl = propertyImpl->getSetterMethodDecl();
|
||||
if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
|
||||
@ -2204,8 +2195,8 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
|
||||
unsigned Attributes = Property->getPropertyAttributes();
|
||||
unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();
|
||||
|
||||
if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) &&
|
||||
!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) {
|
||||
if (!(AttributesAsWritten & ObjCPropertyAttribute::kind_atomic) &&
|
||||
!(AttributesAsWritten & ObjCPropertyAttribute::kind_nonatomic)) {
|
||||
GetterMethod = Property->isClassProperty() ?
|
||||
IMPDecl->getClassMethod(Property->getGetterName()) :
|
||||
IMPDecl->getInstanceMethod(Property->getGetterName());
|
||||
@ -2231,8 +2222,8 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
|
||||
}
|
||||
|
||||
// We only care about readwrite atomic property.
|
||||
if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
|
||||
!(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_nonatomic) ||
|
||||
!(Attributes & ObjCPropertyAttribute::kind_readwrite))
|
||||
continue;
|
||||
if (const ObjCPropertyImplDecl *PIDecl = IMPDecl->FindPropertyImplDecl(
|
||||
Property->getIdentifier(), Property->getQueryKind())) {
|
||||
@ -2253,7 +2244,7 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
|
||||
<< (SetterMethod != nullptr);
|
||||
// fixit stuff.
|
||||
if (Property->getLParenLoc().isValid() &&
|
||||
!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic)) {
|
||||
!(AttributesAsWritten & ObjCPropertyAttribute::kind_atomic)) {
|
||||
// @property () ... case.
|
||||
SourceLocation AfterLParen =
|
||||
getLocForEndOfToken(Property->getLParenLoc());
|
||||
@ -2269,8 +2260,7 @@ Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
|
||||
Diag(Property->getLocation(),
|
||||
diag::note_atomic_property_fixup_suggest)
|
||||
<< FixItHint::CreateInsertion(startLoc, "(nonatomic) ");
|
||||
}
|
||||
else
|
||||
} else
|
||||
Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
|
||||
Diag(Property->getLocation(), diag::note_property_declare);
|
||||
}
|
||||
@ -2498,7 +2488,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) {
|
||||
|
||||
// If the property is null_resettable, the getter returns nonnull.
|
||||
if (property->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_null_resettable) {
|
||||
ObjCPropertyAttribute::kind_null_resettable) {
|
||||
QualType modifiedTy = resultTy;
|
||||
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
|
||||
if (*nullability == NullabilityKind::Unspecified)
|
||||
@ -2577,7 +2567,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property) {
|
||||
// If the property is null_resettable, the setter accepts a
|
||||
// nullable value.
|
||||
if (property->getPropertyAttributes() &
|
||||
ObjCPropertyDecl::OBJC_PR_null_resettable) {
|
||||
ObjCPropertyAttribute::kind_null_resettable) {
|
||||
QualType modifiedTy = paramTy;
|
||||
if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
|
||||
if (*nullability == NullabilityKind::Unspecified)
|
||||
@ -2665,8 +2655,8 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
|
||||
if (!PDecl || PDecl->isInvalidDecl())
|
||||
return;
|
||||
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_readwrite))
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_readonly) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_readwrite))
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "readonly" << "readwrite";
|
||||
|
||||
@ -2674,104 +2664,109 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
|
||||
QualType PropertyTy = PropertyDecl->getType();
|
||||
|
||||
// Check for copy or retain on non-object types.
|
||||
if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
|
||||
ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) &&
|
||||
if ((Attributes &
|
||||
(ObjCPropertyAttribute::kind_weak | ObjCPropertyAttribute::kind_copy |
|
||||
ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong)) &&
|
||||
!PropertyTy->isObjCRetainableType() &&
|
||||
!PropertyDecl->hasAttr<ObjCNSObjectAttr>()) {
|
||||
Diag(Loc, diag::err_objc_property_requires_object)
|
||||
<< (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" :
|
||||
Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)");
|
||||
Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
|
||||
ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong);
|
||||
<< (Attributes & ObjCPropertyAttribute::kind_weak
|
||||
? "weak"
|
||||
: Attributes & ObjCPropertyAttribute::kind_copy
|
||||
? "copy"
|
||||
: "retain (or strong)");
|
||||
Attributes &=
|
||||
~(ObjCPropertyAttribute::kind_weak | ObjCPropertyAttribute::kind_copy |
|
||||
ObjCPropertyAttribute::kind_retain |
|
||||
ObjCPropertyAttribute::kind_strong);
|
||||
PropertyDecl->setInvalidDecl();
|
||||
}
|
||||
|
||||
// Check for assign on object types.
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_assign) &&
|
||||
!(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) &&
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_assign) &&
|
||||
!(Attributes & ObjCPropertyAttribute::kind_unsafe_unretained) &&
|
||||
PropertyTy->isObjCRetainableType() &&
|
||||
!PropertyTy->isObjCARCImplicitlyUnretainedType()) {
|
||||
Diag(Loc, diag::warn_objc_property_assign_on_object);
|
||||
}
|
||||
|
||||
// Check for more than one of { assign, copy, retain }.
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_assign) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_copy) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "assign" << "copy";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_copy;
|
||||
}
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_retain) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "assign" << "retain";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_retain;
|
||||
}
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_strong) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "assign" << "strong";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_strong;
|
||||
}
|
||||
if (getLangOpts().ObjCAutoRefCount &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_weak)) {
|
||||
(Attributes & ObjCPropertyAttribute::kind_weak)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "assign" << "weak";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_weak;
|
||||
}
|
||||
if (PropertyDecl->hasAttr<IBOutletCollectionAttr>())
|
||||
Diag(Loc, diag::warn_iboutletcollection_property_assign);
|
||||
} else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) {
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
|
||||
} else if (Attributes & ObjCPropertyAttribute::kind_unsafe_unretained) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_copy) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "unsafe_unretained" << "copy";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_copy;
|
||||
}
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_retain) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "unsafe_unretained" << "retain";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_retain;
|
||||
}
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_strong) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "unsafe_unretained" << "strong";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_strong;
|
||||
}
|
||||
if (getLangOpts().ObjCAutoRefCount &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_weak)) {
|
||||
(Attributes & ObjCPropertyAttribute::kind_weak)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "unsafe_unretained" << "weak";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_weak;
|
||||
}
|
||||
} else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
|
||||
} else if (Attributes & ObjCPropertyAttribute::kind_copy) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_retain) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "copy" << "retain";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_retain;
|
||||
}
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_strong) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "copy" << "strong";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_strong;
|
||||
}
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_weak) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "copy" << "weak";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_weak;
|
||||
}
|
||||
}
|
||||
else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_weak)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "retain" << "weak";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
|
||||
}
|
||||
else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_weak)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "strong" << "weak";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
|
||||
} else if ((Attributes & ObjCPropertyAttribute::kind_retain) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_weak)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "retain"
|
||||
<< "weak";
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_retain;
|
||||
} else if ((Attributes & ObjCPropertyAttribute::kind_strong) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_weak)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "strong"
|
||||
<< "weak";
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_weak;
|
||||
}
|
||||
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_weak) {
|
||||
// 'weak' and 'nonnull' are mutually exclusive.
|
||||
if (auto nullability = PropertyTy->getNullability(Context)) {
|
||||
if (*nullability == NullabilityKind::NonNull)
|
||||
@ -2780,25 +2775,24 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
|
||||
}
|
||||
}
|
||||
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_atomic) &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_nonatomic)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "atomic" << "nonatomic";
|
||||
Attributes &= ~ObjCDeclSpec::DQ_PR_atomic;
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_atomic) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_nonatomic)) {
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "atomic"
|
||||
<< "nonatomic";
|
||||
Attributes &= ~ObjCPropertyAttribute::kind_atomic;
|
||||
}
|
||||
|
||||
// Warn if user supplied no assignment attribute, property is
|
||||
// readwrite, and this is an object type.
|
||||
if (!getOwnershipRule(Attributes) && PropertyTy->isObjCRetainableType()) {
|
||||
if (Attributes & ObjCDeclSpec::DQ_PR_readonly) {
|
||||
if (Attributes & ObjCPropertyAttribute::kind_readonly) {
|
||||
// do nothing
|
||||
} else if (getLangOpts().ObjCAutoRefCount) {
|
||||
// With arc, @property definitions should default to strong when
|
||||
// not specified.
|
||||
PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
|
||||
PropertyDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_strong);
|
||||
} else if (PropertyTy->isObjCObjectPointerType()) {
|
||||
bool isAnyClassTy =
|
||||
(PropertyTy->isObjCClassType() ||
|
||||
bool isAnyClassTy = (PropertyTy->isObjCClassType() ||
|
||||
PropertyTy->isObjCQualifiedClassType());
|
||||
// In non-gc, non-arc mode, 'Class' is treated as a 'void *' no need to
|
||||
// issue any warning.
|
||||
@ -2823,18 +2817,18 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
|
||||
// (please trim this list while you are at it).
|
||||
}
|
||||
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_copy)
|
||||
&&!(Attributes & ObjCDeclSpec::DQ_PR_readonly)
|
||||
&& getLangOpts().getGC() == LangOptions::GCOnly
|
||||
&& PropertyTy->isBlockPointerType())
|
||||
if (!(Attributes & ObjCPropertyAttribute::kind_copy) &&
|
||||
!(Attributes & ObjCPropertyAttribute::kind_readonly) &&
|
||||
getLangOpts().getGC() == LangOptions::GCOnly &&
|
||||
PropertyTy->isBlockPointerType())
|
||||
Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
|
||||
else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
|
||||
!(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
|
||||
!(Attributes & ObjCDeclSpec::DQ_PR_strong) &&
|
||||
else if ((Attributes & ObjCPropertyAttribute::kind_retain) &&
|
||||
!(Attributes & ObjCPropertyAttribute::kind_readonly) &&
|
||||
!(Attributes & ObjCPropertyAttribute::kind_strong) &&
|
||||
PropertyTy->isBlockPointerType())
|
||||
Diag(Loc, diag::warn_objc_property_retain_of_block);
|
||||
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
|
||||
(Attributes & ObjCDeclSpec::DQ_PR_setter))
|
||||
if ((Attributes & ObjCPropertyAttribute::kind_readonly) &&
|
||||
(Attributes & ObjCPropertyAttribute::kind_setter))
|
||||
Diag(Loc, diag::warn_objc_readonly_property_has_setter);
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ bool ObjCPropertyOpBuilder::isWeakProperty() const {
|
||||
QualType T;
|
||||
if (RefExpr->isExplicitProperty()) {
|
||||
const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
|
||||
if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak)
|
||||
return true;
|
||||
|
||||
T = Prop->getType();
|
||||
|
@ -1280,10 +1280,9 @@ void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
|
||||
QualType T = Record.readType();
|
||||
TypeSourceInfo *TSI = readTypeSourceInfo();
|
||||
D->setType(T, TSI);
|
||||
D->setPropertyAttributes(
|
||||
(ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
|
||||
D->setPropertyAttributes((ObjCPropertyAttribute::Kind)Record.readInt());
|
||||
D->setPropertyAttributesAsWritten(
|
||||
(ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
|
||||
(ObjCPropertyAttribute::Kind)Record.readInt());
|
||||
D->setPropertyImplementation(
|
||||
(ObjCPropertyDecl::PropertyControl)Record.readInt());
|
||||
DeclarationName GetterName = Record.readDeclarationName();
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "CursorVisitor.h"
|
||||
#include "clang-c/FatalErrorHandler.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/DeclObjCCommon.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/OpenMPClause.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
@ -8146,11 +8147,10 @@ unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
|
||||
|
||||
unsigned Result = CXObjCPropertyAttr_noattr;
|
||||
const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
|
||||
ObjCPropertyDecl::PropertyAttributeKind Attr =
|
||||
PD->getPropertyAttributesAsWritten();
|
||||
ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
|
||||
|
||||
#define SET_CXOBJCPROP_ATTR(A) \
|
||||
if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
|
||||
if (Attr & ObjCPropertyAttribute::kind_##A) \
|
||||
Result |= CXObjCPropertyAttr_##A
|
||||
SET_CXOBJCPROP_ATTR(readonly);
|
||||
SET_CXOBJCPROP_ATTR(getter);
|
||||
|
@ -7590,7 +7590,7 @@ bool TypeSystemClang::AddObjCClassProperty(
|
||||
setter_sel = clang_ast.Selectors.getSelector(1, &setter_ident);
|
||||
}
|
||||
property_decl->setSetterName(setter_sel);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_setter);
|
||||
|
||||
if (property_getter_name != nullptr) {
|
||||
clang::IdentifierInfo *getter_ident =
|
||||
@ -7601,33 +7601,34 @@ bool TypeSystemClang::AddObjCClassProperty(
|
||||
getter_sel = clang_ast.Selectors.getSelector(0, &getter_ident);
|
||||
}
|
||||
property_decl->setGetterName(getter_sel);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_getter);
|
||||
|
||||
if (ivar_decl)
|
||||
property_decl->setPropertyIvarDecl(ivar_decl);
|
||||
|
||||
if (property_attributes & DW_APPLE_PROPERTY_readonly)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);
|
||||
if (property_attributes & DW_APPLE_PROPERTY_readwrite)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_readwrite);
|
||||
if (property_attributes & DW_APPLE_PROPERTY_assign)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_assign);
|
||||
if (property_attributes & DW_APPLE_PROPERTY_retain)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_retain);
|
||||
if (property_attributes & DW_APPLE_PROPERTY_copy)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_copy);
|
||||
if (property_attributes & DW_APPLE_PROPERTY_nonatomic)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
|
||||
if (property_attributes & ObjCPropertyDecl::OBJC_PR_nullability)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nullability);
|
||||
if (property_attributes & ObjCPropertyDecl::OBJC_PR_null_resettable)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_nonatomic);
|
||||
if (property_attributes & ObjCPropertyAttribute::kind_nullability)
|
||||
property_decl->setPropertyAttributes(
|
||||
ObjCPropertyDecl::OBJC_PR_null_resettable);
|
||||
if (property_attributes & ObjCPropertyDecl::OBJC_PR_class)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_class);
|
||||
ObjCPropertyAttribute::kind_nullability);
|
||||
if (property_attributes & ObjCPropertyAttribute::kind_null_resettable)
|
||||
property_decl->setPropertyAttributes(
|
||||
ObjCPropertyAttribute::kind_null_resettable);
|
||||
if (property_attributes & ObjCPropertyAttribute::kind_class)
|
||||
property_decl->setPropertyAttributes(ObjCPropertyAttribute::kind_class);
|
||||
|
||||
const bool isInstance =
|
||||
(property_attributes & ObjCPropertyDecl::OBJC_PR_class) == 0;
|
||||
(property_attributes & ObjCPropertyAttribute::kind_class) == 0;
|
||||
|
||||
clang::ObjCMethodDecl *getter = nullptr;
|
||||
if (!getter_sel.isNull())
|
||||
|
@ -898,7 +898,8 @@ HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64)
|
||||
HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86)
|
||||
|
||||
// Apple Objective-C Property Attributes.
|
||||
// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
|
||||
// Keep this list in sync with clang's DeclObjCCommon.h
|
||||
// ObjCPropertyAttribute::Kind!
|
||||
HANDLE_DW_APPLE_PROPERTY(0x01, readonly)
|
||||
HANDLE_DW_APPLE_PROPERTY(0x02, getter)
|
||||
HANDLE_DW_APPLE_PROPERTY(0x04, assign)
|
||||
|
@ -357,7 +357,8 @@ enum Constants {
|
||||
};
|
||||
|
||||
/// Constants for the DW_APPLE_PROPERTY_attributes attribute.
|
||||
/// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
|
||||
/// Keep this list in sync with clang's DeclObjCCommon.h
|
||||
/// ObjCPropertyAttribute::Kind!
|
||||
enum ApplePropertyAttributes {
|
||||
#define HANDLE_DW_APPLE_PROPERTY(ID, NAME) DW_APPLE_PROPERTY_##NAME = ID,
|
||||
#include "llvm/BinaryFormat/Dwarf.def"
|
||||
|
Loading…
x
Reference in New Issue
Block a user