зеркало из https://github.com/microsoft/clang-1.git
Patch for objc2's property ASTs, as well as pretty-priting the ASTs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43778 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2ebc89f6cb
Коммит
82a5fe3d1c
|
@ -36,6 +36,7 @@ static unsigned nIvarDecls = 0;
|
|||
static unsigned nObjcImplementationDecls = 0;
|
||||
static unsigned nObjcCategoryImpl = 0;
|
||||
static unsigned nObjcCompatibleAlias = 0;
|
||||
static unsigned nObjcPropertyDecl = 0;
|
||||
|
||||
static bool StatSwitch = false;
|
||||
|
||||
|
@ -146,6 +147,10 @@ void Decl::PrintStats() {
|
|||
nObjcCompatibleAlias, (int)sizeof(ObjcCompatibleAliasDecl),
|
||||
int(nObjcCompatibleAlias*sizeof(ObjcCompatibleAliasDecl)));
|
||||
|
||||
fprintf(stderr, " %d property decls, %d each (%d bytes)\n",
|
||||
nObjcPropertyDecl, (int)sizeof(ObjcPropertyDecl),
|
||||
int(nObjcPropertyDecl*sizeof(ObjcPropertyDecl)));
|
||||
|
||||
fprintf(stderr, "Total bytes = %d\n",
|
||||
int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+
|
||||
nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+
|
||||
|
@ -215,6 +220,9 @@ void Decl::addDeclKind(const Kind k) {
|
|||
case CompatibleAlias:
|
||||
nObjcCompatibleAlias++;
|
||||
break;
|
||||
case PropertyDecl:
|
||||
nObjcPropertyDecl++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,10 +103,78 @@ static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) {
|
|||
fprintf(stderr, "\t%s %s;\n", Ivars[i]->getType().getAsString().c_str(),
|
||||
Ivars[i]->getName());
|
||||
}
|
||||
fprintf(stderr, "}\n@end\n");
|
||||
fprintf(stderr, "}\n");
|
||||
}
|
||||
else
|
||||
fprintf(stderr,"@end\n");
|
||||
|
||||
int NumProperties = OID->getNumPropertyDecl();
|
||||
if (NumProperties > 0) {
|
||||
for (int i = 0; i < NumProperties; i++) {
|
||||
ObjcPropertyDecl *PDecl = OID->getPropertyDecl()[i];
|
||||
fprintf(stderr, "@property");
|
||||
if (PDecl->getPropertyAttributes() != ObjcPropertyDecl::OBJC_PR_noattr) {
|
||||
bool first = true;
|
||||
fprintf(stderr, " (");
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_readonly)
|
||||
{
|
||||
fprintf(stderr, "%creadonly", first ? ' ' : ',');
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_getter)
|
||||
{
|
||||
fprintf(stderr, "%cgetter = %s", first ? ' ' : ','
|
||||
, PDecl->getGetterName()->getName());
|
||||
first = false;
|
||||
}
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_setter)
|
||||
{
|
||||
fprintf(stderr, "%csetter = %s:", first ? ' ' : ','
|
||||
, PDecl->getSetterName()->getName());
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_assign)
|
||||
{
|
||||
fprintf(stderr, "%cassign", first ? ' ' : ',');
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_readwrite)
|
||||
{
|
||||
fprintf(stderr, "%creadwrite", first ? ' ' : ',');
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_retain)
|
||||
{
|
||||
fprintf(stderr, "%cretain", first ? ' ' : ',');
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_copy)
|
||||
{
|
||||
fprintf(stderr, "%ccopy", first ? ' ' : ',');
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_nonatomic)
|
||||
{
|
||||
fprintf(stderr, "%cnonatomic", first ? ' ' : ',');
|
||||
first = false;
|
||||
}
|
||||
fprintf(stderr, " )");
|
||||
}
|
||||
ObjcIvarDecl **IDecl = PDecl->getPropertyDecls();
|
||||
fprintf(stderr, " %s %s", IDecl[0]->getType().getAsString().c_str(),
|
||||
IDecl[0]->getName());
|
||||
|
||||
for (int j = 1; j < PDecl->getNumPropertyDecls(); j++) {
|
||||
fprintf(stderr, ", %s", IDecl[j]->getName());
|
||||
}
|
||||
fprintf(stderr, ";\n");
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"@end\n");
|
||||
// FIXME: implement the rest...
|
||||
}
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration(
|
|||
void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
||||
tok::ObjCKeywordKind contextKey) {
|
||||
llvm::SmallVector<DeclTy*, 32> allMethods;
|
||||
llvm::SmallVector<DeclTy*, 16> allProperties;
|
||||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
|
||||
SourceLocation AtEndLoc;
|
||||
|
||||
|
@ -247,7 +248,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
|||
if (contextKey != tok::objc_protocol)
|
||||
Diag(AtLoc, diag::err_objc_protocol_optional);
|
||||
} else if (ocKind == tok::objc_property) {
|
||||
ParseObjCPropertyDecl(interfaceDecl);
|
||||
allProperties.push_back(ParseObjCPropertyDecl(interfaceDecl, AtLoc));
|
||||
continue;
|
||||
} else {
|
||||
Diag(Tok, diag::err_objc_illegal_interface_qual);
|
||||
|
@ -277,7 +278,9 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
|||
/// This action is executed even if we don't have any methods (so the @end
|
||||
/// can be recorded properly).
|
||||
Actions.ActOnAddMethodsToObjcDecl(CurScope, interfaceDecl, &allMethods[0],
|
||||
allMethods.size(), AtEndLoc);
|
||||
allMethods.size(),
|
||||
&allProperties[0], allProperties.size(),
|
||||
AtEndLoc);
|
||||
}
|
||||
|
||||
/// Parse property attribute declarations.
|
||||
|
@ -296,7 +299,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
|
|||
/// copy
|
||||
/// nonatomic
|
||||
///
|
||||
void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) {
|
||||
void Parser::ParseObjCPropertyAttribute (ObjcDeclSpec &DS) {
|
||||
SourceLocation loc = ConsumeParen(); // consume '('
|
||||
while (isObjCPropertyAttribute()) {
|
||||
const IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
|
@ -309,6 +312,8 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) {
|
|||
loc = ConsumeToken();
|
||||
if (Tok.is(tok::identifier)) {
|
||||
if (II == ObjcPropertyAttrs[objc_setter]) {
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_setter);
|
||||
DS.setSetterName(Tok.getIdentifierInfo());
|
||||
loc = ConsumeToken(); // consume method name
|
||||
if (Tok.isNot(tok::colon)) {
|
||||
Diag(loc, diag::err_expected_colon);
|
||||
|
@ -316,6 +321,10 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_getter);
|
||||
DS.setGetterName(Tok.getIdentifierInfo());
|
||||
}
|
||||
}
|
||||
else {
|
||||
Diag(loc, diag::err_expected_ident);
|
||||
|
@ -329,6 +338,20 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (II == ObjcPropertyAttrs[objc_readonly])
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_readonly);
|
||||
else if (II == ObjcPropertyAttrs[objc_assign])
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_assign);
|
||||
else if (II == ObjcPropertyAttrs[objc_readwrite])
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_readwrite);
|
||||
else if (II == ObjcPropertyAttrs[objc_retain])
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_retain);
|
||||
else if (II == ObjcPropertyAttrs[objc_copy])
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_copy);
|
||||
else if (II == ObjcPropertyAttrs[objc_nonatomic])
|
||||
DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_nonatomic);
|
||||
|
||||
ConsumeToken(); // consume last attribute token
|
||||
if (Tok.is(tok::comma)) {
|
||||
loc = ConsumeToken();
|
||||
|
@ -352,17 +375,19 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) {
|
|||
///
|
||||
/// @property property-attr-decl[opt] property-component-decl ';'
|
||||
///
|
||||
void Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl) {
|
||||
Parser::DeclTy *Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl,
|
||||
SourceLocation AtLoc) {
|
||||
assert(Tok.isObjCAtKeyword(tok::objc_property) &&
|
||||
"ParseObjCPropertyDecl(): Expected @property");
|
||||
ObjcDeclSpec DS;
|
||||
ConsumeToken(); // the "property" identifier
|
||||
// Parse property attribute list, if any.
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
// property has attribute list.
|
||||
ParseObjCPropertyAttribute(0/*FIXME*/);
|
||||
ParseObjCPropertyAttribute(DS);
|
||||
}
|
||||
// Parse declaration portion of @property.
|
||||
llvm::SmallVector<DeclTy*, 32> PropertyDecls;
|
||||
llvm::SmallVector<DeclTy*, 8> PropertyDecls;
|
||||
ParseStructDeclaration(interfaceDecl, PropertyDecls);
|
||||
if (Tok.is(tok::semi))
|
||||
ConsumeToken();
|
||||
|
@ -370,6 +395,8 @@ void Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl) {
|
|||
Diag(Tok, diag::err_expected_semi_decl_list);
|
||||
SkipUntil(tok::r_brace, true, true);
|
||||
}
|
||||
return Actions.ActOnAddObjcProperties(AtLoc,
|
||||
&PropertyDecls[0], PropertyDecls.size(), DS);
|
||||
}
|
||||
|
||||
/// objc-method-proto:
|
||||
|
@ -919,6 +946,7 @@ Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
|
|||
/// Insert collected methods declarations into the @interface object.
|
||||
Actions.ActOnAddMethodsToObjcDecl(CurScope, ObjcImpDecl,
|
||||
&AllImplMethods[0], AllImplMethods.size(),
|
||||
(DeclTy **)0, 0,
|
||||
atLoc);
|
||||
ObjcImpDecl = 0;
|
||||
AllImplMethods.clear();
|
||||
|
|
|
@ -531,8 +531,14 @@ public:
|
|||
|
||||
virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl,
|
||||
DeclTy **allMethods, unsigned allNum,
|
||||
DeclTy **allProperties, unsigned pNum,
|
||||
SourceLocation AtEndLoc);
|
||||
|
||||
virtual DeclTy *ActOnAddObjcProperties(SourceLocation AtLoc,
|
||||
DeclTy **allProperties,
|
||||
unsigned NumProperties,
|
||||
ObjcDeclSpec &DS);
|
||||
|
||||
virtual DeclTy *ActOnMethodDeclaration(
|
||||
SourceLocation BeginLoc, // location of the + or -.
|
||||
SourceLocation EndLoc, // location of the ; or {.
|
||||
|
|
|
@ -1916,6 +1916,7 @@ void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) {
|
|||
|
||||
void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,
|
||||
DeclTy **allMethods, unsigned allNum,
|
||||
DeclTy **allProperties, unsigned pNum,
|
||||
SourceLocation AtEndLoc) {
|
||||
Decl *ClassDecl = static_cast<Decl *>(classDecl);
|
||||
|
||||
|
@ -1931,11 +1932,19 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,
|
|||
llvm::DenseMap<Selector, const ObjcMethodDecl*> InsMap;
|
||||
llvm::DenseMap<Selector, const ObjcMethodDecl*> ClsMap;
|
||||
|
||||
bool checkDuplicateMethods =
|
||||
bool isInterfaceDeclKind =
|
||||
(isa<ObjcInterfaceDecl>(ClassDecl) || isa<ObjcCategoryDecl>(ClassDecl)
|
||||
|| isa<ObjcProtocolDecl>(ClassDecl));
|
||||
bool checkIdenticalMethods = isa<ObjcImplementationDecl>(ClassDecl);
|
||||
|
||||
// TODO: property declaration in category and protocols.
|
||||
if (pNum != 0 && isa<ObjcInterfaceDecl>(ClassDecl)) {
|
||||
ObjcPropertyDecl **properties = new ObjcPropertyDecl*[pNum];
|
||||
memcpy(properties, allProperties, pNum*sizeof(ObjcPropertyDecl*));
|
||||
dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setPropertyDecls(properties);
|
||||
dyn_cast<ObjcInterfaceDecl>(ClassDecl)->setNumPropertyDecl(pNum);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < allNum; i++ ) {
|
||||
ObjcMethodDecl *Method =
|
||||
cast_or_null<ObjcMethodDecl>(static_cast<Decl*>(allMethods[i]));
|
||||
|
@ -1946,7 +1955,7 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,
|
|||
const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
|
||||
bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
|
||||
: false;
|
||||
if (checkDuplicateMethods && PrevMethod && !match
|
||||
if (isInterfaceDeclKind && PrevMethod && !match
|
||||
|| checkIdenticalMethods && match) {
|
||||
Diag(Method->getLocation(), diag::error_duplicate_method_decl,
|
||||
Method->getSelector().getName());
|
||||
|
@ -1963,7 +1972,7 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl,
|
|||
const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
|
||||
bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
|
||||
: false;
|
||||
if (checkDuplicateMethods && PrevMethod && !match
|
||||
if (isInterfaceDeclKind && PrevMethod && !match
|
||||
|| checkIdenticalMethods && match) {
|
||||
Diag(Method->getLocation(), diag::error_duplicate_method_decl,
|
||||
Method->getSelector().getName());
|
||||
|
@ -2077,6 +2086,47 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
|
|||
return ObjcMethod;
|
||||
}
|
||||
|
||||
Sema::DeclTy *Sema::ActOnAddObjcProperties(SourceLocation AtLoc,
|
||||
DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) {
|
||||
ObjcPropertyDecl *PDecl = new ObjcPropertyDecl(AtLoc);
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readonly)
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readonly);
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_getter) {
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_getter);
|
||||
PDecl->setGetterName(DS.getGetterName());
|
||||
}
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_setter) {
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_setter);
|
||||
PDecl->setSetterName(DS.getSetterName());
|
||||
}
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_assign)
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_assign);
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readwrite)
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readwrite);
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_retain)
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_retain);
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_copy)
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_copy);
|
||||
|
||||
if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_nonatomic)
|
||||
PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_nonatomic);
|
||||
|
||||
PDecl->setNumPropertyDecls(NumProperties);
|
||||
if (NumProperties != 0) {
|
||||
ObjcIvarDecl **properties = new ObjcIvarDecl*[NumProperties];
|
||||
memcpy(properties, allProperties, NumProperties*sizeof(ObjcIvarDecl*));
|
||||
PDecl->setPropertyDecls(properties);
|
||||
}
|
||||
return PDecl;
|
||||
}
|
||||
|
||||
Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
|
||||
DeclTy *lastEnumConst,
|
||||
SourceLocation IdLoc, IdentifierInfo *Id,
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
ObjcCategoryImpl,
|
||||
ObjcImplementation,
|
||||
ObjcProtocol,
|
||||
PropertyDecl,
|
||||
// ScopedDecl
|
||||
CompatibleAlias,
|
||||
// TypeDecl
|
||||
|
|
|
@ -26,6 +26,7 @@ class ObjcIvarDecl;
|
|||
class ObjcMethodDecl;
|
||||
class ObjcProtocolDecl;
|
||||
class ObjcCategoryDecl;
|
||||
class ObjcPropertyDecl;
|
||||
|
||||
/// ObjcInterfaceDecl - Represents an ObjC class declaration. For example:
|
||||
///
|
||||
|
@ -71,6 +72,10 @@ class ObjcInterfaceDecl : public TypeDecl {
|
|||
|
||||
/// List of categories defined for this class.
|
||||
ObjcCategoryDecl *CategoryList;
|
||||
|
||||
/// class properties
|
||||
ObjcPropertyDecl **PropertyDecl; // Null if no property
|
||||
int NumPropertyDecl; // -1 if no property
|
||||
|
||||
bool ForwardDecl:1; // declared with @class.
|
||||
bool InternalInterface:1; // true - no @interface for @implementation
|
||||
|
@ -86,7 +91,8 @@ public:
|
|||
NumIvars(-1),
|
||||
InstanceMethods(0), NumInstanceMethods(-1),
|
||||
ClassMethods(0), NumClassMethods(-1),
|
||||
CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal) {
|
||||
CategoryList(0), PropertyDecl(0), NumPropertyDecl(-1),
|
||||
ForwardDecl(FD), InternalInterface(isInternal) {
|
||||
AllocIntfRefProtocols(numRefProtos);
|
||||
}
|
||||
|
||||
|
@ -146,6 +152,16 @@ public:
|
|||
|
||||
// We also need to record the @end location.
|
||||
SourceLocation getAtEndLoc() const { return AtEndLoc; }
|
||||
|
||||
const int getNumPropertyDecl() const { return NumPropertyDecl; }
|
||||
int getNumPropertyDecl() { return NumPropertyDecl; }
|
||||
void setNumPropertyDecl(int num) { NumPropertyDecl = num; }
|
||||
|
||||
ObjcPropertyDecl **const getPropertyDecl() const { return PropertyDecl; }
|
||||
ObjcPropertyDecl **getPropertyDecl() { return PropertyDecl; }
|
||||
void setPropertyDecls(ObjcPropertyDecl **properties) {
|
||||
PropertyDecl = properties;
|
||||
}
|
||||
|
||||
/// ImplicitInterfaceDecl - check that this is an implicitely declared
|
||||
/// ObjcInterfaceDecl node. This is for legacy objective-c @implementation
|
||||
|
@ -669,6 +685,61 @@ public:
|
|||
static bool classof(const ObjcCompatibleAliasDecl *D) { return true; }
|
||||
|
||||
};
|
||||
|
||||
class ObjcPropertyDecl : public Decl {
|
||||
public:
|
||||
enum PrpoertyAttributeKind { OBJC_PR_noattr = 0x0,
|
||||
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 };
|
||||
private:
|
||||
// List of property name declarations
|
||||
// FIXME: Property is not an ivar.
|
||||
ObjcIvarDecl **PropertyDecls;
|
||||
int NumPropertyDecls;
|
||||
|
||||
PrpoertyAttributeKind PropertyAttributes : 8;
|
||||
|
||||
IdentifierInfo *GetterName; // getter name of NULL if no getter
|
||||
IdentifierInfo *SetterName; // setter name of NULL if no setter
|
||||
|
||||
public:
|
||||
ObjcPropertyDecl(SourceLocation L)
|
||||
: Decl(PropertyDecl, L),
|
||||
PropertyDecls(0), NumPropertyDecls(-1), PropertyAttributes(OBJC_PR_noattr),
|
||||
GetterName(0), SetterName(0) {}
|
||||
|
||||
ObjcIvarDecl **const getPropertyDecls() const { return PropertyDecls; }
|
||||
void setPropertyDecls(ObjcIvarDecl **property) { PropertyDecls = property; }
|
||||
|
||||
const int getNumPropertyDecls() const { return NumPropertyDecls; }
|
||||
void setNumPropertyDecls(int num) { NumPropertyDecls = num; }
|
||||
|
||||
const PrpoertyAttributeKind getPropertyAttributes() const
|
||||
{ return PropertyAttributes; }
|
||||
void setPropertyAttributes(PrpoertyAttributeKind PRVal) {
|
||||
PropertyAttributes =
|
||||
(PrpoertyAttributeKind) (PropertyAttributes | PRVal);
|
||||
}
|
||||
|
||||
const IdentifierInfo *getGetterName() const { return GetterName; }
|
||||
IdentifierInfo *getGetterName() { return GetterName; }
|
||||
void setGetterName(IdentifierInfo *Id) { GetterName = Id; }
|
||||
|
||||
const IdentifierInfo *getSetterName() const { return SetterName; }
|
||||
IdentifierInfo *getSetterName() { return SetterName; }
|
||||
void setSetterName(IdentifierInfo *Id) { SetterName = Id; }
|
||||
|
||||
static bool classof(const Decl *D) {
|
||||
return D->getKind() == PropertyDecl;
|
||||
}
|
||||
static bool classof(const ObjcPropertyDecl *D) { return true; }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
#endif
|
||||
|
|
|
@ -565,9 +565,18 @@ public:
|
|||
DeclTy *ClassDecl,
|
||||
DeclTy **allMethods,
|
||||
unsigned allNum,
|
||||
DeclTy **allProperties,
|
||||
unsigned NumProperties,
|
||||
SourceLocation AtEndLoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ActOnAddObjcProperties - called to build one property AST
|
||||
virtual DeclTy *ActOnAddObjcProperties (SourceLocation AtLoc,
|
||||
DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ActOnClassMessage - used for both unary and keyword messages.
|
||||
// ArgExprs is optional - if it is present, the number of expressions
|
||||
// is obtained from Sel.getNumArgs().
|
||||
|
|
|
@ -292,13 +292,48 @@ public:
|
|||
DQ_Oneway = 0x20
|
||||
};
|
||||
|
||||
ObjcDeclSpec() : objcDeclQualifier(DQ_None) {}
|
||||
/// PrpoertyAttributeKind - list of property attributes.
|
||||
enum ObjcPrpoertyAttributeKind { 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
|
||||
};
|
||||
|
||||
|
||||
ObjcDeclSpec() : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr)
|
||||
{}
|
||||
ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; }
|
||||
void setObjcDeclQualifier(ObjcDeclQualifier DQVal)
|
||||
{ objcDeclQualifier = (ObjcDeclQualifier) (objcDeclQualifier | DQVal); }
|
||||
|
||||
const ObjcPrpoertyAttributeKind getPropertyAttributes() const
|
||||
{ return PropertyAttributes; }
|
||||
void setPropertyAttributes(ObjcPrpoertyAttributeKind PRVal) {
|
||||
PropertyAttributes =
|
||||
(ObjcPrpoertyAttributeKind) (PropertyAttributes | PRVal);
|
||||
}
|
||||
|
||||
const IdentifierInfo *getGetterName() const { return GetterName; }
|
||||
IdentifierInfo *getGetterName() { return GetterName; }
|
||||
void setGetterName(IdentifierInfo *name) { GetterName = name; }
|
||||
|
||||
const IdentifierInfo *getSetterName() const { return SetterName; }
|
||||
IdentifierInfo *getSetterName() { return SetterName; }
|
||||
void setSetterName(IdentifierInfo *name) { SetterName = name; }
|
||||
private:
|
||||
// FIXME: These two are unrelated and mutially exclusive. So perhaps
|
||||
// we can put them in a union to reflect their mutual exclusiveness
|
||||
// (space saving is negligible).
|
||||
ObjcDeclQualifier objcDeclQualifier : 6;
|
||||
|
||||
ObjcPrpoertyAttributeKind PropertyAttributes : 8;
|
||||
IdentifierInfo *GetterName; // getter name of NULL if no getter
|
||||
IdentifierInfo *SetterName; // setter name of NULL if no setter
|
||||
};
|
||||
|
||||
/// DeclaratorChunk - One instance of this struct is used for each type in a
|
||||
|
|
|
@ -298,8 +298,8 @@ private:
|
|||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
|
||||
DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
|
||||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
|
||||
void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
|
||||
void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
|
||||
void ParseObjCPropertyAttribute(ObjcDeclSpec &DS);
|
||||
DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);
|
||||
|
||||
void ParseObjCInstanceMethodDefinition();
|
||||
void ParseObjCClassMethodDefinition();
|
||||
|
|
Загрузка…
Ссылка в новой задаче