diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/AttrImpl.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 25 |
4 files changed, 25 insertions, 9 deletions
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp index dcd3c5bc43..994d45cf74 100644 --- a/lib/AST/AttrImpl.cpp +++ b/lib/AST/AttrImpl.cpp @@ -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 { diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index aa5ce7aad6..a581951da7 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -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; } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 76fd5528dc..ac30fd34cc 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -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; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index a234a73795..1e3405768a 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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) { |