blob: 8eeb2d367d709387cae586e07d4aaa04352a2d38 [file] [log] [blame]
Chris Lattner855e51f2007-12-12 07:09:47 +00001//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-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 Lattner855e51f2007-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"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/DeclObjC.h"
Daniel Dunbar8d03cbe2008-08-11 03:27:53 +000017#include "clang/Basic/Diagnostic.h"
18#include "clang/Parse/DeclSpec.h"
Chris Lattner855e51f2007-12-12 07:09:47 +000019
20using namespace clang;
21
Ted Kremenek42730c52008-01-07 19:49:32 +000022/// ObjCActOnStartOfMethodDef - This routine sets up parameters; invisible
Chris Lattner855e51f2007-12-12 07:09:47 +000023/// and user declared, in the method definition's AST.
Ted Kremenek42730c52008-01-07 19:49:32 +000024void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
Argiris Kirtzidis95256e62008-06-28 06:07:14 +000025 assert(getCurMethodDecl() == 0 && "Method parsing confused");
Steve Naroff3ac43f92008-07-25 17:57:26 +000026 ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>((Decl *)D);
27
28 // If we don't have a valid method decl, simply return.
29 if (!MDecl)
30 return;
Steve Narofffe9eb6a2007-12-18 01:30:32 +000031
32 // Allow the rest of sema to find private method decl implementations.
33 if (MDecl->isInstance())
34 AddInstanceMethodToGlobalPool(MDecl);
35 else
36 AddFactoryMethodToGlobalPool(MDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +000037
38 // Allow all of Sema to see that we are entering a method definition.
Chris Lattnerf3874bc2008-04-06 04:47:34 +000039 PushDeclContext(MDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +000040
41 // Create Decl objects for each parameter, entrring them in the scope for
42 // binding to their use.
Chris Lattner855e51f2007-12-12 07:09:47 +000043
44 // Insert the invisible arguments, self and _cmd!
Daniel Dunbareaf91c32008-08-26 06:07:48 +000045 MDecl->createImplicitParams(Context);
Chris Lattner855e51f2007-12-12 07:09:47 +000046
Daniel Dunbareaf91c32008-08-26 06:07:48 +000047 PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
48 PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
Chris Lattner3e254fb2008-04-08 04:40:51 +000049
Chris Lattner97316c02008-04-10 02:22:51 +000050 // Introduce all of the other parameters into this scope.
Chris Lattner685d7922008-03-16 01:07:14 +000051 for (unsigned i = 0, e = MDecl->getNumParams(); i != e; ++i) {
Chris Lattner855e51f2007-12-12 07:09:47 +000052 ParmVarDecl *PDecl = MDecl->getParamDecl(i);
Chris Lattner3e254fb2008-04-08 04:40:51 +000053 IdentifierInfo *II = PDecl->getIdentifier();
Argiris Kirtzidis43ce0be2008-04-27 13:30:35 +000054 if (II)
55 PushOnScopeChains(PDecl, FnBodyScope);
Chris Lattner855e51f2007-12-12 07:09:47 +000056 }
57}
58
Chris Lattnere705e5e2008-07-21 22:17:28 +000059Sema::DeclTy *Sema::
60ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
61 IdentifierInfo *ClassName, SourceLocation ClassLoc,
62 IdentifierInfo *SuperName, SourceLocation SuperLoc,
Chris Lattnerae1ae492008-07-26 04:13:19 +000063 DeclTy * const *ProtoRefs, unsigned NumProtoRefs,
Chris Lattnere705e5e2008-07-21 22:17:28 +000064 SourceLocation EndProtoLoc, AttributeList *AttrList) {
Chris Lattner855e51f2007-12-12 07:09:47 +000065 assert(ClassName && "Missing class identifier");
66
67 // Check for another declaration kind with the same name.
Steve Naroff6384a012008-04-02 14:35:35 +000068 Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
Ted Kremenek42730c52008-01-07 19:49:32 +000069 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +000070 Diag(ClassLoc, diag::err_redefinition_different_kind,
71 ClassName->getName());
72 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
73 }
74
Ted Kremenek42730c52008-01-07 19:49:32 +000075 ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +000076 if (IDecl) {
77 // Class already seen. Is it a forward declaration?
78 if (!IDecl->isForwardDecl())
79 Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
80 else {
81 IDecl->setLocation(AtInterfaceLoc);
82 IDecl->setForwardDecl(false);
Chris Lattner855e51f2007-12-12 07:09:47 +000083 }
Chris Lattner5cece462008-07-21 07:06:49 +000084 } else {
Daniel Dunbard8bd6822008-08-20 18:02:42 +000085 IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000086 ClassName, ClassLoc);
Daniel Dunbard8bd6822008-08-20 18:02:42 +000087 if (AttrList)
88 ProcessDeclAttributeList(IDecl, AttrList);
Chris Lattner855e51f2007-12-12 07:09:47 +000089
Steve Naroff15208162008-04-02 18:30:49 +000090 ObjCInterfaceDecls[ClassName] = IDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +000091 // Remember that this needs to be removed when the scope is popped.
92 TUScope->AddDecl(IDecl);
93 }
94
95 if (SuperName) {
Ted Kremenek42730c52008-01-07 19:49:32 +000096 ObjCInterfaceDecl* SuperClassEntry = 0;
Chris Lattner855e51f2007-12-12 07:09:47 +000097 // Check if a different kind of symbol declared in this scope.
Steve Naroff6384a012008-04-02 14:35:35 +000098 PrevDecl = LookupDecl(SuperName, Decl::IDNS_Ordinary, TUScope);
Ted Kremenek42730c52008-01-07 19:49:32 +000099 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000100 Diag(SuperLoc, diag::err_redefinition_different_kind,
101 SuperName->getName());
102 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
103 }
104 else {
105 // Check that super class is previously defined
Ted Kremenek42730c52008-01-07 19:49:32 +0000106 SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000107
108 if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
Chris Lattner5cece462008-07-21 07:06:49 +0000109 Diag(SuperLoc, diag::err_undef_superclass,
Chris Lattner855e51f2007-12-12 07:09:47 +0000110 SuperClassEntry ? SuperClassEntry->getName()
111 : SuperName->getName(),
Chris Lattner5cece462008-07-21 07:06:49 +0000112 ClassName->getName(), SourceRange(AtInterfaceLoc, ClassLoc));
Chris Lattner855e51f2007-12-12 07:09:47 +0000113 }
114 }
115 IDecl->setSuperClass(SuperClassEntry);
Steve Naroff7c371742008-04-11 19:35:35 +0000116 IDecl->setSuperClassLoc(SuperLoc);
Chris Lattner855e51f2007-12-12 07:09:47 +0000117 IDecl->setLocEnd(SuperLoc);
118 } else { // we have a root class.
119 IDecl->setLocEnd(ClassLoc);
120 }
121
122 /// Check then save referenced protocols
Chris Lattnerae1ae492008-07-26 04:13:19 +0000123 if (NumProtoRefs) {
124 IDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
Chris Lattner855e51f2007-12-12 07:09:47 +0000125 IDecl->setLocEnd(EndProtoLoc);
126 }
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000127
128 CheckObjCDeclScope(IDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000129 return IDecl;
130}
131
132/// ActOnCompatiblityAlias - this action is called after complete parsing of
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000133/// @compatibility_alias declaration. It sets up the alias relationships.
Steve Naroffe57c21a2008-04-01 23:04:06 +0000134Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
135 IdentifierInfo *AliasName,
136 SourceLocation AliasLocation,
137 IdentifierInfo *ClassName,
138 SourceLocation ClassLocation) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000139 // Look for previous declaration of alias name
Steve Naroff6384a012008-04-02 14:35:35 +0000140 Decl *ADecl = LookupDecl(AliasName, Decl::IDNS_Ordinary, TUScope);
Chris Lattner855e51f2007-12-12 07:09:47 +0000141 if (ADecl) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000142 if (isa<ObjCCompatibleAliasDecl>(ADecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000143 Diag(AliasLocation, diag::warn_previous_alias_decl);
144 Diag(ADecl->getLocation(), diag::warn_previous_declaration);
145 }
146 else {
147 Diag(AliasLocation, diag::err_conflicting_aliasing_type,
148 AliasName->getName());
149 Diag(ADecl->getLocation(), diag::err_previous_declaration);
150 }
151 return 0;
152 }
153 // Check for class declaration
Steve Naroff6384a012008-04-02 14:35:35 +0000154 Decl *CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000155 ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
156 if (CDecl == 0) {
157 Diag(ClassLocation, diag::warn_undef_interface, ClassName->getName());
158 if (CDeclU)
159 Diag(CDeclU->getLocation(), diag::warn_previous_declaration);
Chris Lattner855e51f2007-12-12 07:09:47 +0000160 return 0;
161 }
Chris Lattner2d1c4312008-03-16 21:17:37 +0000162
163 // Everything checked out, instantiate a new alias declaration AST.
Ted Kremenek42730c52008-01-07 19:49:32 +0000164 ObjCCompatibleAliasDecl *AliasDecl =
Steve Naroffe57c21a2008-04-01 23:04:06 +0000165 ObjCCompatibleAliasDecl::Create(Context, AtLoc, AliasName, CDecl);
166
167 ObjCAliasDecls[AliasName] = AliasDecl;
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000168
169 if (!CheckObjCDeclScope(AliasDecl))
170 TUScope->AddDecl(AliasDecl);
171
Chris Lattner855e51f2007-12-12 07:09:47 +0000172 return AliasDecl;
173}
174
Chris Lattner2bdedd62008-07-26 04:03:38 +0000175Sema::DeclTy *
176Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
177 IdentifierInfo *ProtocolName,
178 SourceLocation ProtocolLoc,
179 DeclTy * const *ProtoRefs,
180 unsigned NumProtoRefs,
Daniel Dunbar28680d12008-09-26 04:48:09 +0000181 SourceLocation EndProtoLoc,
182 AttributeList *AttrList) {
183 // FIXME: Deal with AttrList.
Chris Lattner855e51f2007-12-12 07:09:47 +0000184 assert(ProtocolName && "Missing protocol identifier");
Ted Kremenek42730c52008-01-07 19:49:32 +0000185 ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName];
Chris Lattner855e51f2007-12-12 07:09:47 +0000186 if (PDecl) {
187 // Protocol already seen. Better be a forward protocol declaration
Chris Lattnerc1881852008-03-16 01:25:17 +0000188 if (!PDecl->isForwardDecl()) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000189 Diag(ProtocolLoc, diag::err_duplicate_protocol_def,
190 ProtocolName->getName());
Chris Lattnerc1881852008-03-16 01:25:17 +0000191 // Just return the protocol we already had.
192 // FIXME: don't leak the objects passed in!
193 return PDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +0000194 }
Steve Naroff9a9e5212008-08-13 16:39:22 +0000195 // Make sure the cached decl gets a valid start location.
196 PDecl->setLocation(AtProtoInterfaceLoc);
Chris Lattnerc1881852008-03-16 01:25:17 +0000197 PDecl->setForwardDecl(false);
Chris Lattnerc1881852008-03-16 01:25:17 +0000198 } else {
Chris Lattner0be08822008-07-21 21:32:27 +0000199 PDecl = ObjCProtocolDecl::Create(Context, AtProtoInterfaceLoc,ProtocolName);
Chris Lattner7afba9c2008-03-16 20:19:15 +0000200 PDecl->setForwardDecl(false);
Ted Kremenek42730c52008-01-07 19:49:32 +0000201 ObjCProtocols[ProtocolName] = PDecl;
Chris Lattner180f7e22008-03-16 01:23:04 +0000202 }
Chris Lattner855e51f2007-12-12 07:09:47 +0000203
204 if (NumProtoRefs) {
Chris Lattner7afba9c2008-03-16 20:19:15 +0000205 /// Check then save referenced protocols.
Chris Lattner2bdedd62008-07-26 04:03:38 +0000206 PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
Chris Lattner855e51f2007-12-12 07:09:47 +0000207 PDecl->setLocEnd(EndProtoLoc);
208 }
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000209
210 CheckObjCDeclScope(PDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000211 return PDecl;
212}
213
214/// FindProtocolDeclaration - This routine looks up protocols and
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000215/// issues an error if they are not declared. It returns list of
216/// protocol declarations in its 'Protocols' argument.
Chris Lattner855e51f2007-12-12 07:09:47 +0000217void
Chris Lattner2bdedd62008-07-26 04:03:38 +0000218Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
Chris Lattnere705e5e2008-07-21 22:17:28 +0000219 const IdentifierLocPair *ProtocolId,
Chris Lattner855e51f2007-12-12 07:09:47 +0000220 unsigned NumProtocols,
Chris Lattnere705e5e2008-07-21 22:17:28 +0000221 llvm::SmallVectorImpl<DeclTy*> &Protocols) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000222 for (unsigned i = 0; i != NumProtocols; ++i) {
Chris Lattner17d50a92008-07-26 03:47:43 +0000223 ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i].first];
224 if (!PDecl) {
Chris Lattnere705e5e2008-07-21 22:17:28 +0000225 Diag(ProtocolId[i].second, diag::err_undeclared_protocol,
226 ProtocolId[i].first->getName());
Chris Lattner17d50a92008-07-26 03:47:43 +0000227 continue;
228 }
229
230 // If this is a forward declaration and we are supposed to warn in this
231 // case, do it.
232 if (WarnOnDeclarations && PDecl->isForwardDecl())
233 Diag(ProtocolId[i].second, diag::warn_undef_protocolref,
234 ProtocolId[i].first->getName());
235 Protocols.push_back(PDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000236 }
237}
238
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000239/// DiagnosePropertyMismatch - Compares two properties for their
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000240/// attributes and types and warns on a variety of inconsistencies.
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000241///
Fariborz Jahanianed986602008-05-01 00:03:38 +0000242void
243Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
244 ObjCPropertyDecl *SuperProperty,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000245 const char *inheritedName) {
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000246 ObjCPropertyDecl::PropertyAttributeKind CAttr =
247 Property->getPropertyAttributes();
248 ObjCPropertyDecl::PropertyAttributeKind SAttr =
249 SuperProperty->getPropertyAttributes();
250 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
251 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
Fariborz Jahanianed986602008-05-01 00:03:38 +0000252 Diag(Property->getLocation(), diag::warn_readonly_property,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000253 Property->getName(), inheritedName);
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000254 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
255 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
Fariborz Jahanianed986602008-05-01 00:03:38 +0000256 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000257 Property->getName(), "copy", inheritedName,
Fariborz Jahanianed986602008-05-01 00:03:38 +0000258 SourceRange());
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000259 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
260 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
Fariborz Jahanianed986602008-05-01 00:03:38 +0000261 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000262 Property->getName(), "retain", inheritedName,
Fariborz Jahanianed986602008-05-01 00:03:38 +0000263 SourceRange());
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000264
265 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
266 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
Fariborz Jahanianed986602008-05-01 00:03:38 +0000267 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000268 Property->getName(), "atomic", inheritedName,
Fariborz Jahanianed986602008-05-01 00:03:38 +0000269 SourceRange());
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000270 if (Property->getSetterName() != SuperProperty->getSetterName())
Fariborz Jahanianed986602008-05-01 00:03:38 +0000271 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000272 Property->getName(), "setter", inheritedName,
Fariborz Jahanianed986602008-05-01 00:03:38 +0000273 SourceRange());
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000274 if (Property->getGetterName() != SuperProperty->getGetterName())
Fariborz Jahanianed986602008-05-01 00:03:38 +0000275 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000276 Property->getName(), "getter", inheritedName,
Fariborz Jahanianed986602008-05-01 00:03:38 +0000277 SourceRange());
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000278
Chris Lattnerc5cff302008-07-26 20:50:02 +0000279 if (Context.getCanonicalType(Property->getType()) !=
280 Context.getCanonicalType(SuperProperty->getType()))
Fariborz Jahanian513e30a2008-05-01 18:05:01 +0000281 Diag(Property->getLocation(), diag::warn_property_type,
282 Property->getType().getAsString(),
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000283 inheritedName);
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000284
285}
286
287/// ComparePropertiesInBaseAndSuper - This routine compares property
288/// declarations in base and its super class, if any, and issues
289/// diagnostics in a variety of inconsistant situations.
290///
291void
Fariborz Jahanianed986602008-05-01 00:03:38 +0000292Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000293 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
294 if (!SDecl)
295 return;
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000296 // FIXME: O(N^2)
Fariborz Jahanianed986602008-05-01 00:03:38 +0000297 for (ObjCInterfaceDecl::classprop_iterator S = SDecl->classprop_begin(),
298 E = SDecl->classprop_end(); S != E; ++S) {
299 ObjCPropertyDecl *SuperPDecl = (*S);
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000300 // Does property in super class has declaration in current class?
301 for (ObjCInterfaceDecl::classprop_iterator I = IDecl->classprop_begin(),
302 E = IDecl->classprop_end(); I != E; ++I) {
303 ObjCPropertyDecl *PDecl = (*I);
304 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
Douglas Gregor24afd4a2008-11-17 14:58:09 +0000305 DiagnosePropertyMismatch(PDecl, SuperPDecl,
306 SDecl->getIdentifierName());
Fariborz Jahanian1e89de32008-04-24 19:58:34 +0000307 }
308 }
309}
310
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000311/// MergeOneProtocolPropertiesIntoClass - This routine goes thru the list
312/// of properties declared in a protocol and adds them to the list
313/// of properties for current class if it is not there already.
314void
315Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
316 ObjCProtocolDecl *PDecl)
317{
318 llvm::SmallVector<ObjCPropertyDecl*, 16> mergeProperties;
319 for (ObjCProtocolDecl::classprop_iterator P = PDecl->classprop_begin(),
320 E = PDecl->classprop_end(); P != E; ++P) {
321 ObjCPropertyDecl *Pr = (*P);
322 ObjCInterfaceDecl::classprop_iterator CP, CE;
323 // Is this property already in class's list of properties?
324 for (CP = IDecl->classprop_begin(), CE = IDecl->classprop_end();
325 CP != CE; ++CP)
326 if ((*CP)->getIdentifier() == Pr->getIdentifier())
327 break;
328 if (CP == CE)
329 // Add this property to list of properties for thie class.
330 mergeProperties.push_back(Pr);
331 else
332 // Property protocol already exist in class. Diagnose any mismatch.
Douglas Gregor24afd4a2008-11-17 14:58:09 +0000333 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifierName());
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000334 }
335 IDecl->mergeProperties(&mergeProperties[0], mergeProperties.size());
336}
337
338/// MergeProtocolPropertiesIntoClass - This routine merges properties
339/// declared in 'MergeItsProtocols' objects (which can be a class or an
340/// inherited protocol into the list of properties for class 'IDecl'
341///
342
343void
344Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
345 DeclTy *MergeItsProtocols) {
346 Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols);
Chris Lattner5cece462008-07-21 07:06:49 +0000347 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000348 for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
349 E = MDecl->protocol_end(); P != E; ++P)
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000350 // Merge properties of class (*P) into IDECL's
Chris Lattner5cece462008-07-21 07:06:49 +0000351 MergeOneProtocolPropertiesIntoClass(IDecl, *P);
352
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000353 // Go thru the list of protocols for this class and recursively merge
354 // their properties into this class as well.
355 for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
356 E = IDecl->protocol_end(); P != E; ++P)
Chris Lattner5cece462008-07-21 07:06:49 +0000357 MergeProtocolPropertiesIntoClass(IDecl, *P);
358 } else {
Argiris Kirtzidisfc1ea132008-07-21 09:18:38 +0000359 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
360 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
361 E = MD->protocol_end(); P != E; ++P)
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000362 MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
Chris Lattner5cece462008-07-21 07:06:49 +0000363 }
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000364}
365
Chris Lattner855e51f2007-12-12 07:09:47 +0000366/// ActOnForwardProtocolDeclaration -
367Action::DeclTy *
368Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
Chris Lattnere705e5e2008-07-21 22:17:28 +0000369 const IdentifierLocPair *IdentList,
370 unsigned NumElts) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000371 llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
Chris Lattner855e51f2007-12-12 07:09:47 +0000372
373 for (unsigned i = 0; i != NumElts; ++i) {
Chris Lattnere705e5e2008-07-21 22:17:28 +0000374 IdentifierInfo *Ident = IdentList[i].first;
Chris Lattner7afba9c2008-03-16 20:19:15 +0000375 ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident];
Chris Lattnere705e5e2008-07-21 22:17:28 +0000376 if (PDecl == 0) // Not already seen?
377 PDecl = ObjCProtocolDecl::Create(Context, IdentList[i].second, Ident);
Chris Lattner855e51f2007-12-12 07:09:47 +0000378
379 Protocols.push_back(PDecl);
380 }
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000381
382 ObjCForwardProtocolDecl *PDecl =
383 ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
384 &Protocols[0], Protocols.size());
385
386 CheckObjCDeclScope(PDecl);
387 return PDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +0000388}
389
Chris Lattnere705e5e2008-07-21 22:17:28 +0000390Sema::DeclTy *Sema::
391ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
392 IdentifierInfo *ClassName, SourceLocation ClassLoc,
393 IdentifierInfo *CategoryName,
394 SourceLocation CategoryLoc,
Chris Lattner45142b92008-07-26 04:07:02 +0000395 DeclTy * const *ProtoRefs,
Chris Lattnere705e5e2008-07-21 22:17:28 +0000396 unsigned NumProtoRefs,
397 SourceLocation EndProtoLoc) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000398 ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
Chris Lattner855e51f2007-12-12 07:09:47 +0000399
Chris Lattnere29dc832008-03-16 20:34:23 +0000400 ObjCCategoryDecl *CDecl =
Chris Lattner321b5d12008-03-16 20:47:45 +0000401 ObjCCategoryDecl::Create(Context, AtInterfaceLoc, CategoryName);
Chris Lattner855e51f2007-12-12 07:09:47 +0000402 CDecl->setClassInterface(IDecl);
Fariborz Jahanian6669a582008-01-17 20:33:24 +0000403
404 /// Check that class of this category is already completely declared.
405 if (!IDecl || IDecl->isForwardDecl())
406 Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
Steve Naroffac0580b2008-06-05 15:03:27 +0000407 else {
Fariborz Jahanian6669a582008-01-17 20:33:24 +0000408 /// Check for duplicate interface declaration for this category
409 ObjCCategoryDecl *CDeclChain;
410 for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
411 CDeclChain = CDeclChain->getNextClassCategory()) {
Steve Naroffac0580b2008-06-05 15:03:27 +0000412 if (CategoryName && CDeclChain->getIdentifier() == CategoryName) {
Steve Naroff0a7149f2008-06-05 04:33:44 +0000413 Diag(CategoryLoc, diag::warn_dup_category_def, ClassName->getName(),
Fariborz Jahanian6669a582008-01-17 20:33:24 +0000414 CategoryName->getName());
415 break;
416 }
Chris Lattner855e51f2007-12-12 07:09:47 +0000417 }
Steve Naroffac0580b2008-06-05 15:03:27 +0000418 if (!CDeclChain)
419 CDecl->insertNextClassCategory();
Fariborz Jahanian6669a582008-01-17 20:33:24 +0000420 }
Chris Lattner855e51f2007-12-12 07:09:47 +0000421
422 if (NumProtoRefs) {
Chris Lattner45142b92008-07-26 04:07:02 +0000423 CDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
424 CDecl->setLocEnd(EndProtoLoc);
Chris Lattner855e51f2007-12-12 07:09:47 +0000425 }
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000426
427 CheckObjCDeclScope(CDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000428 return CDecl;
429}
430
431/// ActOnStartCategoryImplementation - Perform semantic checks on the
Ted Kremenek42730c52008-01-07 19:49:32 +0000432/// category implementation declaration and build an ObjCCategoryImplDecl
Chris Lattner855e51f2007-12-12 07:09:47 +0000433/// object.
434Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
435 SourceLocation AtCatImplLoc,
436 IdentifierInfo *ClassName, SourceLocation ClassLoc,
437 IdentifierInfo *CatName, SourceLocation CatLoc) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000438 ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
Chris Lattner1b6de332008-03-16 20:53:07 +0000439 ObjCCategoryImplDecl *CDecl =
440 ObjCCategoryImplDecl::Create(Context, AtCatImplLoc, CatName, IDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000441 /// Check that class of this category is already completely declared.
442 if (!IDecl || IDecl->isForwardDecl())
443 Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
444
445 /// TODO: Check that CatName, category name, is not used in another
446 // implementation.
Steve Naroff4b9846d2008-09-28 14:55:53 +0000447 ObjCCategoryImpls.push_back(CDecl);
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000448
449 CheckObjCDeclScope(CDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000450 return CDecl;
451}
452
453Sema::DeclTy *Sema::ActOnStartClassImplementation(
454 SourceLocation AtClassImplLoc,
455 IdentifierInfo *ClassName, SourceLocation ClassLoc,
456 IdentifierInfo *SuperClassname,
457 SourceLocation SuperClassLoc) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000458 ObjCInterfaceDecl* IDecl = 0;
Chris Lattner855e51f2007-12-12 07:09:47 +0000459 // Check for another declaration kind with the same name.
Steve Naroff6384a012008-04-02 14:35:35 +0000460 Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
Ted Kremenek42730c52008-01-07 19:49:32 +0000461 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000462 Diag(ClassLoc, diag::err_redefinition_different_kind,
463 ClassName->getName());
464 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
465 }
466 else {
467 // Is there an interface declaration of this class; if not, warn!
Ted Kremenek42730c52008-01-07 19:49:32 +0000468 IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000469 if (!IDecl)
470 Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
471 }
472
473 // Check that super class name is valid class name
Ted Kremenek42730c52008-01-07 19:49:32 +0000474 ObjCInterfaceDecl* SDecl = 0;
Chris Lattner855e51f2007-12-12 07:09:47 +0000475 if (SuperClassname) {
476 // Check if a different kind of symbol declared in this scope.
Steve Naroff6384a012008-04-02 14:35:35 +0000477 PrevDecl = LookupDecl(SuperClassname, Decl::IDNS_Ordinary, TUScope);
Ted Kremenek42730c52008-01-07 19:49:32 +0000478 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000479 Diag(SuperClassLoc, diag::err_redefinition_different_kind,
480 SuperClassname->getName());
481 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
482 }
483 else {
Ted Kremenek42730c52008-01-07 19:49:32 +0000484 SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000485 if (!SDecl)
486 Diag(SuperClassLoc, diag::err_undef_superclass,
487 SuperClassname->getName(), ClassName->getName());
488 else if (IDecl && IDecl->getSuperClass() != SDecl) {
489 // This implementation and its interface do not have the same
490 // super class.
491 Diag(SuperClassLoc, diag::err_conflicting_super_class,
492 SDecl->getName());
493 Diag(SDecl->getLocation(), diag::err_previous_definition);
494 }
495 }
496 }
497
498 if (!IDecl) {
499 // Legacy case of @implementation with no corresponding @interface.
500 // Build, chain & install the interface decl into the identifier.
Daniel Dunbard8bd6822008-08-20 18:02:42 +0000501
502 // FIXME: Do we support attributes on the @implementation? If so
503 // we should copy them over.
Chris Lattner5cece462008-07-21 07:06:49 +0000504 IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, ClassName,
Steve Naroff7c371742008-04-11 19:35:35 +0000505 ClassLoc, false, true);
Steve Naroff15208162008-04-02 18:30:49 +0000506 ObjCInterfaceDecls[ClassName] = IDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +0000507 IDecl->setSuperClass(SDecl);
508 IDecl->setLocEnd(ClassLoc);
509
510 // Remember that this needs to be removed when the scope is popped.
511 TUScope->AddDecl(IDecl);
512 }
513
Ted Kremenek42730c52008-01-07 19:49:32 +0000514 ObjCImplementationDecl* IMPDecl =
Chris Lattner1b6de332008-03-16 20:53:07 +0000515 ObjCImplementationDecl::Create(Context, AtClassImplLoc, ClassName,
516 IDecl, SDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000517
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000518 if (CheckObjCDeclScope(IMPDecl))
519 return IMPDecl;
520
Chris Lattner855e51f2007-12-12 07:09:47 +0000521 // Check that there is no duplicate implementation of this class.
Ted Kremenek42730c52008-01-07 19:49:32 +0000522 if (ObjCImplementations[ClassName])
Chris Lattner1b6de332008-03-16 20:53:07 +0000523 // FIXME: Don't leak everything!
Chris Lattner855e51f2007-12-12 07:09:47 +0000524 Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
525 else // add it to the list.
Ted Kremenek42730c52008-01-07 19:49:32 +0000526 ObjCImplementations[ClassName] = IMPDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +0000527 return IMPDecl;
528}
529
Ted Kremenek42730c52008-01-07 19:49:32 +0000530void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
531 ObjCIvarDecl **ivars, unsigned numIvars,
Chris Lattner855e51f2007-12-12 07:09:47 +0000532 SourceLocation RBrace) {
533 assert(ImpDecl && "missing implementation decl");
Ted Kremenek42730c52008-01-07 19:49:32 +0000534 ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(ImpDecl->getIdentifier());
Chris Lattner855e51f2007-12-12 07:09:47 +0000535 if (!IDecl)
536 return;
537 /// Check case of non-existing @interface decl.
538 /// (legacy objective-c @implementation decl without an @interface decl).
539 /// Add implementations's ivar to the synthesize class's ivar list.
540 if (IDecl->ImplicitInterfaceDecl()) {
541 IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace);
542 return;
543 }
544 // If implementation has empty ivar list, just return.
545 if (numIvars == 0)
546 return;
547
548 assert(ivars && "missing @implementation ivars");
549
550 // Check interface's Ivar list against those in the implementation.
551 // names and types must match.
552 //
Chris Lattner855e51f2007-12-12 07:09:47 +0000553 unsigned j = 0;
Ted Kremenek42730c52008-01-07 19:49:32 +0000554 ObjCInterfaceDecl::ivar_iterator
Chris Lattner9d76c722007-12-12 17:58:05 +0000555 IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
556 for (; numIvars > 0 && IVI != IVE; ++IVI) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000557 ObjCIvarDecl* ImplIvar = ivars[j++];
558 ObjCIvarDecl* ClsIvar = *IVI;
Chris Lattner855e51f2007-12-12 07:09:47 +0000559 assert (ImplIvar && "missing implementation ivar");
560 assert (ClsIvar && "missing class ivar");
Chris Lattnerb5457862008-07-27 00:05:05 +0000561 if (Context.getCanonicalType(ImplIvar->getType()) !=
562 Context.getCanonicalType(ClsIvar->getType())) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000563 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type,
564 ImplIvar->getIdentifier()->getName());
565 Diag(ClsIvar->getLocation(), diag::err_previous_definition,
566 ClsIvar->getIdentifier()->getName());
567 }
568 // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed
569 // as error.
570 else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
571 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name,
572 ImplIvar->getIdentifier()->getName());
573 Diag(ClsIvar->getLocation(), diag::err_previous_definition,
574 ClsIvar->getIdentifier()->getName());
Chris Lattner1cc669d2007-12-12 18:11:49 +0000575 return;
Chris Lattner855e51f2007-12-12 07:09:47 +0000576 }
577 --numIvars;
Chris Lattner855e51f2007-12-12 07:09:47 +0000578 }
Chris Lattner1cc669d2007-12-12 18:11:49 +0000579
580 if (numIvars > 0)
Chris Lattner847de6f2007-12-12 18:19:52 +0000581 Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
Chris Lattner1cc669d2007-12-12 18:11:49 +0000582 else if (IVI != IVE)
Chris Lattner847de6f2007-12-12 18:19:52 +0000583 Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
Chris Lattner855e51f2007-12-12 07:09:47 +0000584}
585
Steve Naroffb4f48512008-02-10 21:38:56 +0000586void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
587 bool &IncompleteImpl) {
588 if (!IncompleteImpl) {
589 Diag(ImpLoc, diag::warn_incomplete_impl);
590 IncompleteImpl = true;
591 }
592 Diag(ImpLoc, diag::warn_undef_method_impl, method->getSelector().getName());
593}
594
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000595/// FIXME: Type hierarchies in Objective-C can be deep. We could most
596/// likely improve the efficiency of selector lookups and type
597/// checking by associating with each protocol / interface / category
598/// the flattened instance tables. If we used an immutable set to keep
599/// the table then it wouldn't add significant memory cost and it
600/// would be handy for lookups.
601
Steve Naroffb268d2a2008-02-08 22:06:17 +0000602/// CheckProtocolMethodDefs - This routine checks unimplemented methods
Chris Lattner855e51f2007-12-12 07:09:47 +0000603/// Declared in protocol, and those referenced by it.
Steve Naroffb268d2a2008-02-08 22:06:17 +0000604void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
605 ObjCProtocolDecl *PDecl,
Chris Lattner855e51f2007-12-12 07:09:47 +0000606 bool& IncompleteImpl,
Steve Naroffb268d2a2008-02-08 22:06:17 +0000607 const llvm::DenseSet<Selector> &InsMap,
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000608 const llvm::DenseSet<Selector> &ClsMap,
609 ObjCInterfaceDecl *IDecl) {
610 ObjCInterfaceDecl *Super = IDecl->getSuperClass();
611
612 // If a method lookup fails locally we still need to look and see if
613 // the method was implemented by a base class or an inherited
614 // protocol. This lookup is slow, but occurs rarely in correct code
615 // and otherwise would terminate in a warning.
616
Chris Lattner855e51f2007-12-12 07:09:47 +0000617 // check unimplemented instance methods.
Ted Kremenek42730c52008-01-07 19:49:32 +0000618 for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
Steve Naroff2ce399a2007-12-14 23:37:57 +0000619 E = PDecl->instmeth_end(); I != E; ++I) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000620 ObjCMethodDecl *method = *I;
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000621 if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
622 !InsMap.count(method->getSelector()) &&
623 (!Super || !Super->lookupInstanceMethod(method->getSelector())))
Steve Naroffb4f48512008-02-10 21:38:56 +0000624 WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000625 }
626 // check unimplemented class methods
Ted Kremenek42730c52008-01-07 19:49:32 +0000627 for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
Steve Naroff2ce399a2007-12-14 23:37:57 +0000628 E = PDecl->classmeth_end(); I != E; ++I) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000629 ObjCMethodDecl *method = *I;
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000630 if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
631 !ClsMap.count(method->getSelector()) &&
632 (!Super || !Super->lookupClassMethod(method->getSelector())))
Steve Naroffb4f48512008-02-10 21:38:56 +0000633 WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
Steve Naroff2ce399a2007-12-14 23:37:57 +0000634 }
Chris Lattner0be08822008-07-21 21:32:27 +0000635 // Check on this protocols's referenced protocols, recursively.
636 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
637 E = PDecl->protocol_end(); PI != E; ++PI)
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000638 CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000639}
640
Ted Kremenek42730c52008-01-07 19:49:32 +0000641void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
642 ObjCInterfaceDecl* IDecl) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000643 llvm::DenseSet<Selector> InsMap;
644 // Check and see if instance methods in class interface have been
645 // implemented in the implementation class.
Ted Kremenek42730c52008-01-07 19:49:32 +0000646 for (ObjCImplementationDecl::instmeth_iterator I = IMPDecl->instmeth_begin(),
Chris Lattner9d76c722007-12-12 17:58:05 +0000647 E = IMPDecl->instmeth_end(); I != E; ++I)
648 InsMap.insert((*I)->getSelector());
Chris Lattner855e51f2007-12-12 07:09:47 +0000649
650 bool IncompleteImpl = false;
Ted Kremenek42730c52008-01-07 19:49:32 +0000651 for (ObjCInterfaceDecl::instmeth_iterator I = IDecl->instmeth_begin(),
Chris Lattner9d76c722007-12-12 17:58:05 +0000652 E = IDecl->instmeth_end(); I != E; ++I)
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +0000653 if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector()))
Steve Naroffb4f48512008-02-10 21:38:56 +0000654 WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
Chris Lattner9d76c722007-12-12 17:58:05 +0000655
Chris Lattner855e51f2007-12-12 07:09:47 +0000656 llvm::DenseSet<Selector> ClsMap;
657 // Check and see if class methods in class interface have been
658 // implemented in the implementation class.
Ted Kremenek42730c52008-01-07 19:49:32 +0000659 for (ObjCImplementationDecl::classmeth_iterator I =IMPDecl->classmeth_begin(),
Chris Lattner9d76c722007-12-12 17:58:05 +0000660 E = IMPDecl->classmeth_end(); I != E; ++I)
661 ClsMap.insert((*I)->getSelector());
Chris Lattner855e51f2007-12-12 07:09:47 +0000662
Ted Kremenek42730c52008-01-07 19:49:32 +0000663 for (ObjCInterfaceDecl::classmeth_iterator I = IDecl->classmeth_begin(),
Chris Lattner9d76c722007-12-12 17:58:05 +0000664 E = IDecl->classmeth_end(); I != E; ++I)
Steve Naroffb4f48512008-02-10 21:38:56 +0000665 if (!ClsMap.count((*I)->getSelector()))
666 WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000667
668 // Check the protocol list for unimplemented methods in the @implementation
669 // class.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000670 const ObjCList<ObjCProtocolDecl> &Protocols =
671 IDecl->getReferencedProtocols();
672 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
673 E = Protocols.end(); I != E; ++I)
674 CheckProtocolMethodDefs(IMPDecl->getLocation(), *I,
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000675 IncompleteImpl, InsMap, ClsMap, IDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000676}
677
678/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000679/// category interface are implemented in the category @implementation.
Ted Kremenek42730c52008-01-07 19:49:32 +0000680void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
681 ObjCCategoryDecl *CatClassDecl) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000682 llvm::DenseSet<Selector> InsMap;
683 // Check and see if instance methods in category interface have been
684 // implemented in its implementation class.
Ted Kremenek42730c52008-01-07 19:49:32 +0000685 for (ObjCCategoryImplDecl::instmeth_iterator I =CatImplDecl->instmeth_begin(),
Chris Lattner9d76c722007-12-12 17:58:05 +0000686 E = CatImplDecl->instmeth_end(); I != E; ++I)
687 InsMap.insert((*I)->getSelector());
Chris Lattner855e51f2007-12-12 07:09:47 +0000688
689 bool IncompleteImpl = false;
Ted Kremenek42730c52008-01-07 19:49:32 +0000690 for (ObjCCategoryDecl::instmeth_iterator I = CatClassDecl->instmeth_begin(),
Steve Naroff2ce399a2007-12-14 23:37:57 +0000691 E = CatClassDecl->instmeth_end(); I != E; ++I)
Steve Naroffb4f48512008-02-10 21:38:56 +0000692 if (!InsMap.count((*I)->getSelector()))
693 WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
694
Chris Lattner855e51f2007-12-12 07:09:47 +0000695 llvm::DenseSet<Selector> ClsMap;
696 // Check and see if class methods in category interface have been
697 // implemented in its implementation class.
Ted Kremenek42730c52008-01-07 19:49:32 +0000698 for (ObjCCategoryImplDecl::classmeth_iterator
Chris Lattner9d76c722007-12-12 17:58:05 +0000699 I = CatImplDecl->classmeth_begin(), E = CatImplDecl->classmeth_end();
700 I != E; ++I)
701 ClsMap.insert((*I)->getSelector());
Chris Lattner855e51f2007-12-12 07:09:47 +0000702
Ted Kremenek42730c52008-01-07 19:49:32 +0000703 for (ObjCCategoryDecl::classmeth_iterator I = CatClassDecl->classmeth_begin(),
Steve Naroff2ce399a2007-12-14 23:37:57 +0000704 E = CatClassDecl->classmeth_end(); I != E; ++I)
Steve Naroffb4f48512008-02-10 21:38:56 +0000705 if (!ClsMap.count((*I)->getSelector()))
706 WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000707
708 // Check the protocol list for unimplemented methods in the @implementation
709 // class.
Chris Lattner0be08822008-07-21 21:32:27 +0000710 for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),
711 E = CatClassDecl->protocol_end(); PI != E; ++PI)
712 CheckProtocolMethodDefs(CatImplDecl->getLocation(), *PI, IncompleteImpl,
Daniel Dunbar1d706e92008-09-04 20:01:15 +0000713 InsMap, ClsMap, CatClassDecl->getClassInterface());
Chris Lattner855e51f2007-12-12 07:09:47 +0000714}
715
716/// ActOnForwardClassDeclaration -
717Action::DeclTy *
718Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
719 IdentifierInfo **IdentList, unsigned NumElts)
720{
Ted Kremenek42730c52008-01-07 19:49:32 +0000721 llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
Chris Lattner855e51f2007-12-12 07:09:47 +0000722
723 for (unsigned i = 0; i != NumElts; ++i) {
724 // Check for another declaration kind with the same name.
Steve Naroff6384a012008-04-02 14:35:35 +0000725 Decl *PrevDecl = LookupDecl(IdentList[i], Decl::IDNS_Ordinary, TUScope);
Ted Kremenek42730c52008-01-07 19:49:32 +0000726 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Steve Naroffd2549972008-06-05 22:57:10 +0000727 // GCC apparently allows the following idiom:
728 //
729 // typedef NSObject < XCElementTogglerP > XCElementToggler;
730 // @class XCElementToggler;
731 //
732 // FIXME: Make an extension?
733 TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
734 if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
735 Diag(AtClassLoc, diag::err_redefinition_different_kind,
736 IdentList[i]->getName());
737 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
738 }
Chris Lattner855e51f2007-12-12 07:09:47 +0000739 }
Ted Kremenek42730c52008-01-07 19:49:32 +0000740 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000741 if (!IDecl) { // Not already seen? Make a forward decl.
Chris Lattner5cece462008-07-21 07:06:49 +0000742 IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, IdentList[i],
Steve Naroff7c371742008-04-11 19:35:35 +0000743 SourceLocation(), true);
Steve Naroff15208162008-04-02 18:30:49 +0000744 ObjCInterfaceDecls[IdentList[i]] = IDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +0000745
746 // Remember that this needs to be removed when the scope is popped.
747 TUScope->AddDecl(IDecl);
748 }
749
750 Interfaces.push_back(IDecl);
751 }
752
Anders Carlsson0a6ab172008-11-04 16:57:32 +0000753 ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, AtClassLoc,
754 &Interfaces[0],
755 Interfaces.size());
756
757 CheckObjCDeclScope(CDecl);
758 return CDecl;
Chris Lattner855e51f2007-12-12 07:09:47 +0000759}
760
761
762/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
763/// returns true, or false, accordingly.
764/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
Ted Kremenek42730c52008-01-07 19:49:32 +0000765bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
Steve Naroffb91afca2008-10-21 10:37:50 +0000766 const ObjCMethodDecl *PrevMethod,
767 bool matchBasedOnSizeAndAlignment) {
768 QualType T1 = Context.getCanonicalType(Method->getResultType());
769 QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
770
771 if (T1 != T2) {
772 // The result types are different.
773 if (!matchBasedOnSizeAndAlignment)
Chris Lattner855e51f2007-12-12 07:09:47 +0000774 return false;
Steve Naroffb91afca2008-10-21 10:37:50 +0000775 // Incomplete types don't have a size and alignment.
776 if (T1->isIncompleteType() || T2->isIncompleteType())
777 return false;
778 // Check is based on size and alignment.
779 if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
780 return false;
781 }
782 for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) {
783 T1 = Context.getCanonicalType(Method->getParamDecl(i)->getType());
784 T2 = Context.getCanonicalType(PrevMethod->getParamDecl(i)->getType());
785 if (T1 != T2) {
786 // The result types are different.
787 if (!matchBasedOnSizeAndAlignment)
788 return false;
789 // Incomplete types don't have a size and alignment.
790 if (T1->isIncompleteType() || T2->isIncompleteType())
791 return false;
792 // Check is based on size and alignment.
793 if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
794 return false;
795 }
Chris Lattner855e51f2007-12-12 07:09:47 +0000796 }
797 return true;
798}
799
Ted Kremenek42730c52008-01-07 19:49:32 +0000800void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
801 ObjCMethodList &FirstMethod = InstanceMethodPool[Method->getSelector()];
Chris Lattner855e51f2007-12-12 07:09:47 +0000802 if (!FirstMethod.Method) {
803 // Haven't seen a method with this selector name yet - add it.
804 FirstMethod.Method = Method;
805 FirstMethod.Next = 0;
806 } else {
807 // We've seen a method with this name, now check the type signature(s).
808 bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
809
Ted Kremenek42730c52008-01-07 19:49:32 +0000810 for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
Chris Lattner855e51f2007-12-12 07:09:47 +0000811 Next = Next->Next)
812 match = MatchTwoMethodDeclarations(Method, Next->Method);
813
814 if (!match) {
815 // We have a new signature for an existing method - add it.
816 // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
Ted Kremenek42730c52008-01-07 19:49:32 +0000817 struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
Chris Lattner855e51f2007-12-12 07:09:47 +0000818 FirstMethod.Next = OMI;
819 }
820 }
821}
822
Steve Naroffec7e0882008-10-21 10:50:19 +0000823// FIXME: Finish implementing -Wno-strict-selector-match.
Steve Naroff68354f32008-09-30 14:38:43 +0000824ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
825 SourceRange R) {
826 ObjCMethodList &MethList = InstanceMethodPool[Sel];
Steve Naroffb91afca2008-10-21 10:37:50 +0000827 bool issueWarning = false;
Steve Naroff68354f32008-09-30 14:38:43 +0000828
829 if (MethList.Method && MethList.Next) {
Steve Naroffb91afca2008-10-21 10:37:50 +0000830 for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
831 // This checks if the methods differ by size & alignment.
832 if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
833 issueWarning = true;
834 }
835 if (issueWarning && (MethList.Method && MethList.Next)) {
Steve Naroff68354f32008-09-30 14:38:43 +0000836 Diag(R.getBegin(), diag::warn_multiple_method_decl, Sel.getName(), R);
837 Diag(MethList.Method->getLocStart(), diag::warn_using_decl,
838 MethList.Method->getSourceRange());
839 for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
840 Diag(Next->Method->getLocStart(), diag::warn_also_found_decl,
841 Next->Method->getSourceRange());
842 }
843 return MethList.Method;
844}
845
Ted Kremenek42730c52008-01-07 19:49:32 +0000846void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
847 ObjCMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
Chris Lattner855e51f2007-12-12 07:09:47 +0000848 if (!FirstMethod.Method) {
849 // Haven't seen a method with this selector name yet - add it.
850 FirstMethod.Method = Method;
851 FirstMethod.Next = 0;
852 } else {
853 // We've seen a method with this name, now check the type signature(s).
854 bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
855
Ted Kremenek42730c52008-01-07 19:49:32 +0000856 for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
Chris Lattner855e51f2007-12-12 07:09:47 +0000857 Next = Next->Next)
858 match = MatchTwoMethodDeclarations(Method, Next->Method);
859
860 if (!match) {
861 // We have a new signature for an existing method - add it.
862 // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
Ted Kremenek42730c52008-01-07 19:49:32 +0000863 struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
Chris Lattner855e51f2007-12-12 07:09:47 +0000864 FirstMethod.Next = OMI;
865 }
866 }
867}
868
Steve Narofffe9eb6a2007-12-18 01:30:32 +0000869// Note: For class/category implemenations, allMethods/allProperties is
870// always null.
Chris Lattner855e51f2007-12-12 07:09:47 +0000871void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
872 DeclTy **allMethods, unsigned allNum,
873 DeclTy **allProperties, unsigned pNum) {
874 Decl *ClassDecl = static_cast<Decl *>(classDecl);
875
Steve Narofffe9eb6a2007-12-18 01:30:32 +0000876 // FIXME: If we don't have a ClassDecl, we have an error. We should consider
877 // always passing in a decl. If the decl has an error, isInvalidDecl()
Chris Lattner855e51f2007-12-12 07:09:47 +0000878 // should be true.
879 if (!ClassDecl)
880 return;
881
Ted Kremenek42730c52008-01-07 19:49:32 +0000882 llvm::SmallVector<ObjCMethodDecl*, 32> insMethods;
883 llvm::SmallVector<ObjCMethodDecl*, 16> clsMethods;
Chris Lattner855e51f2007-12-12 07:09:47 +0000884
Ted Kremenek42730c52008-01-07 19:49:32 +0000885 llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
886 llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
Chris Lattner855e51f2007-12-12 07:09:47 +0000887
888 bool isInterfaceDeclKind =
Chris Lattner2d1c4312008-03-16 21:17:37 +0000889 isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
890 || isa<ObjCProtocolDecl>(ClassDecl);
Ted Kremenek42730c52008-01-07 19:49:32 +0000891 bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000892
Seo Sanghyeon0473be42008-07-05 02:01:25 +0000893 if (pNum != 0) {
Chris Lattnercffe3662008-03-16 21:23:50 +0000894 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
895 IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000896 else if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
897 CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
898 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(ClassDecl))
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000899 PDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000900 else
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000901 assert(false && "ActOnAtEnd - property declaration misplaced");
Seo Sanghyeon0473be42008-07-05 02:01:25 +0000902 }
Chris Lattner855e51f2007-12-12 07:09:47 +0000903
904 for (unsigned i = 0; i < allNum; i++ ) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000905 ObjCMethodDecl *Method =
906 cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i]));
Chris Lattner855e51f2007-12-12 07:09:47 +0000907
908 if (!Method) continue; // Already issued a diagnostic.
909 if (Method->isInstance()) {
910 /// Check for instance method of the same name with incompatible types
Ted Kremenek42730c52008-01-07 19:49:32 +0000911 const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
Chris Lattner855e51f2007-12-12 07:09:47 +0000912 bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
913 : false;
914 if (isInterfaceDeclKind && PrevMethod && !match
915 || checkIdenticalMethods && match) {
916 Diag(Method->getLocation(), diag::error_duplicate_method_decl,
917 Method->getSelector().getName());
918 Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
919 } else {
920 insMethods.push_back(Method);
921 InsMap[Method->getSelector()] = Method;
922 /// The following allows us to typecheck messages to "id".
923 AddInstanceMethodToGlobalPool(Method);
924 }
925 }
926 else {
927 /// Check for class method of the same name with incompatible types
Ted Kremenek42730c52008-01-07 19:49:32 +0000928 const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
Chris Lattner855e51f2007-12-12 07:09:47 +0000929 bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
930 : false;
931 if (isInterfaceDeclKind && PrevMethod && !match
932 || checkIdenticalMethods && match) {
933 Diag(Method->getLocation(), diag::error_duplicate_method_decl,
934 Method->getSelector().getName());
935 Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
936 } else {
937 clsMethods.push_back(Method);
938 ClsMap[Method->getSelector()] = Method;
Steve Narofffe9eb6a2007-12-18 01:30:32 +0000939 /// The following allows us to typecheck messages to "Class".
940 AddFactoryMethodToGlobalPool(Method);
Chris Lattner855e51f2007-12-12 07:09:47 +0000941 }
942 }
943 }
Steve Naroffe2e61e72008-09-29 14:20:56 +0000944 // Save the size so we can detect if we've added any property methods.
945 unsigned int insMethodsSizePriorToPropAdds = insMethods.size();
946 unsigned int clsMethodsSizePriorToPropAdds = clsMethods.size();
Chris Lattner855e51f2007-12-12 07:09:47 +0000947
Ted Kremenek42730c52008-01-07 19:49:32 +0000948 if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000949 // Compares properties declared in this class to those of its
Fariborz Jahanianed986602008-05-01 00:03:38 +0000950 // super class.
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000951 ComparePropertiesInBaseAndSuper(I);
952 MergeProtocolPropertiesIntoClass(I, I);
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000953 for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
954 e = I->classprop_end(); i != e; ++i)
955 I->addPropertyMethods(Context, *i, insMethods);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000956 I->addMethods(&insMethods[0], insMethods.size(),
957 &clsMethods[0], clsMethods.size(), AtEndLoc);
958
Ted Kremenek42730c52008-01-07 19:49:32 +0000959 } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000960 for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
961 e = P->classprop_end(); i != e; ++i)
962 P->addPropertyMethods(Context, *i, insMethods);
Chris Lattner855e51f2007-12-12 07:09:47 +0000963 P->addMethods(&insMethods[0], insMethods.size(),
964 &clsMethods[0], clsMethods.size(), AtEndLoc);
965 }
Ted Kremenek42730c52008-01-07 19:49:32 +0000966 else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000967 // FIXME: Need to compare properties to those in interface?
968
969 // FIXME: If we merge properties into class we should probably
970 // merge them into category as well?
971 for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
972 e = C->classprop_end(); i != e; ++i)
973 C->addPropertyMethods(Context, *i, insMethods);
Chris Lattner855e51f2007-12-12 07:09:47 +0000974 C->addMethods(&insMethods[0], insMethods.size(),
975 &clsMethods[0], clsMethods.size(), AtEndLoc);
976 }
Ted Kremenek42730c52008-01-07 19:49:32 +0000977 else if (ObjCImplementationDecl *IC =
978 dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +0000979 IC->setLocEnd(AtEndLoc);
Ted Kremenek42730c52008-01-07 19:49:32 +0000980 if (ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
Chris Lattner855e51f2007-12-12 07:09:47 +0000981 ImplMethodsVsClassMethods(IC, IDecl);
982 } else {
Ted Kremenek42730c52008-01-07 19:49:32 +0000983 ObjCCategoryImplDecl* CatImplClass = cast<ObjCCategoryImplDecl>(ClassDecl);
Chris Lattner855e51f2007-12-12 07:09:47 +0000984 CatImplClass->setLocEnd(AtEndLoc);
Ted Kremenek42730c52008-01-07 19:49:32 +0000985 ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface();
Chris Lattner855e51f2007-12-12 07:09:47 +0000986 // Find category interface decl and then check that all methods declared
Daniel Dunbar0c0160f2008-08-27 05:40:03 +0000987 // in this interface are implemented in the category @implementation.
Chris Lattner855e51f2007-12-12 07:09:47 +0000988 if (IDecl) {
Ted Kremenek42730c52008-01-07 19:49:32 +0000989 for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
Chris Lattner855e51f2007-12-12 07:09:47 +0000990 Categories; Categories = Categories->getNextClassCategory()) {
991 if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
992 ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories);
993 break;
994 }
995 }
996 }
997 }
Steve Naroffe2e61e72008-09-29 14:20:56 +0000998 // Add any synthesized methods to the global pool. This allows us to
999 // handle the following, which is supported by GCC (and part of the design).
1000 //
1001 // @interface Foo
1002 // @property double bar;
1003 // @end
1004 //
1005 // void thisIsUnfortunate() {
1006 // id foo;
1007 // double bar = [foo bar];
1008 // }
1009 //
1010 if (insMethodsSizePriorToPropAdds < insMethods.size())
1011 for (unsigned i = insMethodsSizePriorToPropAdds; i < insMethods.size(); i++)
1012 AddInstanceMethodToGlobalPool(insMethods[i]);
1013 if (clsMethodsSizePriorToPropAdds < clsMethods.size())
1014 for (unsigned i = clsMethodsSizePriorToPropAdds; i < clsMethods.size(); i++)
1015 AddFactoryMethodToGlobalPool(clsMethods[i]);
Chris Lattner855e51f2007-12-12 07:09:47 +00001016}
1017
1018
1019/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
1020/// objective-c's type qualifier from the parser version of the same info.
Ted Kremenek42730c52008-01-07 19:49:32 +00001021static Decl::ObjCDeclQualifier
1022CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
1023 Decl::ObjCDeclQualifier ret = Decl::OBJC_TQ_None;
1024 if (PQTVal & ObjCDeclSpec::DQ_In)
1025 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_In);
1026 if (PQTVal & ObjCDeclSpec::DQ_Inout)
1027 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
1028 if (PQTVal & ObjCDeclSpec::DQ_Out)
1029 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Out);
1030 if (PQTVal & ObjCDeclSpec::DQ_Bycopy)
1031 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
1032 if (PQTVal & ObjCDeclSpec::DQ_Byref)
1033 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
1034 if (PQTVal & ObjCDeclSpec::DQ_Oneway)
1035 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
Chris Lattner855e51f2007-12-12 07:09:47 +00001036
1037 return ret;
1038}
1039
1040Sema::DeclTy *Sema::ActOnMethodDeclaration(
1041 SourceLocation MethodLoc, SourceLocation EndLoc,
Chris Lattner114add62008-03-16 00:49:28 +00001042 tok::TokenKind MethodType, DeclTy *classDecl,
Ted Kremenek42730c52008-01-07 19:49:32 +00001043 ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
Chris Lattner855e51f2007-12-12 07:09:47 +00001044 Selector Sel,
1045 // optional arguments. The number of types/arguments is obtained
1046 // from the Sel.getNumArgs().
Ted Kremenek42730c52008-01-07 19:49:32 +00001047 ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
Chris Lattner855e51f2007-12-12 07:09:47 +00001048 AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
1049 bool isVariadic) {
Chris Lattner114add62008-03-16 00:49:28 +00001050 Decl *ClassDecl = static_cast<Decl*>(classDecl);
Steve Naroff70f16242008-02-29 21:48:07 +00001051
1052 // Make sure we can establish a context for the method.
1053 if (!ClassDecl) {
1054 Diag(MethodLoc, diag::error_missing_method_context);
1055 return 0;
1056 }
Chris Lattner855e51f2007-12-12 07:09:47 +00001057 QualType resultDeclType;
1058
1059 if (ReturnType)
1060 resultDeclType = QualType::getFromOpaquePtr(ReturnType);
1061 else // get the type for "id".
Ted Kremenek42730c52008-01-07 19:49:32 +00001062 resultDeclType = Context.getObjCIdType();
Chris Lattner855e51f2007-12-12 07:09:47 +00001063
Chris Lattner114add62008-03-16 00:49:28 +00001064 ObjCMethodDecl* ObjCMethod =
1065 ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
Daniel Dunbard8bd6822008-08-20 18:02:42 +00001066 ClassDecl,
Chris Lattner114add62008-03-16 00:49:28 +00001067 MethodType == tok::minus, isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +00001068 false,
Chris Lattner114add62008-03-16 00:49:28 +00001069 MethodDeclKind == tok::objc_optional ?
1070 ObjCMethodDecl::Optional :
1071 ObjCMethodDecl::Required);
1072
Chris Lattnereee57c02008-04-04 06:12:32 +00001073 llvm::SmallVector<ParmVarDecl*, 16> Params;
1074
1075 for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
1076 // FIXME: arg->AttrList must be stored too!
1077 QualType argType;
1078
1079 if (ArgTypes[i])
1080 argType = QualType::getFromOpaquePtr(ArgTypes[i]);
1081 else
1082 argType = Context.getObjCIdType();
1083 ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
1084 SourceLocation(/*FIXME*/),
1085 ArgNames[i], argType,
Chris Lattner3e254fb2008-04-08 04:40:51 +00001086 VarDecl::None, 0, 0);
Chris Lattnereee57c02008-04-04 06:12:32 +00001087 Param->setObjCDeclQualifier(
1088 CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
1089 Params.push_back(Param);
1090 }
1091
Ted Kremenek42730c52008-01-07 19:49:32 +00001092 ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
1093 ObjCMethod->setObjCDeclQualifier(
1094 CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
1095 const ObjCMethodDecl *PrevMethod = 0;
Daniel Dunbard1d847c2008-09-26 04:12:28 +00001096
1097 if (AttrList)
1098 ProcessDeclAttributeList(ObjCMethod, AttrList);
Chris Lattner855e51f2007-12-12 07:09:47 +00001099
1100 // For implementations (which can be very "coarse grain"), we add the
1101 // method now. This allows the AST to implement lookup methods that work
1102 // incrementally (without waiting until we parse the @end). It also allows
1103 // us to flag multiple declaration errors as they occur.
Ted Kremenek42730c52008-01-07 19:49:32 +00001104 if (ObjCImplementationDecl *ImpDecl =
Chris Lattner114add62008-03-16 00:49:28 +00001105 dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +00001106 if (MethodType == tok::minus) {
Steve Naroff74273de2007-12-19 22:27:04 +00001107 PrevMethod = ImpDecl->getInstanceMethod(Sel);
Ted Kremenek42730c52008-01-07 19:49:32 +00001108 ImpDecl->addInstanceMethod(ObjCMethod);
Chris Lattner855e51f2007-12-12 07:09:47 +00001109 } else {
Steve Naroff74273de2007-12-19 22:27:04 +00001110 PrevMethod = ImpDecl->getClassMethod(Sel);
Ted Kremenek42730c52008-01-07 19:49:32 +00001111 ImpDecl->addClassMethod(ObjCMethod);
Chris Lattner855e51f2007-12-12 07:09:47 +00001112 }
1113 }
Ted Kremenek42730c52008-01-07 19:49:32 +00001114 else if (ObjCCategoryImplDecl *CatImpDecl =
Chris Lattner114add62008-03-16 00:49:28 +00001115 dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
Chris Lattner855e51f2007-12-12 07:09:47 +00001116 if (MethodType == tok::minus) {
Steve Naroff74273de2007-12-19 22:27:04 +00001117 PrevMethod = CatImpDecl->getInstanceMethod(Sel);
Ted Kremenek42730c52008-01-07 19:49:32 +00001118 CatImpDecl->addInstanceMethod(ObjCMethod);
Chris Lattner855e51f2007-12-12 07:09:47 +00001119 } else {
Steve Naroff74273de2007-12-19 22:27:04 +00001120 PrevMethod = CatImpDecl->getClassMethod(Sel);
Ted Kremenek42730c52008-01-07 19:49:32 +00001121 CatImpDecl->addClassMethod(ObjCMethod);
Chris Lattner855e51f2007-12-12 07:09:47 +00001122 }
1123 }
1124 if (PrevMethod) {
1125 // You can never have two method definitions with the same name.
Ted Kremenek42730c52008-01-07 19:49:32 +00001126 Diag(ObjCMethod->getLocation(), diag::error_duplicate_method_decl,
1127 ObjCMethod->getSelector().getName());
Chris Lattner855e51f2007-12-12 07:09:47 +00001128 Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
1129 }
Ted Kremenek42730c52008-01-07 19:49:32 +00001130 return ObjCMethod;
Chris Lattner855e51f2007-12-12 07:09:47 +00001131}
1132
Daniel Dunbar540ff472008-09-23 21:53:23 +00001133void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
1134 SourceLocation Loc,
1135 unsigned &Attributes) {
1136 // FIXME: Improve the reported location.
1137
1138 // readonly and readwrite conflict.
1139 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1140 (Attributes & ObjCDeclSpec::DQ_PR_readwrite)) {
1141 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1142 "readonly", "readwrite");
1143 Attributes ^= ObjCDeclSpec::DQ_PR_readonly;
1144 }
1145
1146 // Check for copy or retain on non-object types.
1147 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
1148 !Context.isObjCObjectPointerType(PropertyTy)) {
1149 Diag(Loc, diag::err_objc_property_requires_object,
1150 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
1151 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
1152 }
1153
1154 // Check for more than one of { assign, copy, retain }.
1155 if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
1156 if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1157 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1158 "assign", "copy");
1159 Attributes ^= ObjCDeclSpec::DQ_PR_copy;
1160 }
1161 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1162 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1163 "assign", "retain");
1164 Attributes ^= ObjCDeclSpec::DQ_PR_retain;
1165 }
1166 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1167 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1168 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1169 "copy", "retain");
1170 Attributes ^= ObjCDeclSpec::DQ_PR_retain;
1171 }
1172 }
1173
1174 // Warn if user supplied no assignment attribute, property is
1175 // readwrite, and this is an object type.
1176 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
1177 ObjCDeclSpec::DQ_PR_retain)) &&
1178 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1179 Context.isObjCObjectPointerType(PropertyTy)) {
1180 // Skip this warning in gc-only mode.
1181 if (getLangOptions().getGCMode() != LangOptions::GCOnly)
1182 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
1183
1184 // If non-gc code warn that this is likely inappropriate.
1185 if (getLangOptions().getGCMode() == LangOptions::NonGC)
1186 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
1187
1188 // FIXME: Implement warning dependent on NSCopying being
1189 // implemented. See also:
1190 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
1191 // (please trim this list while you are at it).
1192 }
1193}
1194
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +00001195Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
1196 FieldDeclarator &FD,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +00001197 ObjCDeclSpec &ODS,
Fariborz Jahanianb7080ae2008-05-06 18:09:04 +00001198 Selector GetterSel,
1199 Selector SetterSel,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +00001200 tok::ObjCKeywordKind MethodImplKind) {
Fariborz Jahaniane7071722008-04-11 23:40:25 +00001201 QualType T = GetTypeForDeclarator(FD.D, S);
Daniel Dunbar540ff472008-09-23 21:53:23 +00001202 unsigned Attributes = ODS.getPropertyAttributes();
1203
1204 // May modify Attributes.
1205 CheckObjCPropertyAttributes(T, AtLoc, Attributes);
1206
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +00001207 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, AtLoc,
1208 FD.D.getIdentifier(), T);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +00001209 // Regardless of setter/getter attribute, we save the default getter/setter
1210 // selector names in anticipation of declaration of setter/getter methods.
1211 PDecl->setGetterName(GetterSel);
1212 PDecl->setSetterName(SetterSel);
Chris Lattner855e51f2007-12-12 07:09:47 +00001213
Daniel Dunbar540ff472008-09-23 21:53:23 +00001214 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
Ted Kremenek42730c52008-01-07 19:49:32 +00001215 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
Chris Lattner855e51f2007-12-12 07:09:47 +00001216
Daniel Dunbar540ff472008-09-23 21:53:23 +00001217 if (Attributes & ObjCDeclSpec::DQ_PR_getter)
Ted Kremenek42730c52008-01-07 19:49:32 +00001218 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
Chris Lattner855e51f2007-12-12 07:09:47 +00001219
Daniel Dunbar540ff472008-09-23 21:53:23 +00001220 if (Attributes & ObjCDeclSpec::DQ_PR_setter)
Ted Kremenek42730c52008-01-07 19:49:32 +00001221 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
Chris Lattner855e51f2007-12-12 07:09:47 +00001222
Daniel Dunbar540ff472008-09-23 21:53:23 +00001223 if (Attributes & ObjCDeclSpec::DQ_PR_assign)
Ted Kremenek42730c52008-01-07 19:49:32 +00001224 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
Chris Lattner855e51f2007-12-12 07:09:47 +00001225
Daniel Dunbar540ff472008-09-23 21:53:23 +00001226 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
Ted Kremenek42730c52008-01-07 19:49:32 +00001227 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
Chris Lattner855e51f2007-12-12 07:09:47 +00001228
Daniel Dunbar540ff472008-09-23 21:53:23 +00001229 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
Ted Kremenek42730c52008-01-07 19:49:32 +00001230 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
Chris Lattner855e51f2007-12-12 07:09:47 +00001231
Daniel Dunbar540ff472008-09-23 21:53:23 +00001232 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
Ted Kremenek42730c52008-01-07 19:49:32 +00001233 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
Chris Lattner855e51f2007-12-12 07:09:47 +00001234
Daniel Dunbar540ff472008-09-23 21:53:23 +00001235 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
Ted Kremenek42730c52008-01-07 19:49:32 +00001236 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
Chris Lattner855e51f2007-12-12 07:09:47 +00001237
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +00001238 if (MethodImplKind == tok::objc_required)
1239 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
1240 else if (MethodImplKind == tok::objc_optional)
1241 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
1242
Chris Lattner855e51f2007-12-12 07:09:47 +00001243 return PDecl;
1244}
1245
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001246/// ActOnPropertyImplDecl - This routine performs semantic checks and
1247/// builds the AST node for a property implementation declaration; declared
1248/// as @synthesize or @dynamic.
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001249///
1250Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
1251 SourceLocation PropertyLoc,
1252 bool Synthesize,
1253 DeclTy *ClassCatImpDecl,
1254 IdentifierInfo *PropertyId,
1255 IdentifierInfo *PropertyIvar) {
1256 Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
1257 // Make sure we have a context for the property implementation declaration.
1258 if (!ClassImpDecl) {
1259 Diag(AtLoc, diag::error_missing_property_context);
1260 return 0;
1261 }
1262 ObjCPropertyDecl *property = 0;
1263 ObjCInterfaceDecl* IDecl = 0;
1264 // Find the class or category class where this property must have
1265 // a declaration.
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +00001266 ObjCImplementationDecl *IC = 0;
1267 ObjCCategoryImplDecl* CatImplClass = 0;
1268 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001269 IDecl = getObjCInterfaceDecl(IC->getIdentifier());
Fariborz Jahanian900e3dc2008-04-21 21:05:54 +00001270 // We always synthesize an interface for an implementation
1271 // without an interface decl. So, IDecl is always non-zero.
1272 assert(IDecl &&
1273 "ActOnPropertyImplDecl - @implementation without @interface");
1274
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001275 // Look for this property declaration in the @implementation's @interface
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001276 property = IDecl->FindPropertyDeclaration(PropertyId);
1277 if (!property) {
Daniel Dunbar540ff472008-09-23 21:53:23 +00001278 Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName());
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001279 return 0;
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001280 }
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001281 }
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +00001282 else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
Fariborz Jahanian900e3dc2008-04-21 21:05:54 +00001283 if (Synthesize) {
1284 Diag(AtLoc, diag::error_synthesize_category_decl);
1285 return 0;
1286 }
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001287 IDecl = CatImplClass->getClassInterface();
1288 if (!IDecl) {
1289 Diag(AtLoc, diag::error_missing_property_interface);
1290 return 0;
1291 }
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001292 ObjCCategoryDecl *Category =
1293 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
1294
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001295 // If category for this implementation not found, it is an error which
1296 // has already been reported eralier.
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001297 if (!Category)
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001298 return 0;
1299 // Look for this property declaration in @implementation's category
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001300 property = Category->FindPropertyDeclaration(PropertyId);
1301 if (!property) {
Fariborz Jahanian900e3dc2008-04-21 21:05:54 +00001302 Diag(PropertyLoc, diag::error_bad_category_property_decl,
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +00001303 Category->getName());
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001304 return 0;
1305 }
1306 }
1307 else {
1308 Diag(AtLoc, diag::error_bad_property_context);
1309 return 0;
1310 }
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +00001311 ObjCIvarDecl *Ivar = 0;
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001312 // Check that we have a valid, previously declared ivar for @synthesize
1313 if (Synthesize) {
1314 // @synthesize
Fariborz Jahanian1f028002008-04-21 21:57:36 +00001315 if (!PropertyIvar)
1316 PropertyIvar = PropertyId;
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001317 // Check that this is a previously declared 'ivar' in 'IDecl' interface
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +00001318 Ivar = IDecl->FindIvarDeclaration(PropertyIvar);
Fariborz Jahanian900e3dc2008-04-21 21:05:54 +00001319 if (!Ivar) {
Fariborz Jahanian1f028002008-04-21 21:57:36 +00001320 Diag(PropertyLoc, diag::error_missing_property_ivar_decl,
1321 PropertyId->getName());
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001322 return 0;
1323 }
Steve Naroffc32e45c2008-09-30 10:07:56 +00001324 QualType PropType = Context.getCanonicalType(property->getType());
1325 QualType IvarType = Context.getCanonicalType(Ivar->getType());
1326
Steve Naroff631e3922008-09-30 00:24:17 +00001327 // Check that type of property and its ivar are type compatible.
Steve Naroffc32e45c2008-09-30 10:07:56 +00001328 if (PropType != IvarType) {
Steve Naroff3557a342008-10-16 14:59:30 +00001329 if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
Steve Naroffc32e45c2008-09-30 10:07:56 +00001330 Diag(PropertyLoc, diag::error_property_ivar_type, property->getName(),
1331 Ivar->getName());
1332 return 0;
1333 }
Fariborz Jahanian900e3dc2008-04-21 21:05:54 +00001334 }
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001335 } else if (PropertyIvar) {
1336 // @dynamic
1337 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
1338 return 0;
1339 }
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001340 assert (property && "ActOnPropertyImplDecl - property declaration missing");
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +00001341 ObjCPropertyImplDecl *PIDecl =
1342 ObjCPropertyImplDecl::Create(Context, AtLoc, PropertyLoc, property,
1343 (Synthesize ?
Daniel Dunbar14117fc2008-08-26 04:47:31 +00001344 ObjCPropertyImplDecl::Synthesize
1345 : ObjCPropertyImplDecl::Dynamic),
1346 Ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +00001347 if (IC)
1348 IC->addPropertyImplementation(PIDecl);
1349 else
1350 CatImplClass->addPropertyImplementation(PIDecl);
1351
1352 return PIDecl;
Fariborz Jahanian78f7e312008-04-18 00:19:30 +00001353}
Anders Carlsson0a6ab172008-11-04 16:57:32 +00001354
1355bool Sema::CheckObjCDeclScope(Decl *D)
1356{
1357 if (isa<TranslationUnitDecl>(CurContext))
1358 return false;
1359
1360 Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
1361 D->setInvalidDecl();
1362
1363 return true;
1364}