[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:
Puyan Lotfi 2020-04-23 02:20:56 -04:00
parent b53fd70b9e
commit 9721fbf85b
27 changed files with 588 additions and 565 deletions

View File

@ -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;
}

View 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

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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 ? "" : ", ")

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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

View File

@ -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))

View File

@ -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);

View File

@ -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)";

View File

@ -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)";

View File

@ -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);

View File

@ -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;
}

View File

@ -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"));

View File

@ -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() &&

View File

@ -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);
}

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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())

View File

@ -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)

View File

@ -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"