summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-11-18 14:59:57 +0000
commit741c13ecc20fb35b836ad690aeecd402f002d654 (patch)
tree60a1694bec5a44d15456acc880cb2f91619f66aa /lib/Sema/SemaDeclObjC.cpp
parentb3a51061b1b9c4add078237850649f7c9efb13ab (diff)
downloadFreeBSD-src-741c13ecc20fb35b836ad690aeecd402f002d654.zip
FreeBSD-src-741c13ecc20fb35b836ad690aeecd402f002d654.tar.gz
Update clang to r89205.
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--lib/Sema/SemaDeclObjC.cpp81
1 files changed, 68 insertions, 13 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 93f8d0d..0c5569c 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -112,6 +112,14 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IDecl->setLocation(AtInterfaceLoc);
IDecl->setForwardDecl(false);
IDecl->setClassLoc(ClassLoc);
+
+ // Since this ObjCInterfaceDecl was created by a forward declaration,
+ // we now add it to the DeclContext since it wasn't added before
+ // (see ActOnForwardClassDeclaration).
+ CurContext->addDecl(IDecl);
+
+ if (AttrList)
+ ProcessDeclAttributeList(TUScope, IDecl, AttrList);
}
} else {
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
@@ -1113,10 +1121,46 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
assert(false && "invalid ObjCContainerDecl type.");
}
+void
+Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
+ ObjCContainerDecl* IDecl) {
+ // Rules apply in non-GC mode only
+ if (getLangOptions().getGCMode() != LangOptions::NonGC)
+ return;
+ for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(),
+ E = IDecl->prop_end();
+ I != E; ++I) {
+ ObjCPropertyDecl *Property = (*I);
+ unsigned Attributes = Property->getPropertyAttributes();
+ // We only care about readwrite atomic property.
+ if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
+ !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
+ continue;
+ if (const ObjCPropertyImplDecl *PIDecl
+ = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) {
+ if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ continue;
+ ObjCMethodDecl *GetterMethod =
+ IMPDecl->getInstanceMethod(Property->getGetterName());
+ ObjCMethodDecl *SetterMethod =
+ IMPDecl->getInstanceMethod(Property->getSetterName());
+ if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
+ SourceLocation MethodLoc =
+ (GetterMethod ? GetterMethod->getLocation()
+ : SetterMethod->getLocation());
+ Diag(MethodLoc, diag::warn_atomic_property_rule)
+ << Property->getIdentifier();
+ Diag(Property->getLocation(), diag::note_property_declare);
+ }
+ }
+ }
+}
+
/// ActOnForwardClassDeclaration -
Action::DeclPtrTy
Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
+ SourceLocation *IdentLocs,
unsigned NumElts) {
llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
@@ -1153,18 +1197,23 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (!IDecl) { // Not already seen? Make a forward decl.
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
- IdentList[i],
- // FIXME: need to get the 'real'
- // identifier loc from the parser.
- AtClassLoc, true);
- PushOnScopeChains(IDecl, TUScope);
+ IdentList[i], IdentLocs[i], true);
+
+ // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
+ // the current DeclContext. This prevents clients that walk DeclContext
+ // from seeing the imaginary ObjCInterfaceDecl until it is actually
+ // declared later (if at all). We also take care to explicitly make
+ // sure this declaration is visible for name lookup.
+ PushOnScopeChains(IDecl, TUScope, false);
+ CurContext->makeDeclVisibleInContext(IDecl, true);
}
Interfaces.push_back(IDecl);
}
+ assert(Interfaces.size() == NumElts);
ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
- &Interfaces[0],
+ Interfaces.data(), IdentLocs,
Interfaces.size());
CurContext->addDecl(CDecl);
CheckObjCDeclScope(CDecl);
@@ -1524,12 +1573,17 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
// should be true.
if (!ClassDecl)
return;
-
+
bool isInterfaceDeclKind =
isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
|| isa<ObjCProtocolDecl>(ClassDecl);
bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
+ if (!isInterfaceDeclKind && AtEndLoc.isInvalid()) {
+ AtEndLoc = ClassDecl->getLocation();
+ Diag(AtEndLoc, diag::warn_missing_atend);
+ }
+
DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
// FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
@@ -1608,8 +1662,10 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
}
if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
IC->setAtEndLoc(AtEndLoc);
- if (ObjCInterfaceDecl* IDecl = IC->getClassInterface())
+ if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
ImplMethodsVsClassMethods(IC, IDecl);
+ AtomicPropertySetterGetterRules(IC, IDecl);
+ }
} else if (ObjCCategoryImplDecl* CatImplClass =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
CatImplClass->setAtEndLoc(AtEndLoc);
@@ -1910,13 +1966,12 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
// with continuation class's readwrite property attribute!
unsigned PIkind = PIDecl->getPropertyAttributes();
if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
- unsigned assignRetainCopyNonatomic =
- (ObjCPropertyDecl::OBJC_PR_assign |
- ObjCPropertyDecl::OBJC_PR_retain |
+ unsigned retainCopyNonatomic =
+ (ObjCPropertyDecl::OBJC_PR_retain |
ObjCPropertyDecl::OBJC_PR_copy |
ObjCPropertyDecl::OBJC_PR_nonatomic);
- if ((Attributes & assignRetainCopyNonatomic) !=
- (PIkind & assignRetainCopyNonatomic)) {
+ if ((Attributes & retainCopyNonatomic) !=
+ (PIkind & retainCopyNonatomic)) {
Diag(AtLoc, diag::warn_property_attr_mismatch);
Diag(PIDecl->getLocation(), diag::note_property_declare);
}
OpenPOWER on IntegriCloud