forked from OSchip/llvm-project
Patch to add type parameter support for attribute iboutletcollection.
Radar 8308053. llvm-svn: 111275
This commit is contained in:
parent
1a58ce7646
commit
b5d59b66c2
|
@ -17,6 +17,7 @@
|
|||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "clang/Basic/AttrKinds.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
@ -27,6 +28,7 @@ namespace clang {
|
|||
class IdentifierInfo;
|
||||
class ObjCInterfaceDecl;
|
||||
class Expr;
|
||||
class QualType;
|
||||
}
|
||||
|
||||
// Defined in ASTContext.h
|
||||
|
@ -286,12 +288,12 @@ public:
|
|||
};
|
||||
|
||||
class IBOutletCollectionAttr : public Attr {
|
||||
const ObjCInterfaceDecl *D;
|
||||
QualType QT;
|
||||
public:
|
||||
IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
|
||||
: Attr(attr::IBOutletCollection), D(d) {}
|
||||
IBOutletCollectionAttr(QualType qt = QualType())
|
||||
: Attr(attr::IBOutletCollection), QT(qt) {}
|
||||
|
||||
const ObjCInterfaceDecl *getClass() const { return D; }
|
||||
QualType getType() const { return QT; }
|
||||
|
||||
virtual Attr *clone(ASTContext &C) const;
|
||||
|
||||
|
|
|
@ -826,6 +826,8 @@ def err_attributes_are_not_compatible : Error<
|
|||
"%0 and %1 attributes are not compatible">;
|
||||
def err_attribute_wrong_number_arguments : Error<
|
||||
"attribute requires %0 argument(s)">;
|
||||
def err_iboutletcollection_type : Error<
|
||||
"invalid type %0 as argument of iboutletcollection attribue">;
|
||||
def err_attribute_missing_parameter_name : Error<
|
||||
"attribute requires unquoted parameter">;
|
||||
def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
|
||||
|
|
|
@ -163,7 +163,7 @@ Attr *IBOutletAttr::clone(ASTContext &C) const {
|
|||
}
|
||||
|
||||
Attr *IBOutletCollectionAttr::clone(ASTContext &C) const {
|
||||
return ::new (C) IBOutletCollectionAttr(D);
|
||||
return ::new (C) IBOutletCollectionAttr(QT);
|
||||
}
|
||||
|
||||
Attr *IBActionAttr::clone(ASTContext &C) const {
|
||||
|
|
|
@ -1190,9 +1190,8 @@ Attr *PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor) {
|
|||
break;
|
||||
|
||||
case attr::IBOutletCollection: {
|
||||
ObjCInterfaceDecl *D =
|
||||
cast_or_null<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
|
||||
New = ::new (*Context) IBOutletCollectionAttr(D);
|
||||
QualType QT = GetType(Record[Idx++]);
|
||||
New = ::new (*Context) IBOutletCollectionAttr(QT);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -2051,7 +2051,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
|||
|
||||
case attr::IBOutletCollection: {
|
||||
const IBOutletCollectionAttr *ICA = cast<IBOutletCollectionAttr>(Attr);
|
||||
AddDeclRef(ICA->getClass(), Record);
|
||||
AddTypeRef(ICA->getType(), Record);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
|
|||
Sema &S) {
|
||||
|
||||
// The iboutletcollection attribute can have zero or one arguments.
|
||||
if (Attr.getNumArgs() > 1) {
|
||||
if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
||||
return;
|
||||
}
|
||||
|
@ -274,9 +274,26 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
|
|||
S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Eventually accept the type argument.
|
||||
d->addAttr(::new (S.Context) IBOutletCollectionAttr());
|
||||
IdentifierInfo *II = Attr.getParameterName();
|
||||
if (!II)
|
||||
II = &S.Context.Idents.get("id");
|
||||
Sema::TypeTy *TypeRep = S.getTypeName(*II, Attr.getLoc(),
|
||||
S.getScopeForContext(d->getDeclContext()->getParent()));
|
||||
if (!TypeRep) {
|
||||
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
|
||||
return;
|
||||
}
|
||||
QualType QT(QualType::getFromOpaquePtr(TypeRep));
|
||||
// Diagnose use of non-object type in iboutletcollection attribute.
|
||||
// FIXME. Gnu attribute extension ignores use of builtin types in
|
||||
// attributes. So, __attribute__((iboutletcollection(char))) will be
|
||||
// treated as __attribute__((iboutletcollection())).
|
||||
if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
|
||||
!QT->isObjCObjectType()) {
|
||||
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
|
||||
return;
|
||||
}
|
||||
d->addAttr(::new (S.Context) IBOutletCollectionAttr(QT));
|
||||
}
|
||||
|
||||
static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify %s
|
||||
// rdar: // 8308053
|
||||
|
||||
@interface I {
|
||||
__attribute__((iboutletcollection(I))) id ivar1;
|
||||
__attribute__((iboutletcollection(id))) id ivar2;
|
||||
__attribute__((iboutletcollection())) id ivar3;
|
||||
__attribute__((iboutletcollection)) id ivar4;
|
||||
}
|
||||
@property (nonatomic, retain) __attribute__((iboutletcollection(I))) id prop1;
|
||||
@property (nonatomic, retain) __attribute__((iboutletcollection(id))) id prop2;
|
||||
@property (nonatomic, retain) __attribute__((iboutletcollection())) id prop3;
|
||||
@property (nonatomic, retain) __attribute__((iboutletcollection)) id prop4;
|
||||
@end
|
||||
|
||||
typedef void *PV;
|
||||
@interface BAD {
|
||||
__attribute__((iboutletcollection(I, 1))) id ivar1; // expected-error {{attribute requires 1 argument(s)}}
|
||||
__attribute__((iboutletcollection(B))) id ivar2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribue}}
|
||||
__attribute__((iboutletcollection(PV))) id ivar3; // // expected-error {{invalid type 'PV' as argument of iboutletcollection attribue}}
|
||||
}
|
||||
@property (nonatomic, retain) __attribute__((iboutletcollection(I,2,3))) id prop1; // expected-error {{attribute requires 1 argument(s)}}
|
||||
@property (nonatomic, retain) __attribute__((iboutletcollection(B))) id prop2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribue}}
|
||||
@end
|
||||
|
Loading…
Reference in New Issue