blob: 49433b5b7b08d4e4ee8ab5d9c21420f6e9fc7c89 [file] [log] [blame]
Chris Lattner4d391482007-12-12 07:09:47 +00001//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner4d391482007-12-12 07:09:47 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements semantic analysis for Objective C declarations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
Steve Naroffca331292009-03-03 14:49:36 +000015#include "clang/AST/Expr.h"
Chris Lattner4d391482007-12-12 07:09:47 +000016#include "clang/AST/ASTContext.h"
17#include "clang/AST/DeclObjC.h"
Daniel Dunbar12bc6922008-08-11 03:27:53 +000018#include "clang/Parse/DeclSpec.h"
Chris Lattner4d391482007-12-12 07:09:47 +000019using namespace clang;
20
Steve Naroffebf64432009-02-28 16:59:13 +000021/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
Chris Lattner4d391482007-12-12 07:09:47 +000022/// and user declared, in the method definition's AST.
Chris Lattnerb28317a2009-03-28 19:18:32 +000023void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
Argyrios Kyrtzidis53d0ea52008-06-28 06:07:14 +000024 assert(getCurMethodDecl() == 0 && "Method parsing confused");
Chris Lattnerb28317a2009-03-28 19:18:32 +000025 ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
Steve Naroff394f3f42008-07-25 17:57:26 +000026
27 // If we don't have a valid method decl, simply return.
28 if (!MDecl)
29 return;
Steve Naroffa56f6162007-12-18 01:30:32 +000030
31 // Allow the rest of sema to find private method decl implementations.
Douglas Gregorf8d49f62009-01-09 17:18:27 +000032 if (MDecl->isInstanceMethod())
Steve Naroffa56f6162007-12-18 01:30:32 +000033 AddInstanceMethodToGlobalPool(MDecl);
34 else
35 AddFactoryMethodToGlobalPool(MDecl);
Chris Lattner4d391482007-12-12 07:09:47 +000036
37 // Allow all of Sema to see that we are entering a method definition.
Douglas Gregor44b43212008-12-11 16:49:14 +000038 PushDeclContext(FnBodyScope, MDecl);
Chris Lattner4d391482007-12-12 07:09:47 +000039
40 // Create Decl objects for each parameter, entrring them in the scope for
41 // binding to their use.
Chris Lattner4d391482007-12-12 07:09:47 +000042
43 // Insert the invisible arguments, self and _cmd!
Fariborz Jahanianfef30b52008-12-09 20:23:04 +000044 MDecl->createImplicitParams(Context, MDecl->getClassInterface());
Chris Lattner4d391482007-12-12 07:09:47 +000045
Daniel Dunbar451318c2008-08-26 06:07:48 +000046 PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
47 PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
Chris Lattner04421082008-04-08 04:40:51 +000048
Chris Lattner8123a952008-04-10 02:22:51 +000049 // Introduce all of the other parameters into this scope.
Chris Lattner89951a82009-02-20 18:43:26 +000050 for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(),
51 E = MDecl->param_end(); PI != E; ++PI)
52 if ((*PI)->getIdentifier())
53 PushOnScopeChains(*PI, FnBodyScope);
Chris Lattner4d391482007-12-12 07:09:47 +000054}
55
Chris Lattnerb28317a2009-03-28 19:18:32 +000056Sema::DeclPtrTy Sema::
Chris Lattner7caeabd2008-07-21 22:17:28 +000057ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
58 IdentifierInfo *ClassName, SourceLocation ClassLoc,
59 IdentifierInfo *SuperName, SourceLocation SuperLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +000060 const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
Chris Lattner7caeabd2008-07-21 22:17:28 +000061 SourceLocation EndProtoLoc, AttributeList *AttrList) {
Chris Lattner4d391482007-12-12 07:09:47 +000062 assert(ClassName && "Missing class identifier");
63
64 // Check for another declaration kind with the same name.
Douglas Gregor47b9a1c2009-02-04 17:27:36 +000065 NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregorf57172b2008-12-08 18:40:42 +000066 if (PrevDecl && PrevDecl->isTemplateParameter()) {
Douglas Gregor72c3f312008-12-05 18:15:24 +000067 // Maybe we will complain about the shadowed template parameter.
68 DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
69 // Just pretend that we didn't see the previous declaration.
70 PrevDecl = 0;
71 }
72
Ted Kremeneka526c5c2008-01-07 19:49:32 +000073 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner3c73c412008-11-19 08:23:25 +000074 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Chris Lattner5f4a6822008-11-23 23:12:31 +000075 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
Chris Lattner4d391482007-12-12 07:09:47 +000076 }
77
Ted Kremeneka526c5c2008-01-07 19:49:32 +000078 ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +000079 if (IDecl) {
80 // Class already seen. Is it a forward declaration?
Steve Naroffcfe8bf32008-11-18 19:15:30 +000081 if (!IDecl->isForwardDecl()) {
Chris Lattner1829a6d2009-02-23 22:00:08 +000082 IDecl->setInvalidDecl();
Chris Lattnerd9d22dd2008-11-24 05:29:24 +000083 Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
Chris Lattnerb8b96af2008-11-23 22:46:27 +000084 Diag(IDecl->getLocation(), diag::note_previous_definition);
85
Steve Naroffcfe8bf32008-11-18 19:15:30 +000086 // Return the previous class interface.
87 // FIXME: don't leak the objects passed in!
Chris Lattnerb28317a2009-03-28 19:18:32 +000088 return DeclPtrTy::make(IDecl);
Steve Naroffcfe8bf32008-11-18 19:15:30 +000089 } else {
Chris Lattner4d391482007-12-12 07:09:47 +000090 IDecl->setLocation(AtInterfaceLoc);
91 IDecl->setForwardDecl(false);
Chris Lattner4d391482007-12-12 07:09:47 +000092 }
Chris Lattnerb752f282008-07-21 07:06:49 +000093 } else {
Douglas Gregord0434102009-01-09 00:49:46 +000094 IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000095 ClassName, ClassLoc);
Daniel Dunbarf6414922008-08-20 18:02:42 +000096 if (AttrList)
97 ProcessDeclAttributeList(IDecl, AttrList);
Chris Lattner4d391482007-12-12 07:09:47 +000098
Steve Naroff31102512008-04-02 18:30:49 +000099 ObjCInterfaceDecls[ClassName] = IDecl;
Douglas Gregord0434102009-01-09 00:49:46 +0000100 // FIXME: PushOnScopeChains
Douglas Gregor6ab35242009-04-09 21:40:53 +0000101 CurContext->addDecl(Context, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000102 // Remember that this needs to be removed when the scope is popped.
Chris Lattnerb28317a2009-03-28 19:18:32 +0000103 TUScope->AddDecl(DeclPtrTy::make(IDecl));
Chris Lattner4d391482007-12-12 07:09:47 +0000104 }
105
106 if (SuperName) {
Chris Lattner4d391482007-12-12 07:09:47 +0000107 // Check if a different kind of symbol declared in this scope.
Douglas Gregor4c921ae2009-01-30 01:04:22 +0000108 PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
Chris Lattner3c73c412008-11-19 08:23:25 +0000109
Steve Naroff818cb9e2009-02-04 17:14:05 +0000110 ObjCInterfaceDecl *SuperClassDecl =
111 dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattnerc7984dd2009-02-16 21:33:09 +0000112
113 // Diagnose classes that inherit from deprecated classes.
114 if (SuperClassDecl)
Douglas Gregor48f3bb92009-02-18 21:56:37 +0000115 (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
Chris Lattnerc7984dd2009-02-16 21:33:09 +0000116
Steve Naroff818cb9e2009-02-04 17:14:05 +0000117 if (PrevDecl && SuperClassDecl == 0) {
118 // The previous declaration was not a class decl. Check if we have a
119 // typedef. If we do, get the underlying class type.
120 if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
121 QualType T = TDecl->getUnderlyingType();
122 if (T->isObjCInterfaceType()) {
123 if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
124 SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
125 }
126 }
Chris Lattnerc7984dd2009-02-16 21:33:09 +0000127
Steve Naroff818cb9e2009-02-04 17:14:05 +0000128 // This handles the following case:
129 //
130 // typedef int SuperClass;
131 // @interface MyClass : SuperClass {} @end
132 //
133 if (!SuperClassDecl) {
134 Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
135 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
136 }
137 }
Chris Lattnerc7984dd2009-02-16 21:33:09 +0000138
Steve Naroff818cb9e2009-02-04 17:14:05 +0000139 if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
140 if (!SuperClassDecl)
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000141 Diag(SuperLoc, diag::err_undef_superclass)
Chris Lattner3c73c412008-11-19 08:23:25 +0000142 << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
Steve Naroff818cb9e2009-02-04 17:14:05 +0000143 else if (SuperClassDecl->isForwardDecl())
Chris Lattner3c73c412008-11-19 08:23:25 +0000144 Diag(SuperLoc, diag::err_undef_superclass)
Steve Naroff818cb9e2009-02-04 17:14:05 +0000145 << SuperClassDecl->getDeclName() << ClassName
Chris Lattner3c73c412008-11-19 08:23:25 +0000146 << SourceRange(AtInterfaceLoc, ClassLoc);
Chris Lattner4d391482007-12-12 07:09:47 +0000147 }
Steve Naroff818cb9e2009-02-04 17:14:05 +0000148 IDecl->setSuperClass(SuperClassDecl);
Steve Naroffd6a07aa2008-04-11 19:35:35 +0000149 IDecl->setSuperClassLoc(SuperLoc);
Chris Lattner4d391482007-12-12 07:09:47 +0000150 IDecl->setLocEnd(SuperLoc);
151 } else { // we have a root class.
152 IDecl->setLocEnd(ClassLoc);
153 }
154
Steve Naroffcfe8bf32008-11-18 19:15:30 +0000155 /// Check then save referenced protocols.
Chris Lattner06036d32008-07-26 04:13:19 +0000156 if (NumProtoRefs) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000157 IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
158 Context);
Chris Lattner4d391482007-12-12 07:09:47 +0000159 IDecl->setLocEnd(EndProtoLoc);
160 }
Anders Carlsson15281452008-11-04 16:57:32 +0000161
162 CheckObjCDeclScope(IDecl);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000163 return DeclPtrTy::make(IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000164}
165
166/// ActOnCompatiblityAlias - this action is called after complete parsing of
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000167/// @compatibility_alias declaration. It sets up the alias relationships.
Chris Lattnerb28317a2009-03-28 19:18:32 +0000168Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
169 IdentifierInfo *AliasName,
170 SourceLocation AliasLocation,
171 IdentifierInfo *ClassName,
172 SourceLocation ClassLocation) {
Chris Lattner4d391482007-12-12 07:09:47 +0000173 // Look for previous declaration of alias name
Douglas Gregor47b9a1c2009-02-04 17:27:36 +0000174 NamedDecl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
Chris Lattner4d391482007-12-12 07:09:47 +0000175 if (ADecl) {
Chris Lattner8b265bd2008-11-23 23:20:13 +0000176 if (isa<ObjCCompatibleAliasDecl>(ADecl))
Chris Lattner4d391482007-12-12 07:09:47 +0000177 Diag(AliasLocation, diag::warn_previous_alias_decl);
Chris Lattner8b265bd2008-11-23 23:20:13 +0000178 else
Chris Lattner3c73c412008-11-19 08:23:25 +0000179 Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
Chris Lattner8b265bd2008-11-23 23:20:13 +0000180 Diag(ADecl->getLocation(), diag::note_previous_declaration);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000181 return DeclPtrTy();
Chris Lattner4d391482007-12-12 07:09:47 +0000182 }
183 // Check for class declaration
Douglas Gregor47b9a1c2009-02-04 17:27:36 +0000184 NamedDecl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
Fariborz Jahanian305c6582009-01-08 01:10:55 +0000185 if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
186 QualType T = TDecl->getUnderlyingType();
187 if (T->isObjCInterfaceType()) {
188 if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) {
189 ClassName = IDecl->getIdentifier();
Douglas Gregor4c921ae2009-01-30 01:04:22 +0000190 CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
Fariborz Jahanian305c6582009-01-08 01:10:55 +0000191 }
192 }
193 }
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000194 ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
195 if (CDecl == 0) {
Chris Lattner3c73c412008-11-19 08:23:25 +0000196 Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000197 if (CDeclU)
Chris Lattner8b265bd2008-11-23 23:20:13 +0000198 Diag(CDeclU->getLocation(), diag::note_previous_declaration);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000199 return DeclPtrTy();
Chris Lattner4d391482007-12-12 07:09:47 +0000200 }
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000201
202 // Everything checked out, instantiate a new alias declaration AST.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000203 ObjCCompatibleAliasDecl *AliasDecl =
Douglas Gregord0434102009-01-09 00:49:46 +0000204 ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
Steve Naroffe8043c32008-04-01 23:04:06 +0000205
206 ObjCAliasDecls[AliasName] = AliasDecl;
Douglas Gregord0434102009-01-09 00:49:46 +0000207
208 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000209 CurContext->addDecl(Context, AliasDecl);
Anders Carlsson15281452008-11-04 16:57:32 +0000210 if (!CheckObjCDeclScope(AliasDecl))
Chris Lattnerb28317a2009-03-28 19:18:32 +0000211 TUScope->AddDecl(DeclPtrTy::make(AliasDecl));
Douglas Gregord0434102009-01-09 00:49:46 +0000212
Chris Lattnerb28317a2009-03-28 19:18:32 +0000213 return DeclPtrTy::make(AliasDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000214}
215
Steve Naroff61d68522009-03-05 15:22:01 +0000216void Sema::CheckForwardProtocolDeclarationForCircularDependency(
217 IdentifierInfo *PName,
218 SourceLocation &Ploc, SourceLocation PrevLoc,
219 const ObjCList<ObjCProtocolDecl> &PList)
220{
221 for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
222 E = PList.end(); I != E; ++I) {
223
224 if (ObjCProtocolDecl *PDecl = ObjCProtocols[(*I)->getIdentifier()]) {
225 if (PDecl->getIdentifier() == PName) {
226 Diag(Ploc, diag::err_protocol_has_circular_dependency);
227 Diag(PrevLoc, diag::note_previous_definition);
228 }
229 CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
230 PDecl->getLocation(), PDecl->getReferencedProtocols());
231 }
232 }
233}
234
Chris Lattnerb28317a2009-03-28 19:18:32 +0000235Sema::DeclPtrTy
Chris Lattnere13b9592008-07-26 04:03:38 +0000236Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
237 IdentifierInfo *ProtocolName,
238 SourceLocation ProtocolLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000239 const DeclPtrTy *ProtoRefs,
Chris Lattnere13b9592008-07-26 04:03:38 +0000240 unsigned NumProtoRefs,
Daniel Dunbar246e70f2008-09-26 04:48:09 +0000241 SourceLocation EndProtoLoc,
242 AttributeList *AttrList) {
243 // FIXME: Deal with AttrList.
Chris Lattner4d391482007-12-12 07:09:47 +0000244 assert(ProtocolName && "Missing protocol identifier");
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000245 ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName];
Chris Lattner4d391482007-12-12 07:09:47 +0000246 if (PDecl) {
247 // Protocol already seen. Better be a forward protocol declaration
Chris Lattner439e71f2008-03-16 01:25:17 +0000248 if (!PDecl->isForwardDecl()) {
Fariborz Jahaniane2573e52009-04-06 23:43:32 +0000249 Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
Chris Lattnerb8b96af2008-11-23 22:46:27 +0000250 Diag(PDecl->getLocation(), diag::note_previous_definition);
Chris Lattner439e71f2008-03-16 01:25:17 +0000251 // Just return the protocol we already had.
252 // FIXME: don't leak the objects passed in!
Chris Lattnerb28317a2009-03-28 19:18:32 +0000253 return DeclPtrTy::make(PDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000254 }
Steve Naroff61d68522009-03-05 15:22:01 +0000255 ObjCList<ObjCProtocolDecl> PList;
256 PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
257 CheckForwardProtocolDeclarationForCircularDependency(
258 ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
259 PList.Destroy(Context);
260
Steve Narofff11b5082008-08-13 16:39:22 +0000261 // Make sure the cached decl gets a valid start location.
262 PDecl->setLocation(AtProtoInterfaceLoc);
Chris Lattner439e71f2008-03-16 01:25:17 +0000263 PDecl->setForwardDecl(false);
Chris Lattner439e71f2008-03-16 01:25:17 +0000264 } else {
Douglas Gregord0434102009-01-09 00:49:46 +0000265 PDecl = ObjCProtocolDecl::Create(Context, CurContext,
266 AtProtoInterfaceLoc,ProtocolName);
267 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000268 CurContext->addDecl(Context, PDecl);
Chris Lattnerc8581052008-03-16 20:19:15 +0000269 PDecl->setForwardDecl(false);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000270 ObjCProtocols[ProtocolName] = PDecl;
Chris Lattnercca59d72008-03-16 01:23:04 +0000271 }
Fariborz Jahanianbc1c8772008-12-17 01:07:27 +0000272 if (AttrList)
273 ProcessDeclAttributeList(PDecl, AttrList);
Chris Lattner4d391482007-12-12 07:09:47 +0000274 if (NumProtoRefs) {
Chris Lattnerc8581052008-03-16 20:19:15 +0000275 /// Check then save referenced protocols.
Chris Lattner38af2de2009-02-20 21:35:13 +0000276 PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,Context);
Chris Lattner4d391482007-12-12 07:09:47 +0000277 PDecl->setLocEnd(EndProtoLoc);
278 }
Anders Carlsson15281452008-11-04 16:57:32 +0000279
280 CheckObjCDeclScope(PDecl);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000281 return DeclPtrTy::make(PDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000282}
283
284/// FindProtocolDeclaration - This routine looks up protocols and
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000285/// issues an error if they are not declared. It returns list of
286/// protocol declarations in its 'Protocols' argument.
Chris Lattner4d391482007-12-12 07:09:47 +0000287void
Chris Lattnere13b9592008-07-26 04:03:38 +0000288Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000289 const IdentifierLocPair *ProtocolId,
Chris Lattner4d391482007-12-12 07:09:47 +0000290 unsigned NumProtocols,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000291 llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
Chris Lattner4d391482007-12-12 07:09:47 +0000292 for (unsigned i = 0; i != NumProtocols; ++i) {
Chris Lattnereacc3922008-07-26 03:47:43 +0000293 ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i].first];
294 if (!PDecl) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000295 Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
Chris Lattner3c73c412008-11-19 08:23:25 +0000296 << ProtocolId[i].first;
Chris Lattnereacc3922008-07-26 03:47:43 +0000297 continue;
298 }
Chris Lattner45ce5c32009-02-14 08:22:25 +0000299
Douglas Gregor48f3bb92009-02-18 21:56:37 +0000300 (void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
Chris Lattnereacc3922008-07-26 03:47:43 +0000301
302 // If this is a forward declaration and we are supposed to warn in this
303 // case, do it.
304 if (WarnOnDeclarations && PDecl->isForwardDecl())
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000305 Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
Chris Lattner3c73c412008-11-19 08:23:25 +0000306 << ProtocolId[i].first;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000307 Protocols.push_back(DeclPtrTy::make(PDecl));
Chris Lattner4d391482007-12-12 07:09:47 +0000308 }
309}
310
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000311/// DiagnosePropertyMismatch - Compares two properties for their
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000312/// attributes and types and warns on a variety of inconsistencies.
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000313///
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000314void
315Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
316 ObjCPropertyDecl *SuperProperty,
Chris Lattner8ec03f52008-11-24 03:54:41 +0000317 const IdentifierInfo *inheritedName) {
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000318 ObjCPropertyDecl::PropertyAttributeKind CAttr =
319 Property->getPropertyAttributes();
320 ObjCPropertyDecl::PropertyAttributeKind SAttr =
321 SuperProperty->getPropertyAttributes();
322 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
323 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000324 Diag(Property->getLocation(), diag::warn_readonly_property)
Chris Lattner8ec03f52008-11-24 03:54:41 +0000325 << Property->getDeclName() << inheritedName;
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000326 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
327 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
Chris Lattnerc9c7c4e2008-11-18 22:52:51 +0000328 Diag(Property->getLocation(), diag::warn_property_attribute)
Chris Lattner8ec03f52008-11-24 03:54:41 +0000329 << Property->getDeclName() << "copy" << inheritedName;
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000330 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
331 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
Chris Lattnerc9c7c4e2008-11-18 22:52:51 +0000332 Diag(Property->getLocation(), diag::warn_property_attribute)
Chris Lattner8ec03f52008-11-24 03:54:41 +0000333 << Property->getDeclName() << "retain" << inheritedName;
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000334
335 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
336 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
Chris Lattnerc9c7c4e2008-11-18 22:52:51 +0000337 Diag(Property->getLocation(), diag::warn_property_attribute)
Chris Lattner8ec03f52008-11-24 03:54:41 +0000338 << Property->getDeclName() << "atomic" << inheritedName;
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000339 if (Property->getSetterName() != SuperProperty->getSetterName())
Chris Lattnerc9c7c4e2008-11-18 22:52:51 +0000340 Diag(Property->getLocation(), diag::warn_property_attribute)
Chris Lattner8ec03f52008-11-24 03:54:41 +0000341 << Property->getDeclName() << "setter" << inheritedName;
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000342 if (Property->getGetterName() != SuperProperty->getGetterName())
Chris Lattnerc9c7c4e2008-11-18 22:52:51 +0000343 Diag(Property->getLocation(), diag::warn_property_attribute)
Chris Lattner8ec03f52008-11-24 03:54:41 +0000344 << Property->getDeclName() << "getter" << inheritedName;
Steve Naroff15edf0d2009-03-03 15:43:24 +0000345
346 QualType LHSType =
347 Context.getCanonicalType(SuperProperty->getType());
348 QualType RHSType =
349 Context.getCanonicalType(Property->getType());
350
351 if (!Context.typesAreCompatible(LHSType, RHSType)) {
352 // FIXME: Incorporate this test with typesAreCompatible.
353 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType())
354 if (ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false))
355 return;
356 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
357 << Property->getType() << SuperProperty->getType() << inheritedName;
358 }
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000359}
360
361/// ComparePropertiesInBaseAndSuper - This routine compares property
362/// declarations in base and its super class, if any, and issues
363/// diagnostics in a variety of inconsistant situations.
364///
Chris Lattner70f19542009-02-16 21:26:43 +0000365void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000366 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
367 if (!SDecl)
368 return;
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000369 // FIXME: O(N^2)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000370 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(Context),
371 E = SDecl->prop_end(Context); S != E; ++S) {
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000372 ObjCPropertyDecl *SuperPDecl = (*S);
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000373 // Does property in super class has declaration in current class?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000374 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(Context),
375 E = IDecl->prop_end(Context); I != E; ++I) {
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000376 ObjCPropertyDecl *PDecl = (*I);
377 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000378 DiagnosePropertyMismatch(PDecl, SuperPDecl,
Chris Lattner8ec03f52008-11-24 03:54:41 +0000379 SDecl->getIdentifier());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000380 }
381 }
382}
383
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000384/// MergeOneProtocolPropertiesIntoClass - This routine goes thru the list
385/// of properties declared in a protocol and adds them to the list
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000386/// of properties for current class/category if it is not there already.
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000387void
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000388Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
Chris Lattner8ec03f52008-11-24 03:54:41 +0000389 ObjCProtocolDecl *PDecl) {
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000390 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
391 if (!IDecl) {
392 // Category
393 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
394 assert (CatDecl && "MergeOneProtocolPropertiesIntoClass");
Douglas Gregor6ab35242009-04-09 21:40:53 +0000395 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context),
396 E = PDecl->prop_end(Context); P != E; ++P) {
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000397 ObjCPropertyDecl *Pr = (*P);
Steve Naroff09c47192009-01-09 15:36:25 +0000398 ObjCCategoryDecl::prop_iterator CP, CE;
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000399 // Is this property already in category's list of properties?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000400 for (CP = CatDecl->prop_begin(Context), CE = CatDecl->prop_end(Context);
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000401 CP != CE; ++CP)
402 if ((*CP)->getIdentifier() == Pr->getIdentifier())
403 break;
Fariborz Jahaniana66793e2009-01-09 21:04:52 +0000404 if (CP != CE)
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000405 // Property protocol already exist in class. Diagnose any mismatch.
406 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
407 }
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000408 return;
409 }
Douglas Gregor6ab35242009-04-09 21:40:53 +0000410 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context),
411 E = PDecl->prop_end(Context); P != E; ++P) {
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000412 ObjCPropertyDecl *Pr = (*P);
Steve Naroff09c47192009-01-09 15:36:25 +0000413 ObjCInterfaceDecl::prop_iterator CP, CE;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000414 // Is this property already in class's list of properties?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000415 for (CP = IDecl->prop_begin(Context), CE = IDecl->prop_end(Context);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000416 CP != CE; ++CP)
417 if ((*CP)->getIdentifier() == Pr->getIdentifier())
418 break;
Fariborz Jahaniana66793e2009-01-09 21:04:52 +0000419 if (CP != CE)
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000420 // Property protocol already exist in class. Diagnose any mismatch.
Chris Lattner8ec03f52008-11-24 03:54:41 +0000421 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000422 }
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000423}
424
425/// MergeProtocolPropertiesIntoClass - This routine merges properties
426/// declared in 'MergeItsProtocols' objects (which can be a class or an
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000427/// inherited protocol into the list of properties for class/category 'CDecl'
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000428///
Chris Lattner70f19542009-02-16 21:26:43 +0000429void Sema::MergeProtocolPropertiesIntoClass(Decl *CDecl,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000430 DeclPtrTy MergeItsProtocols) {
431 Decl *ClassDecl = MergeItsProtocols.getAs<Decl>();
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000432 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
433
434 if (!IDecl) {
435 // Category
436 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
437 assert (CatDecl && "MergeProtocolPropertiesIntoClass");
438 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
439 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(),
440 E = MDecl->protocol_end(); P != E; ++P)
441 // Merge properties of category (*P) into IDECL's
442 MergeOneProtocolPropertiesIntoClass(CatDecl, *P);
443
444 // Go thru the list of protocols for this category and recursively merge
445 // their properties into this class as well.
446 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
447 E = CatDecl->protocol_end(); P != E; ++P)
Chris Lattnerb28317a2009-03-28 19:18:32 +0000448 MergeProtocolPropertiesIntoClass(CatDecl, DeclPtrTy::make(*P));
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000449 } else {
450 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
451 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
452 E = MD->protocol_end(); P != E; ++P)
Chris Lattnerb28317a2009-03-28 19:18:32 +0000453 MergeOneProtocolPropertiesIntoClass(CatDecl, *P);
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000454 }
455 return;
456 }
457
Chris Lattnerb752f282008-07-21 07:06:49 +0000458 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000459 for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
460 E = MDecl->protocol_end(); P != E; ++P)
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000461 // Merge properties of class (*P) into IDECL's
Chris Lattnerb752f282008-07-21 07:06:49 +0000462 MergeOneProtocolPropertiesIntoClass(IDecl, *P);
463
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000464 // Go thru the list of protocols for this class and recursively merge
465 // their properties into this class as well.
466 for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
467 E = IDecl->protocol_end(); P != E; ++P)
Chris Lattnerb28317a2009-03-28 19:18:32 +0000468 MergeProtocolPropertiesIntoClass(IDecl, DeclPtrTy::make(*P));
Chris Lattnerb752f282008-07-21 07:06:49 +0000469 } else {
Argyrios Kyrtzidise8f0d302008-07-21 09:18:38 +0000470 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
471 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
472 E = MD->protocol_end(); P != E; ++P)
Chris Lattnerb28317a2009-03-28 19:18:32 +0000473 MergeOneProtocolPropertiesIntoClass(IDecl, *P);
Chris Lattnerb752f282008-07-21 07:06:49 +0000474 }
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000475}
476
Fariborz Jahanian78c39c72009-03-02 19:06:08 +0000477/// DiagnoseClassExtensionDupMethods - Check for duplicate declaration of
Fariborz Jahanianb7f95f52009-03-02 19:05:07 +0000478/// a class method in its extension.
479///
480void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
481 ObjCInterfaceDecl *ID) {
482 if (!ID)
483 return; // Possibly due to previous error
484
485 llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
Douglas Gregor6ab35242009-04-09 21:40:53 +0000486 for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(Context),
487 e = ID->meth_end(Context); i != e; ++i) {
Fariborz Jahanianb7f95f52009-03-02 19:05:07 +0000488 ObjCMethodDecl *MD = *i;
489 MethodMap[MD->getSelector()] = MD;
490 }
491
492 if (MethodMap.empty())
493 return;
Douglas Gregor6ab35242009-04-09 21:40:53 +0000494 for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(Context),
495 e = CAT->meth_end(Context); i != e; ++i) {
Fariborz Jahanianb7f95f52009-03-02 19:05:07 +0000496 ObjCMethodDecl *Method = *i;
497 const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
498 if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
499 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
500 << Method->getDeclName();
501 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
502 }
503 }
504}
505
Chris Lattner58fe03b2009-04-12 08:43:13 +0000506/// ActOnForwardProtocolDeclaration - Handle @protocol foo;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000507Action::DeclPtrTy
Chris Lattner4d391482007-12-12 07:09:47 +0000508Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000509 const IdentifierLocPair *IdentList,
Fariborz Jahanianbc1c8772008-12-17 01:07:27 +0000510 unsigned NumElts,
511 AttributeList *attrList) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000512 llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
Chris Lattner4d391482007-12-12 07:09:47 +0000513
514 for (unsigned i = 0; i != NumElts; ++i) {
Chris Lattner7caeabd2008-07-21 22:17:28 +0000515 IdentifierInfo *Ident = IdentList[i].first;
Chris Lattnerc8581052008-03-16 20:19:15 +0000516 ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident];
Douglas Gregord0434102009-01-09 00:49:46 +0000517 if (PDecl == 0) { // Not already seen?
518 PDecl = ObjCProtocolDecl::Create(Context, CurContext,
519 IdentList[i].second, Ident);
520 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000521 CurContext->addDecl(Context, PDecl);
Douglas Gregord0434102009-01-09 00:49:46 +0000522 }
Fariborz Jahanianbc1c8772008-12-17 01:07:27 +0000523 if (attrList)
524 ProcessDeclAttributeList(PDecl, attrList);
Chris Lattner4d391482007-12-12 07:09:47 +0000525 Protocols.push_back(PDecl);
526 }
Anders Carlsson15281452008-11-04 16:57:32 +0000527
528 ObjCForwardProtocolDecl *PDecl =
Douglas Gregord0434102009-01-09 00:49:46 +0000529 ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc,
Anders Carlsson15281452008-11-04 16:57:32 +0000530 &Protocols[0], Protocols.size());
Douglas Gregor6ab35242009-04-09 21:40:53 +0000531 CurContext->addDecl(Context, PDecl);
Anders Carlsson15281452008-11-04 16:57:32 +0000532 CheckObjCDeclScope(PDecl);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000533 return DeclPtrTy::make(PDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000534}
535
Chris Lattnerb28317a2009-03-28 19:18:32 +0000536Sema::DeclPtrTy Sema::
Chris Lattner7caeabd2008-07-21 22:17:28 +0000537ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
538 IdentifierInfo *ClassName, SourceLocation ClassLoc,
539 IdentifierInfo *CategoryName,
540 SourceLocation CategoryLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000541 const DeclPtrTy *ProtoRefs,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000542 unsigned NumProtoRefs,
543 SourceLocation EndProtoLoc) {
Chris Lattner61f9d412008-03-16 20:34:23 +0000544 ObjCCategoryDecl *CDecl =
Douglas Gregord0434102009-01-09 00:49:46 +0000545 ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName);
546 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000547 CurContext->addDecl(Context, CDecl);
Chris Lattner70f19542009-02-16 21:26:43 +0000548
549 ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
Fariborz Jahanian7c453b32008-01-17 20:33:24 +0000550 /// Check that class of this category is already completely declared.
Chris Lattner70f19542009-02-16 21:26:43 +0000551 if (!IDecl || IDecl->isForwardDecl()) {
552 CDecl->setInvalidDecl();
Chris Lattner3c73c412008-11-19 08:23:25 +0000553 Diag(ClassLoc, diag::err_undef_interface) << ClassName;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000554 return DeclPtrTy::make(CDecl);
Fariborz Jahanian7c453b32008-01-17 20:33:24 +0000555 }
Chris Lattner4d391482007-12-12 07:09:47 +0000556
Chris Lattner70f19542009-02-16 21:26:43 +0000557 CDecl->setClassInterface(IDecl);
Chris Lattner16b34b42009-02-16 21:30:01 +0000558
559 // If the interface is deprecated, warn about it.
Douglas Gregor48f3bb92009-02-18 21:56:37 +0000560 (void)DiagnoseUseOfDecl(IDecl, ClassLoc);
Chris Lattner70f19542009-02-16 21:26:43 +0000561
562 /// Check for duplicate interface declaration for this category
563 ObjCCategoryDecl *CDeclChain;
564 for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
565 CDeclChain = CDeclChain->getNextClassCategory()) {
566 if (CategoryName && CDeclChain->getIdentifier() == CategoryName) {
567 Diag(CategoryLoc, diag::warn_dup_category_def)
568 << ClassName << CategoryName;
569 Diag(CDeclChain->getLocation(), diag::note_previous_definition);
570 break;
571 }
572 }
573 if (!CDeclChain)
574 CDecl->insertNextClassCategory();
575
Chris Lattner4d391482007-12-12 07:09:47 +0000576 if (NumProtoRefs) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000577 CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,Context);
Chris Lattner6bd6d0b2008-07-26 04:07:02 +0000578 CDecl->setLocEnd(EndProtoLoc);
Chris Lattner4d391482007-12-12 07:09:47 +0000579 }
Anders Carlsson15281452008-11-04 16:57:32 +0000580
581 CheckObjCDeclScope(CDecl);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000582 return DeclPtrTy::make(CDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000583}
584
585/// ActOnStartCategoryImplementation - Perform semantic checks on the
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000586/// category implementation declaration and build an ObjCCategoryImplDecl
Chris Lattner4d391482007-12-12 07:09:47 +0000587/// object.
Chris Lattnerb28317a2009-03-28 19:18:32 +0000588Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
Chris Lattner4d391482007-12-12 07:09:47 +0000589 SourceLocation AtCatImplLoc,
590 IdentifierInfo *ClassName, SourceLocation ClassLoc,
591 IdentifierInfo *CatName, SourceLocation CatLoc) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000592 ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
Chris Lattner75c9cae2008-03-16 20:53:07 +0000593 ObjCCategoryImplDecl *CDecl =
Douglas Gregord0434102009-01-09 00:49:46 +0000594 ObjCCategoryImplDecl::Create(Context, CurContext, AtCatImplLoc, CatName,
595 IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000596 /// Check that class of this category is already completely declared.
597 if (!IDecl || IDecl->isForwardDecl())
Chris Lattner3c73c412008-11-19 08:23:25 +0000598 Diag(ClassLoc, diag::err_undef_interface) << ClassName;
Chris Lattner4d391482007-12-12 07:09:47 +0000599
Douglas Gregord0434102009-01-09 00:49:46 +0000600 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000601 CurContext->addDecl(Context, CDecl);
Douglas Gregord0434102009-01-09 00:49:46 +0000602
Chris Lattner4d391482007-12-12 07:09:47 +0000603 /// TODO: Check that CatName, category name, is not used in another
604 // implementation.
Steve Naroffe84a8642008-09-28 14:55:53 +0000605 ObjCCategoryImpls.push_back(CDecl);
Anders Carlsson15281452008-11-04 16:57:32 +0000606
607 CheckObjCDeclScope(CDecl);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000608 return DeclPtrTy::make(CDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000609}
610
Chris Lattnerb28317a2009-03-28 19:18:32 +0000611Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
Chris Lattner4d391482007-12-12 07:09:47 +0000612 SourceLocation AtClassImplLoc,
613 IdentifierInfo *ClassName, SourceLocation ClassLoc,
614 IdentifierInfo *SuperClassname,
615 SourceLocation SuperClassLoc) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000616 ObjCInterfaceDecl* IDecl = 0;
Chris Lattner4d391482007-12-12 07:09:47 +0000617 // Check for another declaration kind with the same name.
Douglas Gregor47b9a1c2009-02-04 17:27:36 +0000618 NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000619 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner3c73c412008-11-19 08:23:25 +0000620 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Chris Lattner5f4a6822008-11-23 23:12:31 +0000621 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
Chris Lattner1829a6d2009-02-23 22:00:08 +0000622 } else {
Chris Lattner4d391482007-12-12 07:09:47 +0000623 // Is there an interface declaration of this class; if not, warn!
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000624 IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000625 if (!IDecl)
Chris Lattner3c73c412008-11-19 08:23:25 +0000626 Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
Chris Lattner4d391482007-12-12 07:09:47 +0000627 }
628
629 // Check that super class name is valid class name
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000630 ObjCInterfaceDecl* SDecl = 0;
Chris Lattner4d391482007-12-12 07:09:47 +0000631 if (SuperClassname) {
632 // Check if a different kind of symbol declared in this scope.
Douglas Gregor4c921ae2009-01-30 01:04:22 +0000633 PrevDecl = LookupName(TUScope, SuperClassname, LookupOrdinaryName);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000634 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner3c73c412008-11-19 08:23:25 +0000635 Diag(SuperClassLoc, diag::err_redefinition_different_kind)
636 << SuperClassname;
Chris Lattner5f4a6822008-11-23 23:12:31 +0000637 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
Chris Lattner3c73c412008-11-19 08:23:25 +0000638 } else {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000639 SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000640 if (!SDecl)
Chris Lattner3c73c412008-11-19 08:23:25 +0000641 Diag(SuperClassLoc, diag::err_undef_superclass)
642 << SuperClassname << ClassName;
Chris Lattner4d391482007-12-12 07:09:47 +0000643 else if (IDecl && IDecl->getSuperClass() != SDecl) {
644 // This implementation and its interface do not have the same
645 // super class.
Chris Lattner3c73c412008-11-19 08:23:25 +0000646 Diag(SuperClassLoc, diag::err_conflicting_super_class)
Chris Lattner08631c52008-11-23 21:45:46 +0000647 << SDecl->getDeclName();
Chris Lattner5f4a6822008-11-23 23:12:31 +0000648 Diag(SDecl->getLocation(), diag::note_previous_definition);
Chris Lattner4d391482007-12-12 07:09:47 +0000649 }
650 }
651 }
652
653 if (!IDecl) {
654 // Legacy case of @implementation with no corresponding @interface.
655 // Build, chain & install the interface decl into the identifier.
Daniel Dunbarf6414922008-08-20 18:02:42 +0000656
657 // FIXME: Do we support attributes on the @implementation? If so
658 // we should copy them over.
Douglas Gregord0434102009-01-09 00:49:46 +0000659 IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
660 ClassName, ClassLoc, false, true);
Steve Naroff31102512008-04-02 18:30:49 +0000661 ObjCInterfaceDecls[ClassName] = IDecl;
Chris Lattner4d391482007-12-12 07:09:47 +0000662 IDecl->setSuperClass(SDecl);
663 IDecl->setLocEnd(ClassLoc);
664
Douglas Gregord0434102009-01-09 00:49:46 +0000665 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000666 CurContext->addDecl(Context, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000667 // Remember that this needs to be removed when the scope is popped.
Chris Lattnerb28317a2009-03-28 19:18:32 +0000668 TUScope->AddDecl(DeclPtrTy::make(IDecl));
Chris Lattner4d391482007-12-12 07:09:47 +0000669 }
670
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000671 ObjCImplementationDecl* IMPDecl =
Douglas Gregord0434102009-01-09 00:49:46 +0000672 ObjCImplementationDecl::Create(Context, CurContext, AtClassImplLoc,
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000673 IDecl, SDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000674
Douglas Gregord0434102009-01-09 00:49:46 +0000675 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +0000676 CurContext->addDecl(Context, IMPDecl);
Douglas Gregord0434102009-01-09 00:49:46 +0000677
Anders Carlsson15281452008-11-04 16:57:32 +0000678 if (CheckObjCDeclScope(IMPDecl))
Chris Lattnerb28317a2009-03-28 19:18:32 +0000679 return DeclPtrTy::make(IMPDecl);
Anders Carlsson15281452008-11-04 16:57:32 +0000680
Chris Lattner4d391482007-12-12 07:09:47 +0000681 // Check that there is no duplicate implementation of this class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000682 if (ObjCImplementations[ClassName])
Chris Lattner75c9cae2008-03-16 20:53:07 +0000683 // FIXME: Don't leak everything!
Chris Lattner3c73c412008-11-19 08:23:25 +0000684 Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
Chris Lattner4d391482007-12-12 07:09:47 +0000685 else // add it to the list.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000686 ObjCImplementations[ClassName] = IMPDecl;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000687 return DeclPtrTy::make(IMPDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000688}
689
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000690void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
691 ObjCIvarDecl **ivars, unsigned numIvars,
Chris Lattner4d391482007-12-12 07:09:47 +0000692 SourceLocation RBrace) {
693 assert(ImpDecl && "missing implementation decl");
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000694 ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
Chris Lattner4d391482007-12-12 07:09:47 +0000695 if (!IDecl)
696 return;
697 /// Check case of non-existing @interface decl.
698 /// (legacy objective-c @implementation decl without an @interface decl).
699 /// Add implementations's ivar to the synthesize class's ivar list.
700 if (IDecl->ImplicitInterfaceDecl()) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000701 IDecl->setIVarList(ivars, numIvars, Context);
702 IDecl->setLocEnd(RBrace);
Chris Lattner4d391482007-12-12 07:09:47 +0000703 return;
704 }
705 // If implementation has empty ivar list, just return.
706 if (numIvars == 0)
707 return;
708
709 assert(ivars && "missing @implementation ivars");
710
711 // Check interface's Ivar list against those in the implementation.
712 // names and types must match.
713 //
Chris Lattner4d391482007-12-12 07:09:47 +0000714 unsigned j = 0;
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000715 ObjCInterfaceDecl::ivar_iterator
Chris Lattner4c525092007-12-12 17:58:05 +0000716 IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
717 for (; numIvars > 0 && IVI != IVE; ++IVI) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000718 ObjCIvarDecl* ImplIvar = ivars[j++];
719 ObjCIvarDecl* ClsIvar = *IVI;
Chris Lattner4d391482007-12-12 07:09:47 +0000720 assert (ImplIvar && "missing implementation ivar");
721 assert (ClsIvar && "missing class ivar");
Steve Naroffca331292009-03-03 14:49:36 +0000722
723 // First, make sure the types match.
Chris Lattner1b63eef2008-07-27 00:05:05 +0000724 if (Context.getCanonicalType(ImplIvar->getType()) !=
725 Context.getCanonicalType(ClsIvar->getType())) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000726 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
Chris Lattner08631c52008-11-23 21:45:46 +0000727 << ImplIvar->getIdentifier()
728 << ImplIvar->getType() << ClsIvar->getType();
Chris Lattner5f4a6822008-11-23 23:12:31 +0000729 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
Steve Naroffca331292009-03-03 14:49:36 +0000730 } else if (ImplIvar->isBitField() && ClsIvar->isBitField()) {
731 Expr *ImplBitWidth = ImplIvar->getBitWidth();
732 Expr *ClsBitWidth = ClsIvar->getBitWidth();
733 if (ImplBitWidth->getIntegerConstantExprValue(Context).getZExtValue() !=
734 ClsBitWidth->getIntegerConstantExprValue(Context).getZExtValue()) {
735 Diag(ImplBitWidth->getLocStart(), diag::err_conflicting_ivar_bitwidth)
736 << ImplIvar->getIdentifier();
737 Diag(ClsBitWidth->getLocStart(), diag::note_previous_definition);
738 }
739 }
740 // Make sure the names are identical.
741 if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000742 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
Chris Lattner08631c52008-11-23 21:45:46 +0000743 << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
Chris Lattner5f4a6822008-11-23 23:12:31 +0000744 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
Chris Lattner4d391482007-12-12 07:09:47 +0000745 }
746 --numIvars;
Chris Lattner4d391482007-12-12 07:09:47 +0000747 }
Chris Lattner609e4c72007-12-12 18:11:49 +0000748
749 if (numIvars > 0)
Chris Lattner0e391052007-12-12 18:19:52 +0000750 Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
Chris Lattner609e4c72007-12-12 18:11:49 +0000751 else if (IVI != IVE)
Chris Lattner0e391052007-12-12 18:19:52 +0000752 Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
Chris Lattner4d391482007-12-12 07:09:47 +0000753}
754
Steve Naroff3c2eb662008-02-10 21:38:56 +0000755void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
756 bool &IncompleteImpl) {
757 if (!IncompleteImpl) {
758 Diag(ImpLoc, diag::warn_incomplete_impl);
759 IncompleteImpl = true;
760 }
Chris Lattner08631c52008-11-23 21:45:46 +0000761 Diag(ImpLoc, diag::warn_undef_method_impl) << method->getDeclName();
Steve Naroff3c2eb662008-02-10 21:38:56 +0000762}
763
Fariborz Jahanian8daab972008-12-05 18:18:52 +0000764void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
765 ObjCMethodDecl *IntfMethodDecl) {
Chris Lattner5272b7f2009-04-11 18:01:59 +0000766 if (!Context.typesAreCompatible(IntfMethodDecl->getResultType(),
Chris Lattner3aff9192009-04-11 19:58:42 +0000767 ImpMethodDecl->getResultType())) {
768 Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_ret_types)
769 << ImpMethodDecl->getDeclName() << IntfMethodDecl->getResultType()
770 << ImpMethodDecl->getResultType();
Fariborz Jahanian8daab972008-12-05 18:18:52 +0000771 Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition);
772 }
Chris Lattner3aff9192009-04-11 19:58:42 +0000773
774 for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
775 IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
776 IM != EM; ++IM, ++IF) {
777 if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType()))
778 continue;
779
780 Diag((*IM)->getLocation(), diag::warn_conflicting_param_types)
781 << ImpMethodDecl->getDeclName() << (*IF)->getType()
782 << (*IM)->getType();
Chris Lattnerd1e0f5a2009-04-11 20:14:49 +0000783 Diag((*IF)->getLocation(), diag::note_previous_definition);
Chris Lattner3aff9192009-04-11 19:58:42 +0000784 }
Fariborz Jahanian8daab972008-12-05 18:18:52 +0000785}
786
Fariborz Jahaniand1fa6442009-01-12 19:55:42 +0000787/// isPropertyReadonly - Return true if property is readonly, by searching
788/// for the property in the class and in its categories and implementations
789///
790bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
Steve Naroff22dc0b02009-02-26 19:11:32 +0000791 ObjCInterfaceDecl *IDecl) {
Fariborz Jahaniand1fa6442009-01-12 19:55:42 +0000792 // by far the most common case.
793 if (!PDecl->isReadOnly())
794 return false;
795 // Even if property is ready only, if interface has a user defined setter,
796 // it is not considered read only.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000797 if (IDecl->getInstanceMethod(Context, PDecl->getSetterName()))
Fariborz Jahaniand1fa6442009-01-12 19:55:42 +0000798 return false;
799
800 // Main class has the property as 'readonly'. Must search
801 // through the category list to see if the property's
802 // attribute has been over-ridden to 'readwrite'.
803 for (ObjCCategoryDecl *Category = IDecl->getCategoryList();
804 Category; Category = Category->getNextClassCategory()) {
805 // Even if property is ready only, if a category has a user defined setter,
806 // it is not considered read only.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000807 if (Category->getInstanceMethod(Context, PDecl->getSetterName()))
Fariborz Jahaniand1fa6442009-01-12 19:55:42 +0000808 return false;
809 ObjCPropertyDecl *P =
Douglas Gregor6ab35242009-04-09 21:40:53 +0000810 Category->FindPropertyDeclaration(Context, PDecl->getIdentifier());
Fariborz Jahaniand1fa6442009-01-12 19:55:42 +0000811 if (P && !P->isReadOnly())
812 return false;
813 }
814
815 // Also, check for definition of a setter method in the implementation if
816 // all else failed.
817 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
818 if (ObjCImplementationDecl *IMD =
819 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
820 if (IMD->getInstanceMethod(PDecl->getSetterName()))
821 return false;
822 }
823 else if (ObjCCategoryImplDecl *CIMD =
824 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
825 if (CIMD->getInstanceMethod(PDecl->getSetterName()))
826 return false;
827 }
828 }
Steve Naroff22dc0b02009-02-26 19:11:32 +0000829 // Lastly, look through the implementation (if one is in scope).
830 if (ObjCImplementationDecl *ImpDecl =
831 ObjCImplementations[IDecl->getIdentifier()])
832 if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
833 return false;
Fariborz Jahanian50efe042009-04-06 16:59:10 +0000834 // If all fails, look at the super class.
835 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
836 return isPropertyReadonly(PDecl, SIDecl);
Fariborz Jahaniand1fa6442009-01-12 19:55:42 +0000837 return true;
838}
839
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000840/// FIXME: Type hierarchies in Objective-C can be deep. We could most
841/// likely improve the efficiency of selector lookups and type
842/// checking by associating with each protocol / interface / category
843/// the flattened instance tables. If we used an immutable set to keep
844/// the table then it wouldn't add significant memory cost and it
845/// would be handy for lookups.
846
Steve Naroffefe7f362008-02-08 22:06:17 +0000847/// CheckProtocolMethodDefs - This routine checks unimplemented methods
Chris Lattner4d391482007-12-12 07:09:47 +0000848/// Declared in protocol, and those referenced by it.
Steve Naroffefe7f362008-02-08 22:06:17 +0000849void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
850 ObjCProtocolDecl *PDecl,
Chris Lattner4d391482007-12-12 07:09:47 +0000851 bool& IncompleteImpl,
Steve Naroffefe7f362008-02-08 22:06:17 +0000852 const llvm::DenseSet<Selector> &InsMap,
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000853 const llvm::DenseSet<Selector> &ClsMap,
854 ObjCInterfaceDecl *IDecl) {
855 ObjCInterfaceDecl *Super = IDecl->getSuperClass();
856
857 // If a method lookup fails locally we still need to look and see if
858 // the method was implemented by a base class or an inherited
859 // protocol. This lookup is slow, but occurs rarely in correct code
860 // and otherwise would terminate in a warning.
861
Chris Lattner4d391482007-12-12 07:09:47 +0000862 // check unimplemented instance methods.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000863 for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(Context),
864 E = PDecl->instmeth_end(Context); I != E; ++I) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000865 ObjCMethodDecl *method = *I;
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000866 if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
Fariborz Jahaniane793a6e2008-11-24 22:16:00 +0000867 !method->isSynthesized() && !InsMap.count(method->getSelector()) &&
Douglas Gregor6ab35242009-04-09 21:40:53 +0000868 (!Super ||
869 !Super->lookupInstanceMethod(Context, method->getSelector()))) {
Fariborz Jahanianb072b712009-04-03 21:51:32 +0000870 // Ugly, but necessary. Method declared in protcol might have
871 // have been synthesized due to a property declared in the class which
872 // uses the protocol.
873 ObjCMethodDecl *MethodInClass =
Douglas Gregor6ab35242009-04-09 21:40:53 +0000874 IDecl->lookupInstanceMethod(Context, method->getSelector());
Fariborz Jahanianb072b712009-04-03 21:51:32 +0000875 if (!MethodInClass || !MethodInClass->isSynthesized())
876 WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
877 }
Chris Lattner4d391482007-12-12 07:09:47 +0000878 }
879 // check unimplemented class methods
Douglas Gregor6ab35242009-04-09 21:40:53 +0000880 for (ObjCProtocolDecl::classmeth_iterator
881 I = PDecl->classmeth_begin(Context),
882 E = PDecl->classmeth_end(Context);
883 I != E; ++I) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000884 ObjCMethodDecl *method = *I;
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000885 if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
886 !ClsMap.count(method->getSelector()) &&
Douglas Gregor6ab35242009-04-09 21:40:53 +0000887 (!Super || !Super->lookupClassMethod(Context, method->getSelector())))
Steve Naroff3c2eb662008-02-10 21:38:56 +0000888 WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
Steve Naroff58dbdeb2007-12-14 23:37:57 +0000889 }
Chris Lattner780f3292008-07-21 21:32:27 +0000890 // Check on this protocols's referenced protocols, recursively.
891 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
892 E = PDecl->protocol_end(); PI != E; ++PI)
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000893 CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000894}
895
Chris Lattnercddc8882009-03-01 00:56:52 +0000896void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
897 ObjCContainerDecl* CDecl,
898 bool IncompleteImpl) {
Chris Lattner4d391482007-12-12 07:09:47 +0000899 llvm::DenseSet<Selector> InsMap;
900 // Check and see if instance methods in class interface have been
901 // implemented in the implementation class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000902 for (ObjCImplementationDecl::instmeth_iterator I = IMPDecl->instmeth_begin(),
Douglas Gregor6ab35242009-04-09 21:40:53 +0000903 E = IMPDecl->instmeth_end(); I != E; ++I)
Chris Lattner4c525092007-12-12 17:58:05 +0000904 InsMap.insert((*I)->getSelector());
Chris Lattner4d391482007-12-12 07:09:47 +0000905
Douglas Gregor6ab35242009-04-09 21:40:53 +0000906 for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
907 E = CDecl->instmeth_end(Context); I != E; ++I) {
Chris Lattnerbdbde4d2009-02-16 19:25:52 +0000908 if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector())) {
Steve Naroff3c2eb662008-02-10 21:38:56 +0000909 WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
Chris Lattnerbdbde4d2009-02-16 19:25:52 +0000910 continue;
Fariborz Jahaniande739412008-12-05 01:35:25 +0000911 }
Chris Lattnerbdbde4d2009-02-16 19:25:52 +0000912
913 ObjCMethodDecl *ImpMethodDecl =
914 IMPDecl->getInstanceMethod((*I)->getSelector());
915 ObjCMethodDecl *IntfMethodDecl =
Douglas Gregor6ab35242009-04-09 21:40:53 +0000916 CDecl->getInstanceMethod(Context, (*I)->getSelector());
Chris Lattnerbdbde4d2009-02-16 19:25:52 +0000917 assert(IntfMethodDecl &&
918 "IntfMethodDecl is null in ImplMethodsVsClassMethods");
919 // ImpMethodDecl may be null as in a @dynamic property.
920 if (ImpMethodDecl)
921 WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
922 }
Chris Lattner4c525092007-12-12 17:58:05 +0000923
Chris Lattner4d391482007-12-12 07:09:47 +0000924 llvm::DenseSet<Selector> ClsMap;
925 // Check and see if class methods in class interface have been
926 // implemented in the implementation class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000927 for (ObjCImplementationDecl::classmeth_iterator I =IMPDecl->classmeth_begin(),
Chris Lattner4c525092007-12-12 17:58:05 +0000928 E = IMPDecl->classmeth_end(); I != E; ++I)
929 ClsMap.insert((*I)->getSelector());
Chris Lattner4d391482007-12-12 07:09:47 +0000930
Douglas Gregor6ab35242009-04-09 21:40:53 +0000931 for (ObjCInterfaceDecl::classmeth_iterator
932 I = CDecl->classmeth_begin(Context),
933 E = CDecl->classmeth_end(Context);
934 I != E; ++I)
Steve Naroff3c2eb662008-02-10 21:38:56 +0000935 if (!ClsMap.count((*I)->getSelector()))
936 WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
Fariborz Jahanian8daab972008-12-05 18:18:52 +0000937 else {
938 ObjCMethodDecl *ImpMethodDecl =
939 IMPDecl->getClassMethod((*I)->getSelector());
940 ObjCMethodDecl *IntfMethodDecl =
Douglas Gregor6ab35242009-04-09 21:40:53 +0000941 CDecl->getClassMethod(Context, (*I)->getSelector());
Fariborz Jahanian8daab972008-12-05 18:18:52 +0000942 WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
943 }
944
Chris Lattner4d391482007-12-12 07:09:47 +0000945
946 // Check the protocol list for unimplemented methods in the @implementation
947 // class.
Chris Lattnercddc8882009-03-01 00:56:52 +0000948 if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
949 for (ObjCCategoryDecl::protocol_iterator PI = I->protocol_begin(),
950 E = I->protocol_end(); PI != E; ++PI)
951 CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
952 InsMap, ClsMap, I);
953 // Check class extensions (unnamed categories)
954 for (ObjCCategoryDecl *Categories = I->getCategoryList();
955 Categories; Categories = Categories->getNextClassCategory()) {
956 if (!Categories->getIdentifier()) {
957 ImplMethodsVsClassMethods(IMPDecl, Categories, IncompleteImpl);
958 break;
959 }
Fariborz Jahanian8daab972008-12-05 18:18:52 +0000960 }
Chris Lattnercddc8882009-03-01 00:56:52 +0000961 } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
962 for (ObjCCategoryDecl::protocol_iterator PI = C->protocol_begin(),
963 E = C->protocol_end(); PI != E; ++PI)
964 CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
965 InsMap, ClsMap, C->getClassInterface());
966 } else
967 assert(false && "invalid ObjCContainerDecl type.");
Chris Lattner4d391482007-12-12 07:09:47 +0000968}
969
970/// ActOnForwardClassDeclaration -
Chris Lattnerb28317a2009-03-28 19:18:32 +0000971Action::DeclPtrTy
Chris Lattner4d391482007-12-12 07:09:47 +0000972Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
Chris Lattnerbdbde4d2009-02-16 19:25:52 +0000973 IdentifierInfo **IdentList,
974 unsigned NumElts) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000975 llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
Chris Lattner4d391482007-12-12 07:09:47 +0000976
977 for (unsigned i = 0; i != NumElts; ++i) {
978 // Check for another declaration kind with the same name.
Douglas Gregor47b9a1c2009-02-04 17:27:36 +0000979 NamedDecl *PrevDecl = LookupName(TUScope, IdentList[i], LookupOrdinaryName);
Douglas Gregorf57172b2008-12-08 18:40:42 +0000980 if (PrevDecl && PrevDecl->isTemplateParameter()) {
Douglas Gregor72c3f312008-12-05 18:15:24 +0000981 // Maybe we will complain about the shadowed template parameter.
982 DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
983 // Just pretend that we didn't see the previous declaration.
984 PrevDecl = 0;
985 }
986
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000987 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Steve Naroffc7333882008-06-05 22:57:10 +0000988 // GCC apparently allows the following idiom:
989 //
990 // typedef NSObject < XCElementTogglerP > XCElementToggler;
991 // @class XCElementToggler;
992 //
993 // FIXME: Make an extension?
994 TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
995 if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
Chris Lattner3c73c412008-11-19 08:23:25 +0000996 Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
Chris Lattner5f4a6822008-11-23 23:12:31 +0000997 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
Steve Naroffc7333882008-06-05 22:57:10 +0000998 }
Chris Lattner4d391482007-12-12 07:09:47 +0000999 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001000 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +00001001 if (!IDecl) { // Not already seen? Make a forward decl.
Douglas Gregord0434102009-01-09 00:49:46 +00001002 IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
1003 IdentList[i], SourceLocation(), true);
Steve Naroff31102512008-04-02 18:30:49 +00001004 ObjCInterfaceDecls[IdentList[i]] = IDecl;
Chris Lattner4d391482007-12-12 07:09:47 +00001005
Douglas Gregord0434102009-01-09 00:49:46 +00001006 // FIXME: PushOnScopeChains?
Douglas Gregor6ab35242009-04-09 21:40:53 +00001007 CurContext->addDecl(Context, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +00001008 // Remember that this needs to be removed when the scope is popped.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001009 TUScope->AddDecl(DeclPtrTy::make(IDecl));
Chris Lattner4d391482007-12-12 07:09:47 +00001010 }
1011
1012 Interfaces.push_back(IDecl);
1013 }
1014
Douglas Gregord0434102009-01-09 00:49:46 +00001015 ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
Anders Carlsson15281452008-11-04 16:57:32 +00001016 &Interfaces[0],
1017 Interfaces.size());
Douglas Gregor6ab35242009-04-09 21:40:53 +00001018 CurContext->addDecl(Context, CDecl);
Anders Carlsson15281452008-11-04 16:57:32 +00001019 CheckObjCDeclScope(CDecl);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001020 return DeclPtrTy::make(CDecl);
Chris Lattner4d391482007-12-12 07:09:47 +00001021}
1022
1023
1024/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
1025/// returns true, or false, accordingly.
1026/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001027bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
Steve Narofffe6b0dc2008-10-21 10:37:50 +00001028 const ObjCMethodDecl *PrevMethod,
1029 bool matchBasedOnSizeAndAlignment) {
1030 QualType T1 = Context.getCanonicalType(Method->getResultType());
1031 QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
1032
1033 if (T1 != T2) {
1034 // The result types are different.
1035 if (!matchBasedOnSizeAndAlignment)
Chris Lattner4d391482007-12-12 07:09:47 +00001036 return false;
Steve Narofffe6b0dc2008-10-21 10:37:50 +00001037 // Incomplete types don't have a size and alignment.
1038 if (T1->isIncompleteType() || T2->isIncompleteType())
1039 return false;
1040 // Check is based on size and alignment.
1041 if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
1042 return false;
1043 }
Chris Lattner89951a82009-02-20 18:43:26 +00001044
1045 ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
1046 E = Method->param_end();
1047 ObjCMethodDecl::param_iterator PrevI = PrevMethod->param_begin();
1048
1049 for (; ParamI != E; ++ParamI, ++PrevI) {
1050 assert(PrevI != PrevMethod->param_end() && "Param mismatch");
1051 T1 = Context.getCanonicalType((*ParamI)->getType());
1052 T2 = Context.getCanonicalType((*PrevI)->getType());
Steve Narofffe6b0dc2008-10-21 10:37:50 +00001053 if (T1 != T2) {
1054 // The result types are different.
1055 if (!matchBasedOnSizeAndAlignment)
1056 return false;
1057 // Incomplete types don't have a size and alignment.
1058 if (T1->isIncompleteType() || T2->isIncompleteType())
1059 return false;
1060 // Check is based on size and alignment.
1061 if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
1062 return false;
1063 }
Chris Lattner4d391482007-12-12 07:09:47 +00001064 }
1065 return true;
1066}
1067
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001068void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
Chris Lattnerb25df352009-03-04 05:16:45 +00001069 ObjCMethodList &Entry = InstanceMethodPool[Method->getSelector()];
1070 if (Entry.Method == 0) {
Chris Lattner4d391482007-12-12 07:09:47 +00001071 // Haven't seen a method with this selector name yet - add it.
Chris Lattnerb25df352009-03-04 05:16:45 +00001072 Entry.Method = Method;
1073 Entry.Next = 0;
1074 return;
Chris Lattner4d391482007-12-12 07:09:47 +00001075 }
Chris Lattnerb25df352009-03-04 05:16:45 +00001076
1077 // We've seen a method with this name, see if we have already seen this type
1078 // signature.
1079 for (ObjCMethodList *List = &Entry; List; List = List->Next)
1080 if (MatchTwoMethodDeclarations(Method, List->Method))
1081 return;
1082
1083 // We have a new signature for an existing method - add it.
1084 // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
1085 Entry.Next = new ObjCMethodList(Method, Entry.Next);
Chris Lattner4d391482007-12-12 07:09:47 +00001086}
1087
Steve Naroff6f5f41c2008-10-21 10:50:19 +00001088// FIXME: Finish implementing -Wno-strict-selector-match.
Steve Naroff037cda52008-09-30 14:38:43 +00001089ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
1090 SourceRange R) {
1091 ObjCMethodList &MethList = InstanceMethodPool[Sel];
Steve Narofffe6b0dc2008-10-21 10:37:50 +00001092 bool issueWarning = false;
Steve Naroff037cda52008-09-30 14:38:43 +00001093
1094 if (MethList.Method && MethList.Next) {
Steve Narofffe6b0dc2008-10-21 10:37:50 +00001095 for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
1096 // This checks if the methods differ by size & alignment.
1097 if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
1098 issueWarning = true;
1099 }
1100 if (issueWarning && (MethList.Method && MethList.Next)) {
Chris Lattner077bf5e2008-11-24 03:33:13 +00001101 Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
Chris Lattner1326a3d2008-11-23 23:26:13 +00001102 Diag(MethList.Method->getLocStart(), diag::note_using_decl)
Chris Lattnerdcd5ef12008-11-19 05:27:50 +00001103 << MethList.Method->getSourceRange();
Steve Naroff037cda52008-09-30 14:38:43 +00001104 for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
Chris Lattner1326a3d2008-11-23 23:26:13 +00001105 Diag(Next->Method->getLocStart(), diag::note_also_found_decl)
Chris Lattnerdcd5ef12008-11-19 05:27:50 +00001106 << Next->Method->getSourceRange();
Steve Naroff037cda52008-09-30 14:38:43 +00001107 }
1108 return MethList.Method;
1109}
1110
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001111void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
1112 ObjCMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +00001113 if (!FirstMethod.Method) {
1114 // Haven't seen a method with this selector name yet - add it.
1115 FirstMethod.Method = Method;
1116 FirstMethod.Next = 0;
1117 } else {
1118 // We've seen a method with this name, now check the type signature(s).
1119 bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
1120
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001121 for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
Chris Lattner4d391482007-12-12 07:09:47 +00001122 Next = Next->Next)
1123 match = MatchTwoMethodDeclarations(Method, Next->Method);
1124
1125 if (!match) {
1126 // We have a new signature for an existing method - add it.
1127 // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001128 struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
Chris Lattner4d391482007-12-12 07:09:47 +00001129 FirstMethod.Next = OMI;
1130 }
1131 }
1132}
1133
Steve Naroff0701bbb2009-01-08 17:28:14 +00001134/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
1135/// have the property type and issue diagnostics if they don't.
1136/// Also synthesize a getter/setter method if none exist (and update the
1137/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
1138/// methods is the "right" thing to do.
1139void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
1140 ObjCContainerDecl *CD) {
1141 ObjCMethodDecl *GetterMethod, *SetterMethod;
1142
Douglas Gregor6ab35242009-04-09 21:40:53 +00001143 GetterMethod = CD->getInstanceMethod(Context, property->getGetterName());
1144 SetterMethod = CD->getInstanceMethod(Context, property->getSetterName());
Steve Naroff0701bbb2009-01-08 17:28:14 +00001145
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001146 if (GetterMethod &&
Fariborz Jahanian196d0ed2008-12-06 21:48:16 +00001147 GetterMethod->getResultType() != property->getType()) {
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001148 Diag(property->getLocation(),
1149 diag::err_accessor_property_type_mismatch)
1150 << property->getDeclName()
Ted Kremenek8af2c162009-03-14 00:20:08 +00001151 << GetterMethod->getSelector();
Fariborz Jahanian196d0ed2008-12-06 21:48:16 +00001152 Diag(GetterMethod->getLocation(), diag::note_declared_at);
1153 }
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001154
1155 if (SetterMethod) {
Fariborz Jahanian5dd41292008-12-06 23:12:49 +00001156 if (Context.getCanonicalType(SetterMethod->getResultType())
1157 != Context.VoidTy)
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001158 Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
Chris Lattner89951a82009-02-20 18:43:26 +00001159 if (SetterMethod->param_size() != 1 ||
1160 ((*SetterMethod->param_begin())->getType() != property->getType())) {
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001161 Diag(property->getLocation(),
1162 diag::err_accessor_property_type_mismatch)
1163 << property->getDeclName()
Ted Kremenek8af2c162009-03-14 00:20:08 +00001164 << SetterMethod->getSelector();
Fariborz Jahanian196d0ed2008-12-06 21:48:16 +00001165 Diag(SetterMethod->getLocation(), diag::note_declared_at);
1166 }
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001167 }
Steve Naroff0701bbb2009-01-08 17:28:14 +00001168
1169 // Synthesize getter/setter methods if none exist.
Steve Naroff92f863b2009-01-08 20:15:03 +00001170 // Find the default getter and if one not found, add one.
Steve Naroff4fb78c62009-01-08 20:17:34 +00001171 // FIXME: The synthesized property we set here is misleading. We
1172 // almost always synthesize these methods unless the user explicitly
1173 // provided prototypes (which is odd, but allowed). Sema should be
1174 // typechecking that the declarations jive in that situation (which
1175 // it is not currently).
Steve Naroff92f863b2009-01-08 20:15:03 +00001176 if (!GetterMethod) {
1177 // No instance method of same name as property getter name was found.
1178 // Declare a getter method and add it to the list of methods
1179 // for this class.
1180 GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
1181 property->getLocation(), property->getGetterName(),
1182 property->getType(), CD, true, false, true,
1183 (property->getPropertyImplementation() ==
1184 ObjCPropertyDecl::Optional) ?
1185 ObjCMethodDecl::Optional :
1186 ObjCMethodDecl::Required);
Douglas Gregor6ab35242009-04-09 21:40:53 +00001187 CD->addDecl(Context, GetterMethod);
Steve Naroff92f863b2009-01-08 20:15:03 +00001188 } else
1189 // A user declared getter will be synthesize when @synthesize of
1190 // the property with the same name is seen in the @implementation
1191 GetterMethod->setIsSynthesized();
1192 property->setGetterMethodDecl(GetterMethod);
1193
1194 // Skip setter if property is read-only.
1195 if (!property->isReadOnly()) {
1196 // Find the default setter and if one not found, add one.
1197 if (!SetterMethod) {
1198 // No instance method of same name as property setter name was found.
1199 // Declare a setter method and add it to the list of methods
1200 // for this class.
1201 SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
1202 property->getLocation(),
1203 property->getSetterName(),
1204 Context.VoidTy, CD, true, false, true,
1205 (property->getPropertyImplementation() ==
1206 ObjCPropertyDecl::Optional) ?
1207 ObjCMethodDecl::Optional :
1208 ObjCMethodDecl::Required);
1209 // Invent the arguments for the setter. We don't bother making a
1210 // nice name for the argument.
1211 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
Chris Lattnerd1e0f5a2009-04-11 20:14:49 +00001212 property->getLocation(),
Steve Naroff92f863b2009-01-08 20:15:03 +00001213 property->getIdentifier(),
1214 property->getType(),
1215 VarDecl::None,
Douglas Gregor4afa39d2009-01-20 01:17:11 +00001216 0);
Chris Lattner38af2de2009-02-20 21:35:13 +00001217 SetterMethod->setMethodParams(&Argument, 1, Context);
Douglas Gregor6ab35242009-04-09 21:40:53 +00001218 CD->addDecl(Context, SetterMethod);
Steve Naroff92f863b2009-01-08 20:15:03 +00001219 } else
1220 // A user declared setter will be synthesize when @synthesize of
1221 // the property with the same name is seen in the @implementation
1222 SetterMethod->setIsSynthesized();
1223 property->setSetterMethodDecl(SetterMethod);
1224 }
Steve Naroff0701bbb2009-01-08 17:28:14 +00001225 // Add any synthesized methods to the global pool. This allows us to
1226 // handle the following, which is supported by GCC (and part of the design).
1227 //
1228 // @interface Foo
1229 // @property double bar;
1230 // @end
1231 //
1232 // void thisIsUnfortunate() {
1233 // id foo;
1234 // double bar = [foo bar];
1235 // }
1236 //
Douglas Gregor6037fcb2009-01-09 19:42:16 +00001237 if (GetterMethod)
Steve Naroff0701bbb2009-01-08 17:28:14 +00001238 AddInstanceMethodToGlobalPool(GetterMethod);
Douglas Gregor6037fcb2009-01-09 19:42:16 +00001239 if (SetterMethod)
Steve Naroff0701bbb2009-01-08 17:28:14 +00001240 AddInstanceMethodToGlobalPool(SetterMethod);
Fariborz Jahanianf3cd3fd2008-12-02 18:39:49 +00001241}
1242
Steve Naroffa56f6162007-12-18 01:30:32 +00001243// Note: For class/category implemenations, allMethods/allProperties is
1244// always null.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001245void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
1246 DeclPtrTy *allMethods, unsigned allNum,
1247 DeclPtrTy *allProperties, unsigned pNum,
Chris Lattner682bf922009-03-29 16:50:03 +00001248 DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
Chris Lattnerb28317a2009-03-28 19:18:32 +00001249 Decl *ClassDecl = classDecl.getAs<Decl>();
Chris Lattner4d391482007-12-12 07:09:47 +00001250
Steve Naroffa56f6162007-12-18 01:30:32 +00001251 // FIXME: If we don't have a ClassDecl, we have an error. We should consider
1252 // always passing in a decl. If the decl has an error, isInvalidDecl()
Chris Lattner4d391482007-12-12 07:09:47 +00001253 // should be true.
1254 if (!ClassDecl)
1255 return;
1256
Chris Lattner4d391482007-12-12 07:09:47 +00001257 bool isInterfaceDeclKind =
Chris Lattnerf8d17a52008-03-16 21:17:37 +00001258 isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
1259 || isa<ObjCProtocolDecl>(ClassDecl);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001260 bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
Steve Naroff09c47192009-01-09 15:36:25 +00001261
Steve Naroff0701bbb2009-01-08 17:28:14 +00001262 DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
Steve Naroff0701bbb2009-01-08 17:28:14 +00001263
1264 // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
1265 llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
1266 llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
1267
Chris Lattner4d391482007-12-12 07:09:47 +00001268 for (unsigned i = 0; i < allNum; i++ ) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001269 ObjCMethodDecl *Method =
Chris Lattnerb28317a2009-03-28 19:18:32 +00001270 cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
Chris Lattner4d391482007-12-12 07:09:47 +00001271
1272 if (!Method) continue; // Already issued a diagnostic.
Douglas Gregorf8d49f62009-01-09 17:18:27 +00001273 if (Method->isInstanceMethod()) {
Chris Lattner4d391482007-12-12 07:09:47 +00001274 /// Check for instance method of the same name with incompatible types
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001275 const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +00001276 bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
1277 : false;
Eli Friedman82b4e762008-12-16 20:15:50 +00001278 if ((isInterfaceDeclKind && PrevMethod && !match)
1279 || (checkIdenticalMethods && match)) {
Chris Lattner5f4a6822008-11-23 23:12:31 +00001280 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
Chris Lattner077bf5e2008-11-24 03:33:13 +00001281 << Method->getDeclName();
Chris Lattner5f4a6822008-11-23 23:12:31 +00001282 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
Chris Lattner4d391482007-12-12 07:09:47 +00001283 } else {
Douglas Gregor6ab35242009-04-09 21:40:53 +00001284 DC->addDecl(Context, Method);
Chris Lattner4d391482007-12-12 07:09:47 +00001285 InsMap[Method->getSelector()] = Method;
1286 /// The following allows us to typecheck messages to "id".
1287 AddInstanceMethodToGlobalPool(Method);
1288 }
1289 }
1290 else {
1291 /// Check for class method of the same name with incompatible types
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001292 const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +00001293 bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
1294 : false;
Eli Friedman82b4e762008-12-16 20:15:50 +00001295 if ((isInterfaceDeclKind && PrevMethod && !match)
1296 || (checkIdenticalMethods && match)) {
Chris Lattner5f4a6822008-11-23 23:12:31 +00001297 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
Chris Lattner077bf5e2008-11-24 03:33:13 +00001298 << Method->getDeclName();
Chris Lattner5f4a6822008-11-23 23:12:31 +00001299 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
Chris Lattner4d391482007-12-12 07:09:47 +00001300 } else {
Douglas Gregor6ab35242009-04-09 21:40:53 +00001301 DC->addDecl(Context, Method);
Chris Lattner4d391482007-12-12 07:09:47 +00001302 ClsMap[Method->getSelector()] = Method;
Steve Naroffa56f6162007-12-18 01:30:32 +00001303 /// The following allows us to typecheck messages to "Class".
1304 AddFactoryMethodToGlobalPool(Method);
Chris Lattner4d391482007-12-12 07:09:47 +00001305 }
1306 }
1307 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001308 if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +00001309 // Compares properties declared in this class to those of its
Fariborz Jahanian02edb982008-05-01 00:03:38 +00001310 // super class.
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +00001311 ComparePropertiesInBaseAndSuper(I);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001312 MergeProtocolPropertiesIntoClass(I, DeclPtrTy::make(I));
Steve Naroff09c47192009-01-09 15:36:25 +00001313 } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
Fariborz Jahanian77e14bd2008-12-06 19:59:02 +00001314 // Categories are used to extend the class by declaring new methods.
1315 // By the same token, they are also used to add new properties. No
1316 // need to compare the added property to those in the class.
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +00001317
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +00001318 // Merge protocol properties into category
Chris Lattnerb28317a2009-03-28 19:18:32 +00001319 MergeProtocolPropertiesIntoClass(C, DeclPtrTy::make(C));
Fariborz Jahanianb7f95f52009-03-02 19:05:07 +00001320 if (C->getIdentifier() == 0)
1321 DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
Chris Lattner4d391482007-12-12 07:09:47 +00001322 }
Steve Naroff09c47192009-01-09 15:36:25 +00001323 if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
1324 // ProcessPropertyDecl is responsible for diagnosing conflicts with any
1325 // user-defined setter/getter. It also synthesizes setter/getter methods
1326 // and adds them to the DeclContext and global method pools.
Douglas Gregor6ab35242009-04-09 21:40:53 +00001327 for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(Context),
1328 E = CDecl->prop_end(Context);
1329 I != E; ++I)
Chris Lattner97a58872009-02-16 18:32:47 +00001330 ProcessPropertyDecl(*I, CDecl);
Steve Naroff09c47192009-01-09 15:36:25 +00001331 CDecl->setAtEndLoc(AtEndLoc);
1332 }
1333 if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +00001334 IC->setLocEnd(AtEndLoc);
Douglas Gregor4afa39d2009-01-20 01:17:11 +00001335 if (ObjCInterfaceDecl* IDecl = IC->getClassInterface())
Chris Lattner4d391482007-12-12 07:09:47 +00001336 ImplMethodsVsClassMethods(IC, IDecl);
Steve Naroff09c47192009-01-09 15:36:25 +00001337 } else if (ObjCCategoryImplDecl* CatImplClass =
1338 dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +00001339 CatImplClass->setLocEnd(AtEndLoc);
Chris Lattner97a58872009-02-16 18:32:47 +00001340
Chris Lattner4d391482007-12-12 07:09:47 +00001341 // Find category interface decl and then check that all methods declared
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +00001342 // in this interface are implemented in the category @implementation.
Chris Lattner97a58872009-02-16 18:32:47 +00001343 if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001344 for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
Chris Lattner4d391482007-12-12 07:09:47 +00001345 Categories; Categories = Categories->getNextClassCategory()) {
1346 if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
Chris Lattnercddc8882009-03-01 00:56:52 +00001347 ImplMethodsVsClassMethods(CatImplClass, Categories);
Chris Lattner4d391482007-12-12 07:09:47 +00001348 break;
1349 }
1350 }
1351 }
1352 }
Chris Lattner682bf922009-03-29 16:50:03 +00001353 if (isInterfaceDeclKind) {
1354 // Reject invalid vardecls.
1355 for (unsigned i = 0; i != tuvNum; i++) {
1356 DeclGroupRef DG = allTUVars[i].getAsVal<DeclGroupRef>();
1357 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
1358 if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
1359 if (VDecl->getStorageClass() != VarDecl::Extern &&
1360 VDecl->getStorageClass() != VarDecl::PrivateExtern)
1361 Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass)
Ted Kremenek5a112952009-04-10 18:25:37 +00001362 << cast<NamedDecl>(ClassDecl)->getDeclName();
Fariborz Jahanianb31cb7f2009-03-21 18:06:45 +00001363 }
Chris Lattner682bf922009-03-29 16:50:03 +00001364 }
Fariborz Jahanian38e24c72009-03-18 22:33:24 +00001365 }
Chris Lattner4d391482007-12-12 07:09:47 +00001366}
1367
1368
1369/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
1370/// objective-c's type qualifier from the parser version of the same info.
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001371static Decl::ObjCDeclQualifier
1372CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
1373 Decl::ObjCDeclQualifier ret = Decl::OBJC_TQ_None;
1374 if (PQTVal & ObjCDeclSpec::DQ_In)
1375 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_In);
1376 if (PQTVal & ObjCDeclSpec::DQ_Inout)
1377 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
1378 if (PQTVal & ObjCDeclSpec::DQ_Out)
1379 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Out);
1380 if (PQTVal & ObjCDeclSpec::DQ_Bycopy)
1381 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
1382 if (PQTVal & ObjCDeclSpec::DQ_Byref)
1383 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
1384 if (PQTVal & ObjCDeclSpec::DQ_Oneway)
1385 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
Chris Lattner4d391482007-12-12 07:09:47 +00001386
1387 return ret;
1388}
1389
Chris Lattnerb28317a2009-03-28 19:18:32 +00001390Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
Chris Lattner4d391482007-12-12 07:09:47 +00001391 SourceLocation MethodLoc, SourceLocation EndLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +00001392 tok::TokenKind MethodType, DeclPtrTy classDecl,
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001393 ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
Chris Lattner4d391482007-12-12 07:09:47 +00001394 Selector Sel,
1395 // optional arguments. The number of types/arguments is obtained
1396 // from the Sel.getNumArgs().
Chris Lattnere294d3f2009-04-11 18:57:04 +00001397 ObjCArgInfo *ArgInfo,
Fariborz Jahanian439c6582009-01-09 00:38:19 +00001398 llvm::SmallVectorImpl<Declarator> &Cdecls,
Chris Lattner4d391482007-12-12 07:09:47 +00001399 AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
1400 bool isVariadic) {
Chris Lattnerb28317a2009-03-28 19:18:32 +00001401 Decl *ClassDecl = classDecl.getAs<Decl>();
Steve Naroffda323ad2008-02-29 21:48:07 +00001402
1403 // Make sure we can establish a context for the method.
1404 if (!ClassDecl) {
1405 Diag(MethodLoc, diag::error_missing_method_context);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001406 return DeclPtrTy();
Steve Naroffda323ad2008-02-29 21:48:07 +00001407 }
Chris Lattner4d391482007-12-12 07:09:47 +00001408 QualType resultDeclType;
1409
Steve Naroffccef3712009-02-20 22:59:16 +00001410 if (ReturnType) {
Chris Lattner4d391482007-12-12 07:09:47 +00001411 resultDeclType = QualType::getFromOpaquePtr(ReturnType);
Steve Naroffccef3712009-02-20 22:59:16 +00001412
1413 // Methods cannot return interface types. All ObjC objects are
1414 // passed by reference.
1415 if (resultDeclType->isObjCInterfaceType()) {
Chris Lattner2dd979f2009-04-11 19:08:56 +00001416 Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
1417 << 0 << resultDeclType;
Chris Lattnerb28317a2009-03-28 19:18:32 +00001418 return DeclPtrTy();
Steve Naroffccef3712009-02-20 22:59:16 +00001419 }
1420 } else // get the type for "id".
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001421 resultDeclType = Context.getObjCIdType();
Chris Lattner4d391482007-12-12 07:09:47 +00001422
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001423 ObjCMethodDecl* ObjCMethod =
1424 ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
Chris Lattner32d3f9c2009-03-29 04:30:19 +00001425 cast<DeclContext>(ClassDecl),
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001426 MethodType == tok::minus, isVariadic,
Fariborz Jahanian46070342008-05-07 20:53:44 +00001427 false,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001428 MethodDeclKind == tok::objc_optional ?
1429 ObjCMethodDecl::Optional :
1430 ObjCMethodDecl::Required);
1431
Chris Lattner0ed844b2008-04-04 06:12:32 +00001432 llvm::SmallVector<ParmVarDecl*, 16> Params;
1433
Chris Lattner7db638d2009-04-11 19:42:43 +00001434 for (unsigned i = 0, e = Sel.getNumArgs(); i != e; ++i) {
Chris Lattner2dd979f2009-04-11 19:08:56 +00001435 QualType ArgType, UnpromotedArgType;
Chris Lattner0ed844b2008-04-04 06:12:32 +00001436
Chris Lattnere294d3f2009-04-11 18:57:04 +00001437 if (ArgInfo[i].Type == 0) {
Chris Lattner2dd979f2009-04-11 19:08:56 +00001438 UnpromotedArgType = ArgType = Context.getObjCIdType();
Chris Lattnere294d3f2009-04-11 18:57:04 +00001439 } else {
Chris Lattner2dd979f2009-04-11 19:08:56 +00001440 UnpromotedArgType = ArgType = QualType::getFromOpaquePtr(ArgInfo[i].Type);
Steve Naroff6082c622008-12-09 19:36:17 +00001441 // Perform the default array/function conversions (C99 6.7.5.3p[7,8]).
Chris Lattnerf97e8fa2009-04-11 19:34:56 +00001442 ArgType = adjustParameterType(ArgType);
Chris Lattnere294d3f2009-04-11 18:57:04 +00001443 }
1444
Fariborz Jahanian4306d3c2008-12-20 23:29:59 +00001445 ParmVarDecl* Param;
Chris Lattner2dd979f2009-04-11 19:08:56 +00001446 if (ArgType == UnpromotedArgType)
Chris Lattner7db638d2009-04-11 19:42:43 +00001447 Param = ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
Chris Lattner2dd979f2009-04-11 19:08:56 +00001448 ArgInfo[i].Name, ArgType,
Douglas Gregor4afa39d2009-01-20 01:17:11 +00001449 VarDecl::None, 0);
Fariborz Jahanian4306d3c2008-12-20 23:29:59 +00001450 else
Douglas Gregor64650af2009-02-02 23:39:07 +00001451 Param = OriginalParmVarDecl::Create(Context, ObjCMethod,
Chris Lattner7db638d2009-04-11 19:42:43 +00001452 ArgInfo[i].NameLoc,
Chris Lattner2dd979f2009-04-11 19:08:56 +00001453 ArgInfo[i].Name, ArgType,
1454 UnpromotedArgType,
Douglas Gregor64650af2009-02-02 23:39:07 +00001455 VarDecl::None, 0);
Fariborz Jahanian4306d3c2008-12-20 23:29:59 +00001456
Chris Lattnerf97e8fa2009-04-11 19:34:56 +00001457 if (ArgType->isObjCInterfaceType()) {
1458 Diag(ArgInfo[i].NameLoc,
1459 diag::err_object_cannot_be_passed_returned_by_value)
1460 << 1 << ArgType;
1461 Param->setInvalidDecl();
1462 }
1463
Chris Lattner0ed844b2008-04-04 06:12:32 +00001464 Param->setObjCDeclQualifier(
Chris Lattnere294d3f2009-04-11 18:57:04 +00001465 CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
Chris Lattnerf97e8fa2009-04-11 19:34:56 +00001466
1467 // Apply the attributes to the parameter.
1468 ProcessDeclAttributeList(Param, ArgInfo[i].ArgAttrs);
1469
Chris Lattner0ed844b2008-04-04 06:12:32 +00001470 Params.push_back(Param);
1471 }
1472
Chris Lattner38af2de2009-02-20 21:35:13 +00001473 ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs(), Context);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001474 ObjCMethod->setObjCDeclQualifier(
1475 CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
1476 const ObjCMethodDecl *PrevMethod = 0;
Daniel Dunbar35682492008-09-26 04:12:28 +00001477
1478 if (AttrList)
1479 ProcessDeclAttributeList(ObjCMethod, AttrList);
Chris Lattner4d391482007-12-12 07:09:47 +00001480
1481 // For implementations (which can be very "coarse grain"), we add the
1482 // method now. This allows the AST to implement lookup methods that work
1483 // incrementally (without waiting until we parse the @end). It also allows
1484 // us to flag multiple declaration errors as they occur.
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001485 if (ObjCImplementationDecl *ImpDecl =
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001486 dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +00001487 if (MethodType == tok::minus) {
Steve Naroff94a5c332007-12-19 22:27:04 +00001488 PrevMethod = ImpDecl->getInstanceMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001489 ImpDecl->addInstanceMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001490 } else {
Steve Naroff94a5c332007-12-19 22:27:04 +00001491 PrevMethod = ImpDecl->getClassMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001492 ImpDecl->addClassMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001493 }
1494 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001495 else if (ObjCCategoryImplDecl *CatImpDecl =
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001496 dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +00001497 if (MethodType == tok::minus) {
Steve Naroff94a5c332007-12-19 22:27:04 +00001498 PrevMethod = CatImpDecl->getInstanceMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001499 CatImpDecl->addInstanceMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001500 } else {
Steve Naroff94a5c332007-12-19 22:27:04 +00001501 PrevMethod = CatImpDecl->getClassMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001502 CatImpDecl->addClassMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001503 }
1504 }
1505 if (PrevMethod) {
1506 // You can never have two method definitions with the same name.
Chris Lattner5f4a6822008-11-23 23:12:31 +00001507 Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
Chris Lattner077bf5e2008-11-24 03:33:13 +00001508 << ObjCMethod->getDeclName();
Chris Lattner5f4a6822008-11-23 23:12:31 +00001509 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
Chris Lattner4d391482007-12-12 07:09:47 +00001510 }
Chris Lattnerb28317a2009-03-28 19:18:32 +00001511 return DeclPtrTy::make(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001512}
1513
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001514void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
1515 SourceLocation Loc,
1516 unsigned &Attributes) {
1517 // FIXME: Improve the reported location.
1518
Fariborz Jahanian567c8df2008-12-06 01:12:43 +00001519 // readonly and readwrite/assign/retain/copy conflict.
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001520 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
Fariborz Jahanian567c8df2008-12-06 01:12:43 +00001521 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
1522 ObjCDeclSpec::DQ_PR_assign |
1523 ObjCDeclSpec::DQ_PR_copy |
1524 ObjCDeclSpec::DQ_PR_retain))) {
1525 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ?
1526 "readwrite" :
1527 (Attributes & ObjCDeclSpec::DQ_PR_assign) ?
1528 "assign" :
1529 (Attributes & ObjCDeclSpec::DQ_PR_copy) ?
1530 "copy" : "retain";
1531
Fariborz Jahanianba45da82008-12-08 19:28:10 +00001532 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ?
Chris Lattner28372fa2009-01-29 18:49:48 +00001533 diag::err_objc_property_attr_mutually_exclusive :
1534 diag::warn_objc_property_attr_mutually_exclusive)
Fariborz Jahanian567c8df2008-12-06 01:12:43 +00001535 << "readonly" << which;
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001536 }
1537
1538 // Check for copy or retain on non-object types.
1539 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
1540 !Context.isObjCObjectPointerType(PropertyTy)) {
Chris Lattner5dc266a2008-11-20 06:13:02 +00001541 Diag(Loc, diag::err_objc_property_requires_object)
1542 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001543 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
1544 }
1545
1546 // Check for more than one of { assign, copy, retain }.
1547 if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
1548 if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
Chris Lattner5dc266a2008-11-20 06:13:02 +00001549 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1550 << "assign" << "copy";
1551 Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001552 }
1553 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
Chris Lattner5dc266a2008-11-20 06:13:02 +00001554 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1555 << "assign" << "retain";
1556 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001557 }
1558 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1559 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
Chris Lattner5dc266a2008-11-20 06:13:02 +00001560 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1561 << "copy" << "retain";
1562 Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001563 }
1564 }
1565
1566 // Warn if user supplied no assignment attribute, property is
1567 // readwrite, and this is an object type.
1568 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
1569 ObjCDeclSpec::DQ_PR_retain)) &&
1570 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1571 Context.isObjCObjectPointerType(PropertyTy)) {
1572 // Skip this warning in gc-only mode.
1573 if (getLangOptions().getGCMode() != LangOptions::GCOnly)
1574 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
1575
1576 // If non-gc code warn that this is likely inappropriate.
1577 if (getLangOptions().getGCMode() == LangOptions::NonGC)
1578 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
1579
1580 // FIXME: Implement warning dependent on NSCopying being
1581 // implemented. See also:
1582 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
1583 // (please trim this list while you are at it).
1584 }
1585}
1586
Chris Lattnerb28317a2009-03-28 19:18:32 +00001587Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
1588 FieldDeclarator &FD,
1589 ObjCDeclSpec &ODS,
1590 Selector GetterSel,
1591 Selector SetterSel,
1592 DeclPtrTy ClassCategory,
1593 bool *isOverridingProperty,
1594 tok::ObjCKeywordKind MethodImplKind) {
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001595 unsigned Attributes = ODS.getPropertyAttributes();
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001596 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
1597 // default is readwrite!
1598 !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
1599 // property is defaulted to 'assign' if it is readwrite and is
1600 // not retain or copy
1601 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
1602 (isReadWrite &&
1603 !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
1604 !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
1605 QualType T = GetTypeForDeclarator(FD.D, S);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001606 Decl *ClassDecl = ClassCategory.getAs<Decl>();
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001607 ObjCInterfaceDecl *CCPrimary = 0; // continuation class's primary class
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001608 // May modify Attributes.
1609 CheckObjCPropertyAttributes(T, AtLoc, Attributes);
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001610 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
1611 if (!CDecl->getIdentifier()) {
Fariborz Jahanian22b6e062009-04-01 23:23:53 +00001612 // This is a continuation class. property requires special
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001613 // handling.
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001614 if ((CCPrimary = CDecl->getClassInterface())) {
1615 // Find the property in continuation class's primary class only.
1616 ObjCPropertyDecl *PIDecl = 0;
1617 IdentifierInfo *PropertyId = FD.D.getIdentifier();
Douglas Gregor6ab35242009-04-09 21:40:53 +00001618 for (ObjCInterfaceDecl::prop_iterator
1619 I = CCPrimary->prop_begin(Context),
1620 E = CCPrimary->prop_end(Context);
1621 I != E; ++I)
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001622 if ((*I)->getIdentifier() == PropertyId) {
1623 PIDecl = *I;
1624 break;
1625 }
1626
1627 if (PIDecl) {
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001628 // property 'PIDecl's readonly attribute will be over-ridden
Fariborz Jahanian22b6e062009-04-01 23:23:53 +00001629 // with continuation class's readwrite property attribute!
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001630 unsigned PIkind = PIDecl->getPropertyAttributes();
1631 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
Fariborz Jahanian9bfb2a22008-12-08 18:47:29 +00001632 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) !=
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001633 (PIkind & ObjCPropertyDecl::OBJC_PR_nonatomic))
1634 Diag(AtLoc, diag::warn_property_attr_mismatch);
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001635 PIDecl->makeitReadWriteAttribute();
1636 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
1637 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
1638 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
1639 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
1640 PIDecl->setSetterName(SetterSel);
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001641 // FIXME: use a common routine with addPropertyMethods.
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001642 ObjCMethodDecl *SetterDecl =
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001643 ObjCMethodDecl::Create(Context, AtLoc, AtLoc, SetterSel,
1644 Context.VoidTy,
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001645 CCPrimary,
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001646 true, false, true,
1647 ObjCMethodDecl::Required);
Chris Lattner38af2de2009-02-20 21:35:13 +00001648 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterDecl,
Chris Lattnerd1e0f5a2009-04-11 20:14:49 +00001649 FD.D.getIdentifierLoc(),
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001650 PropertyId,
Chris Lattner38af2de2009-02-20 21:35:13 +00001651 T, VarDecl::None, 0);
1652 SetterDecl->setMethodParams(&Argument, 1, Context);
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001653 PIDecl->setSetterMethodDecl(SetterDecl);
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001654 }
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001655 else
1656 Diag(AtLoc, diag::err_use_continuation_class)
1657 << CCPrimary->getDeclName();
1658 *isOverridingProperty = true;
1659 return DeclPtrTy();
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001660 }
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001661 // No matching property found in the primary class. Just fall thru
1662 // and add property to continuation class's primary class.
1663 ClassDecl = CCPrimary;
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001664 } else {
Chris Lattnerf25df992009-02-20 21:38:52 +00001665 Diag(CDecl->getLocation(), diag::err_continuation_class);
1666 *isOverridingProperty = true;
Chris Lattnerb28317a2009-03-28 19:18:32 +00001667 return DeclPtrTy();
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001668 }
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001669 }
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001670
Steve Naroff93983f82009-01-11 12:47:58 +00001671 DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
1672 assert(DC && "ClassDecl is not a DeclContext");
Chris Lattnerd1e0f5a2009-04-11 20:14:49 +00001673 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
1674 FD.D.getIdentifierLoc(),
Fariborz Jahanian1de1e742008-04-14 23:36:35 +00001675 FD.D.getIdentifier(), T);
Douglas Gregor6ab35242009-04-09 21:40:53 +00001676 DC->addDecl(Context, PDecl);
Chris Lattner97a58872009-02-16 18:32:47 +00001677
Chris Lattnerd1e0f5a2009-04-11 20:14:49 +00001678 if (T->isArrayType() || T->isFunctionType()) {
1679 Diag(AtLoc, diag::err_property_type) << T;
1680 PDecl->setInvalidDecl();
1681 }
1682
Chris Lattner97a58872009-02-16 18:32:47 +00001683 ProcessDeclAttributes(PDecl, FD.D);
Douglas Gregord0434102009-01-09 00:49:46 +00001684
Fariborz Jahanian33de3f02008-05-07 17:43:59 +00001685 // Regardless of setter/getter attribute, we save the default getter/setter
1686 // selector names in anticipation of declaration of setter/getter methods.
1687 PDecl->setGetterName(GetterSel);
1688 PDecl->setSetterName(SetterSel);
Chris Lattner4d391482007-12-12 07:09:47 +00001689
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001690 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001691 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
Chris Lattner4d391482007-12-12 07:09:47 +00001692
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001693 if (Attributes & ObjCDeclSpec::DQ_PR_getter)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001694 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
Chris Lattner4d391482007-12-12 07:09:47 +00001695
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001696 if (Attributes & ObjCDeclSpec::DQ_PR_setter)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001697 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
Chris Lattner4d391482007-12-12 07:09:47 +00001698
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001699 if (isReadWrite)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001700 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
Chris Lattner4d391482007-12-12 07:09:47 +00001701
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001702 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001703 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
Chris Lattner4d391482007-12-12 07:09:47 +00001704
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001705 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001706 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
Chris Lattner4d391482007-12-12 07:09:47 +00001707
Fariborz Jahanian8cf0bb32008-11-26 20:01:34 +00001708 if (isAssign)
1709 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
1710
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001711 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001712 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
Chris Lattner4d391482007-12-12 07:09:47 +00001713
Fariborz Jahanian46b55e52008-05-05 18:51:55 +00001714 if (MethodImplKind == tok::objc_required)
1715 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
1716 else if (MethodImplKind == tok::objc_optional)
1717 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
Fariborz Jahaniand09a4562009-04-02 18:44:20 +00001718 // A case of continuation class adding a new property in the class. This
1719 // is not what it was meant for. However, gcc supports it and so should we.
1720 // Make sure setter/getters are declared here.
1721 if (CCPrimary)
1722 ProcessPropertyDecl(PDecl, CCPrimary);
Fariborz Jahanian46b55e52008-05-05 18:51:55 +00001723
Chris Lattnerb28317a2009-03-28 19:18:32 +00001724 return DeclPtrTy::make(PDecl);
Chris Lattner4d391482007-12-12 07:09:47 +00001725}
1726
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001727/// ActOnPropertyImplDecl - This routine performs semantic checks and
1728/// builds the AST node for a property implementation declaration; declared
1729/// as @synthesize or @dynamic.
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001730///
Chris Lattnerb28317a2009-03-28 19:18:32 +00001731Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
1732 SourceLocation PropertyLoc,
1733 bool Synthesize,
1734 DeclPtrTy ClassCatImpDecl,
1735 IdentifierInfo *PropertyId,
1736 IdentifierInfo *PropertyIvar) {
1737 Decl *ClassImpDecl = ClassCatImpDecl.getAs<Decl>();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001738 // Make sure we have a context for the property implementation declaration.
1739 if (!ClassImpDecl) {
1740 Diag(AtLoc, diag::error_missing_property_context);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001741 return DeclPtrTy();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001742 }
1743 ObjCPropertyDecl *property = 0;
1744 ObjCInterfaceDecl* IDecl = 0;
1745 // Find the class or category class where this property must have
1746 // a declaration.
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001747 ObjCImplementationDecl *IC = 0;
1748 ObjCCategoryImplDecl* CatImplClass = 0;
1749 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
Douglas Gregor4afa39d2009-01-20 01:17:11 +00001750 IDecl = IC->getClassInterface();
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001751 // We always synthesize an interface for an implementation
1752 // without an interface decl. So, IDecl is always non-zero.
1753 assert(IDecl &&
1754 "ActOnPropertyImplDecl - @implementation without @interface");
1755
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001756 // Look for this property declaration in the @implementation's @interface
Douglas Gregor6ab35242009-04-09 21:40:53 +00001757 property = IDecl->FindPropertyDeclaration(Context, PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001758 if (!property) {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +00001759 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
Chris Lattnerb28317a2009-03-28 19:18:32 +00001760 return DeclPtrTy();
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001761 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001762 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001763 else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001764 if (Synthesize) {
1765 Diag(AtLoc, diag::error_synthesize_category_decl);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001766 return DeclPtrTy();
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001767 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001768 IDecl = CatImplClass->getClassInterface();
1769 if (!IDecl) {
1770 Diag(AtLoc, diag::error_missing_property_interface);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001771 return DeclPtrTy();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001772 }
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001773 ObjCCategoryDecl *Category =
1774 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
1775
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001776 // If category for this implementation not found, it is an error which
1777 // has already been reported eralier.
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001778 if (!Category)
Chris Lattnerb28317a2009-03-28 19:18:32 +00001779 return DeclPtrTy();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001780 // Look for this property declaration in @implementation's category
Douglas Gregor6ab35242009-04-09 21:40:53 +00001781 property = Category->FindPropertyDeclaration(Context, PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001782 if (!property) {
Chris Lattner5dc266a2008-11-20 06:13:02 +00001783 Diag(PropertyLoc, diag::error_bad_category_property_decl)
Chris Lattnerd9d22dd2008-11-24 05:29:24 +00001784 << Category->getDeclName();
Chris Lattnerb28317a2009-03-28 19:18:32 +00001785 return DeclPtrTy();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001786 }
Chris Lattnerb28317a2009-03-28 19:18:32 +00001787 } else {
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001788 Diag(AtLoc, diag::error_bad_property_context);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001789 return DeclPtrTy();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001790 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001791 ObjCIvarDecl *Ivar = 0;
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001792 // Check that we have a valid, previously declared ivar for @synthesize
1793 if (Synthesize) {
1794 // @synthesize
Fariborz Jahanian6cdf16d2008-04-21 21:57:36 +00001795 if (!PropertyIvar)
1796 PropertyIvar = PropertyId;
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +00001797 QualType PropType = Context.getCanonicalType(property->getType());
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001798 // Check that this is a previously declared 'ivar' in 'IDecl' interface
Douglas Gregor6ab35242009-04-09 21:40:53 +00001799 Ivar = IDecl->lookupInstanceVariable(Context, PropertyIvar);
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001800 if (!Ivar) {
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +00001801 if (getLangOptions().ObjCNonFragileABI) {
1802 Ivar = ObjCIvarDecl::Create(Context, CurContext, PropertyLoc,
1803 PropertyIvar, PropType,
Fariborz Jahanian77c9fd22009-04-06 18:30:00 +00001804 ObjCIvarDecl::Public,
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +00001805 (Expr *)0);
1806 property->setPropertyIvarDecl(Ivar);
1807 }
1808 else {
Steve Narofff4c00ff2009-03-03 22:09:41 +00001809 Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +00001810 return DeclPtrTy();
1811 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001812 }
Steve Naroff3ce52d62008-09-30 10:07:56 +00001813 QualType IvarType = Context.getCanonicalType(Ivar->getType());
1814
Steve Narofffbbe0ac2008-09-30 00:24:17 +00001815 // Check that type of property and its ivar are type compatible.
Steve Naroff3ce52d62008-09-30 10:07:56 +00001816 if (PropType != IvarType) {
Steve Naroff4fa4ab62008-10-16 14:59:30 +00001817 if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
Chris Lattner5dc266a2008-11-20 06:13:02 +00001818 Diag(PropertyLoc, diag::error_property_ivar_type)
Chris Lattnerd9d22dd2008-11-24 05:29:24 +00001819 << property->getDeclName() << Ivar->getDeclName();
Chris Lattnerb28317a2009-03-28 19:18:32 +00001820 return DeclPtrTy();
Steve Naroff3ce52d62008-09-30 10:07:56 +00001821 }
Chris Lattnerb28317a2009-03-28 19:18:32 +00001822
1823 // FIXME! Rules for properties are somewhat different that those
1824 // for assignments. Use a new routine to consolidate all cases;
1825 // specifically for property redeclarations as well as for ivars.
1826 QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType();
1827 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
1828 if (lhsType != rhsType &&
1829 lhsType->isArithmeticType()) {
1830 Diag(PropertyLoc, diag::error_property_ivar_type)
1831 << property->getDeclName() << Ivar->getDeclName();
1832 return DeclPtrTy();
1833 }
1834 // __weak is explicit. So it works on Canonical type.
Fariborz Jahanianc8bafd72009-04-07 21:25:06 +00001835 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
1836 getLangOptions().getGCMode() != LangOptions::NonGC) {
Chris Lattnerb28317a2009-03-28 19:18:32 +00001837 Diag(PropertyLoc, diag::error_weak_property)
1838 << property->getDeclName() << Ivar->getDeclName();
1839 return DeclPtrTy();
1840 }
1841 if ((Context.isObjCObjectPointerType(property->getType()) ||
Fariborz Jahanian0a9217f2009-04-10 22:42:54 +00001842 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
1843 getLangOptions().getGCMode() != LangOptions::NonGC) {
Chris Lattnerb28317a2009-03-28 19:18:32 +00001844 Diag(PropertyLoc, diag::error_strong_property)
1845 << property->getDeclName() << Ivar->getDeclName();
1846 return DeclPtrTy();
Fariborz Jahanianacdc33b2009-01-19 20:13:47 +00001847 }
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001848 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001849 } else if (PropertyIvar) {
1850 // @dynamic
1851 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001852 return DeclPtrTy();
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001853 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001854 assert (property && "ActOnPropertyImplDecl - property declaration missing");
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001855 ObjCPropertyImplDecl *PIDecl =
Douglas Gregord0434102009-01-09 00:49:46 +00001856 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
1857 property,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001858 (Synthesize ?
Daniel Dunbar9f0afd42008-08-26 04:47:31 +00001859 ObjCPropertyImplDecl::Synthesize
1860 : ObjCPropertyImplDecl::Dynamic),
1861 Ivar);
Douglas Gregor6ab35242009-04-09 21:40:53 +00001862 CurContext->addDecl(Context, PIDecl);
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +00001863 if (IC) {
1864 if (Synthesize)
1865 if (ObjCPropertyImplDecl *PPIDecl =
1866 IC->FindPropertyImplIvarDecl(PropertyIvar)) {
1867 Diag(PropertyLoc, diag::error_duplicate_ivar_use)
1868 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1869 << PropertyIvar;
1870 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1871 }
1872
1873 if (ObjCPropertyImplDecl *PPIDecl = IC->FindPropertyImplDecl(PropertyId)) {
1874 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
1875 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001876 return DeclPtrTy();
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +00001877 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001878 IC->addPropertyImplementation(PIDecl);
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +00001879 }
1880 else {
1881 if (Synthesize)
1882 if (ObjCPropertyImplDecl *PPIDecl =
1883 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
1884 Diag(PropertyLoc, diag::error_duplicate_ivar_use)
1885 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1886 << PropertyIvar;
1887 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1888 }
1889
1890 if (ObjCPropertyImplDecl *PPIDecl =
1891 CatImplClass->FindPropertyImplDecl(PropertyId)) {
1892 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
1893 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001894 return DeclPtrTy();
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +00001895 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001896 CatImplClass->addPropertyImplementation(PIDecl);
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +00001897 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001898
Chris Lattnerb28317a2009-03-28 19:18:32 +00001899 return DeclPtrTy::make(PIDecl);
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001900}
Anders Carlsson15281452008-11-04 16:57:32 +00001901
Chris Lattnercc98eac2008-12-17 07:13:27 +00001902bool Sema::CheckObjCDeclScope(Decl *D) {
Douglas Gregorce356072009-01-06 23:51:29 +00001903 if (isa<TranslationUnitDecl>(CurContext->getLookupContext()))
Anders Carlsson15281452008-11-04 16:57:32 +00001904 return false;
1905
1906 Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
1907 D->setInvalidDecl();
1908
1909 return true;
1910}
Chris Lattnercc98eac2008-12-17 07:13:27 +00001911
1912/// Collect the instance variables declared in an Objective-C object. Used in
1913/// the creation of structures from objects using the @defs directive.
1914/// FIXME: This should be consolidated with CollectObjCIvars as it is also
1915/// part of the AST generation logic of @defs.
1916static void CollectIvars(ObjCInterfaceDecl *Class, RecordDecl *Record,
1917 ASTContext& Ctx,
Chris Lattnerb28317a2009-03-28 19:18:32 +00001918 llvm::SmallVectorImpl<Sema::DeclPtrTy> &ivars) {
Chris Lattnercc98eac2008-12-17 07:13:27 +00001919 if (Class->getSuperClass())
1920 CollectIvars(Class->getSuperClass(), Record, Ctx, ivars);
1921
1922 // For each ivar, create a fresh ObjCAtDefsFieldDecl.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001923 for (ObjCInterfaceDecl::ivar_iterator I = Class->ivar_begin(),
1924 E = Class->ivar_end(); I != E; ++I) {
Chris Lattnercc98eac2008-12-17 07:13:27 +00001925 ObjCIvarDecl* ID = *I;
Chris Lattnerb28317a2009-03-28 19:18:32 +00001926 Decl *FD = ObjCAtDefsFieldDecl::Create(Ctx, Record, ID->getLocation(),
1927 ID->getIdentifier(), ID->getType(),
1928 ID->getBitWidth());
1929 ivars.push_back(Sema::DeclPtrTy::make(FD));
Chris Lattnercc98eac2008-12-17 07:13:27 +00001930 }
1931}
1932
1933/// Called whenever @defs(ClassName) is encountered in the source. Inserts the
1934/// instance variables of ClassName into Decls.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001935void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
Chris Lattnercc98eac2008-12-17 07:13:27 +00001936 IdentifierInfo *ClassName,
Chris Lattnerb28317a2009-03-28 19:18:32 +00001937 llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
Chris Lattnercc98eac2008-12-17 07:13:27 +00001938 // Check that ClassName is a valid class
1939 ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName);
1940 if (!Class) {
1941 Diag(DeclStart, diag::err_undef_interface) << ClassName;
1942 return;
1943 }
1944 // Collect the instance variables
Chris Lattnerb28317a2009-03-28 19:18:32 +00001945 CollectIvars(Class, dyn_cast<RecordDecl>(TagD.getAs<Decl>()), Context, Decls);
Chris Lattnercc98eac2008-12-17 07:13:27 +00001946
1947 // Introduce all of these fields into the appropriate scope.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001948 for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
Chris Lattnercc98eac2008-12-17 07:13:27 +00001949 D != Decls.end(); ++D) {
Chris Lattnerb28317a2009-03-28 19:18:32 +00001950 FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
Chris Lattnercc98eac2008-12-17 07:13:27 +00001951 if (getLangOptions().CPlusPlus)
1952 PushOnScopeChains(cast<FieldDecl>(FD), S);
Chris Lattnerb28317a2009-03-28 19:18:32 +00001953 else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
Douglas Gregor6ab35242009-04-09 21:40:53 +00001954 Record->addDecl(Context, FD);
Chris Lattnercc98eac2008-12-17 07:13:27 +00001955 }
1956}
1957