blob: 6c17d5f1f6c917c8f06ef3fe238dbe132cd59c33 [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"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/DeclObjC.h"
Daniel Dunbar12bc6922008-08-11 03:27:53 +000017#include "clang/Basic/Diagnostic.h"
18#include "clang/Parse/DeclSpec.h"
Chris Lattner4d391482007-12-12 07:09:47 +000019
20using namespace clang;
21
Ted Kremeneka526c5c2008-01-07 19:49:32 +000022/// ObjCActOnStartOfMethodDef - This routine sets up parameters; invisible
Chris Lattner4d391482007-12-12 07:09:47 +000023/// and user declared, in the method definition's AST.
Ted Kremeneka526c5c2008-01-07 19:49:32 +000024void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
Argyrios Kyrtzidis53d0ea52008-06-28 06:07:14 +000025 assert(getCurMethodDecl() == 0 && "Method parsing confused");
Steve Naroff394f3f42008-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 Naroffa56f6162007-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 Lattner4d391482007-12-12 07:09:47 +000037
38 // Allow all of Sema to see that we are entering a method definition.
Chris Lattnerb048c982008-04-06 04:47:34 +000039 PushDeclContext(MDecl);
Chris Lattner4d391482007-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 Lattner4d391482007-12-12 07:09:47 +000043
44 // Insert the invisible arguments, self and _cmd!
Daniel Dunbar451318c2008-08-26 06:07:48 +000045 MDecl->createImplicitParams(Context);
Chris Lattner4d391482007-12-12 07:09:47 +000046
Daniel Dunbar451318c2008-08-26 06:07:48 +000047 PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
48 PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
Chris Lattner04421082008-04-08 04:40:51 +000049
Chris Lattner8123a952008-04-10 02:22:51 +000050 // Introduce all of the other parameters into this scope.
Chris Lattner58cce3b2008-03-16 01:07:14 +000051 for (unsigned i = 0, e = MDecl->getNumParams(); i != e; ++i) {
Chris Lattner4d391482007-12-12 07:09:47 +000052 ParmVarDecl *PDecl = MDecl->getParamDecl(i);
Chris Lattner04421082008-04-08 04:40:51 +000053 IdentifierInfo *II = PDecl->getIdentifier();
Argyrios Kyrtzidis642e38b2008-04-27 13:30:35 +000054 if (II)
55 PushOnScopeChains(PDecl, FnBodyScope);
Chris Lattner4d391482007-12-12 07:09:47 +000056 }
57}
58
Chris Lattner7caeabd2008-07-21 22:17:28 +000059Sema::DeclTy *Sema::
60ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
61 IdentifierInfo *ClassName, SourceLocation ClassLoc,
62 IdentifierInfo *SuperName, SourceLocation SuperLoc,
Chris Lattner06036d32008-07-26 04:13:19 +000063 DeclTy * const *ProtoRefs, unsigned NumProtoRefs,
Chris Lattner7caeabd2008-07-21 22:17:28 +000064 SourceLocation EndProtoLoc, AttributeList *AttrList) {
Chris Lattner4d391482007-12-12 07:09:47 +000065 assert(ClassName && "Missing class identifier");
66
67 // Check for another declaration kind with the same name.
Steve Naroffb327ce02008-04-02 14:35:35 +000068 Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
Ted Kremeneka526c5c2008-01-07 19:49:32 +000069 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner4d391482007-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 Kremeneka526c5c2008-01-07 19:49:32 +000075 ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-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 Lattner4d391482007-12-12 07:09:47 +000083 }
Chris Lattnerb752f282008-07-21 07:06:49 +000084 } else {
Daniel Dunbarf6414922008-08-20 18:02:42 +000085 IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000086 ClassName, ClassLoc);
Daniel Dunbarf6414922008-08-20 18:02:42 +000087 if (AttrList)
88 ProcessDeclAttributeList(IDecl, AttrList);
Chris Lattner4d391482007-12-12 07:09:47 +000089
Steve Naroff31102512008-04-02 18:30:49 +000090 ObjCInterfaceDecls[ClassName] = IDecl;
Chris Lattner4d391482007-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 Kremeneka526c5c2008-01-07 19:49:32 +000096 ObjCInterfaceDecl* SuperClassEntry = 0;
Chris Lattner4d391482007-12-12 07:09:47 +000097 // Check if a different kind of symbol declared in this scope.
Steve Naroffb327ce02008-04-02 14:35:35 +000098 PrevDecl = LookupDecl(SuperName, Decl::IDNS_Ordinary, TUScope);
Ted Kremeneka526c5c2008-01-07 19:49:32 +000099 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner4d391482007-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 Kremeneka526c5c2008-01-07 19:49:32 +0000106 SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000107
108 if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) {
Chris Lattnerb752f282008-07-21 07:06:49 +0000109 Diag(SuperLoc, diag::err_undef_superclass,
Chris Lattner4d391482007-12-12 07:09:47 +0000110 SuperClassEntry ? SuperClassEntry->getName()
111 : SuperName->getName(),
Chris Lattnerb752f282008-07-21 07:06:49 +0000112 ClassName->getName(), SourceRange(AtInterfaceLoc, ClassLoc));
Chris Lattner4d391482007-12-12 07:09:47 +0000113 }
114 }
115 IDecl->setSuperClass(SuperClassEntry);
Steve Naroffd6a07aa2008-04-11 19:35:35 +0000116 IDecl->setSuperClassLoc(SuperLoc);
Chris Lattner4d391482007-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 Lattner06036d32008-07-26 04:13:19 +0000123 if (NumProtoRefs) {
124 IDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
Chris Lattner4d391482007-12-12 07:09:47 +0000125 IDecl->setLocEnd(EndProtoLoc);
126 }
Anders Carlsson15281452008-11-04 16:57:32 +0000127
128 CheckObjCDeclScope(IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000129 return IDecl;
130}
131
132/// ActOnCompatiblityAlias - this action is called after complete parsing of
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000133/// @compatibility_alias declaration. It sets up the alias relationships.
Steve Naroffe8043c32008-04-01 23:04:06 +0000134Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
135 IdentifierInfo *AliasName,
136 SourceLocation AliasLocation,
137 IdentifierInfo *ClassName,
138 SourceLocation ClassLocation) {
Chris Lattner4d391482007-12-12 07:09:47 +0000139 // Look for previous declaration of alias name
Steve Naroffb327ce02008-04-02 14:35:35 +0000140 Decl *ADecl = LookupDecl(AliasName, Decl::IDNS_Ordinary, TUScope);
Chris Lattner4d391482007-12-12 07:09:47 +0000141 if (ADecl) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000142 if (isa<ObjCCompatibleAliasDecl>(ADecl)) {
Chris Lattner4d391482007-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 Naroffb327ce02008-04-02 14:35:35 +0000154 Decl *CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
Chris Lattnerf8d17a52008-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 Lattner4d391482007-12-12 07:09:47 +0000160 return 0;
161 }
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000162
163 // Everything checked out, instantiate a new alias declaration AST.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000164 ObjCCompatibleAliasDecl *AliasDecl =
Steve Naroffe8043c32008-04-01 23:04:06 +0000165 ObjCCompatibleAliasDecl::Create(Context, AtLoc, AliasName, CDecl);
166
167 ObjCAliasDecls[AliasName] = AliasDecl;
Anders Carlsson15281452008-11-04 16:57:32 +0000168
169 if (!CheckObjCDeclScope(AliasDecl))
170 TUScope->AddDecl(AliasDecl);
171
Chris Lattner4d391482007-12-12 07:09:47 +0000172 return AliasDecl;
173}
174
Chris Lattnere13b9592008-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 Dunbar246e70f2008-09-26 04:48:09 +0000181 SourceLocation EndProtoLoc,
182 AttributeList *AttrList) {
183 // FIXME: Deal with AttrList.
Chris Lattner4d391482007-12-12 07:09:47 +0000184 assert(ProtocolName && "Missing protocol identifier");
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000185 ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName];
Chris Lattner4d391482007-12-12 07:09:47 +0000186 if (PDecl) {
187 // Protocol already seen. Better be a forward protocol declaration
Chris Lattner439e71f2008-03-16 01:25:17 +0000188 if (!PDecl->isForwardDecl()) {
Chris Lattner4d391482007-12-12 07:09:47 +0000189 Diag(ProtocolLoc, diag::err_duplicate_protocol_def,
190 ProtocolName->getName());
Chris Lattner439e71f2008-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 Lattner4d391482007-12-12 07:09:47 +0000194 }
Steve Narofff11b5082008-08-13 16:39:22 +0000195 // Make sure the cached decl gets a valid start location.
196 PDecl->setLocation(AtProtoInterfaceLoc);
Chris Lattner439e71f2008-03-16 01:25:17 +0000197 PDecl->setForwardDecl(false);
Chris Lattner439e71f2008-03-16 01:25:17 +0000198 } else {
Chris Lattner780f3292008-07-21 21:32:27 +0000199 PDecl = ObjCProtocolDecl::Create(Context, AtProtoInterfaceLoc,ProtocolName);
Chris Lattnerc8581052008-03-16 20:19:15 +0000200 PDecl->setForwardDecl(false);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000201 ObjCProtocols[ProtocolName] = PDecl;
Chris Lattnercca59d72008-03-16 01:23:04 +0000202 }
Chris Lattner4d391482007-12-12 07:09:47 +0000203
204 if (NumProtoRefs) {
Chris Lattnerc8581052008-03-16 20:19:15 +0000205 /// Check then save referenced protocols.
Chris Lattnere13b9592008-07-26 04:03:38 +0000206 PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
Chris Lattner4d391482007-12-12 07:09:47 +0000207 PDecl->setLocEnd(EndProtoLoc);
208 }
Anders Carlsson15281452008-11-04 16:57:32 +0000209
210 CheckObjCDeclScope(PDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000211 return PDecl;
212}
213
214/// FindProtocolDeclaration - This routine looks up protocols and
Daniel Dunbar7ad1b1f2008-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 Lattner4d391482007-12-12 07:09:47 +0000217void
Chris Lattnere13b9592008-07-26 04:03:38 +0000218Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000219 const IdentifierLocPair *ProtocolId,
Chris Lattner4d391482007-12-12 07:09:47 +0000220 unsigned NumProtocols,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000221 llvm::SmallVectorImpl<DeclTy*> &Protocols) {
Chris Lattner4d391482007-12-12 07:09:47 +0000222 for (unsigned i = 0; i != NumProtocols; ++i) {
Chris Lattnereacc3922008-07-26 03:47:43 +0000223 ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i].first];
224 if (!PDecl) {
Chris Lattner7caeabd2008-07-21 22:17:28 +0000225 Diag(ProtocolId[i].second, diag::err_undeclared_protocol,
226 ProtocolId[i].first->getName());
Chris Lattnereacc3922008-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 Lattner4d391482007-12-12 07:09:47 +0000236 }
237}
238
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000239/// DiagnosePropertyMismatch - Compares two properties for their
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000240/// attributes and types and warns on a variety of inconsistencies.
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000241///
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000242void
243Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
244 ObjCPropertyDecl *SuperProperty,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000245 const char *inheritedName) {
Fariborz Jahanianb5e02242008-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 Jahanian02edb982008-05-01 00:03:38 +0000252 Diag(Property->getLocation(), diag::warn_readonly_property,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000253 Property->getName(), inheritedName);
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000254 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
255 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000256 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000257 Property->getName(), "copy", inheritedName,
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000258 SourceRange());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000259 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
260 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000261 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000262 Property->getName(), "retain", inheritedName,
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000263 SourceRange());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000264
265 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
266 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000267 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000268 Property->getName(), "atomic", inheritedName,
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000269 SourceRange());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000270 if (Property->getSetterName() != SuperProperty->getSetterName())
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000271 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000272 Property->getName(), "setter", inheritedName,
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000273 SourceRange());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000274 if (Property->getGetterName() != SuperProperty->getGetterName())
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000275 Diag(Property->getLocation(), diag::warn_property_attribute,
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000276 Property->getName(), "getter", inheritedName,
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000277 SourceRange());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000278
Chris Lattner717250a2008-07-26 20:50:02 +0000279 if (Context.getCanonicalType(Property->getType()) !=
280 Context.getCanonicalType(SuperProperty->getType()))
Fariborz Jahanian34350962008-05-01 18:05:01 +0000281 Diag(Property->getLocation(), diag::warn_property_type,
282 Property->getType().getAsString(),
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000283 inheritedName);
Fariborz Jahanianb5e02242008-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 Jahanian02edb982008-05-01 00:03:38 +0000292Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000293 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
294 if (!SDecl)
295 return;
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000296 // FIXME: O(N^2)
Fariborz Jahanian02edb982008-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 Jahanianb5e02242008-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())
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000305 DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl->getName());
Fariborz Jahanianb5e02242008-04-24 19:58:34 +0000306 }
307 }
308}
309
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000310/// MergeOneProtocolPropertiesIntoClass - This routine goes thru the list
311/// of properties declared in a protocol and adds them to the list
312/// of properties for current class if it is not there already.
313void
314Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
315 ObjCProtocolDecl *PDecl)
316{
317 llvm::SmallVector<ObjCPropertyDecl*, 16> mergeProperties;
318 for (ObjCProtocolDecl::classprop_iterator P = PDecl->classprop_begin(),
319 E = PDecl->classprop_end(); P != E; ++P) {
320 ObjCPropertyDecl *Pr = (*P);
321 ObjCInterfaceDecl::classprop_iterator CP, CE;
322 // Is this property already in class's list of properties?
323 for (CP = IDecl->classprop_begin(), CE = IDecl->classprop_end();
324 CP != CE; ++CP)
325 if ((*CP)->getIdentifier() == Pr->getIdentifier())
326 break;
327 if (CP == CE)
328 // Add this property to list of properties for thie class.
329 mergeProperties.push_back(Pr);
330 else
331 // Property protocol already exist in class. Diagnose any mismatch.
332 DiagnosePropertyMismatch((*CP), Pr, PDecl->getName());
333 }
334 IDecl->mergeProperties(&mergeProperties[0], mergeProperties.size());
335}
336
337/// MergeProtocolPropertiesIntoClass - This routine merges properties
338/// declared in 'MergeItsProtocols' objects (which can be a class or an
339/// inherited protocol into the list of properties for class 'IDecl'
340///
341
342void
343Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
344 DeclTy *MergeItsProtocols) {
345 Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols);
Chris Lattnerb752f282008-07-21 07:06:49 +0000346 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000347 for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
348 E = MDecl->protocol_end(); P != E; ++P)
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000349 // Merge properties of class (*P) into IDECL's
Chris Lattnerb752f282008-07-21 07:06:49 +0000350 MergeOneProtocolPropertiesIntoClass(IDecl, *P);
351
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000352 // Go thru the list of protocols for this class and recursively merge
353 // their properties into this class as well.
354 for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
355 E = IDecl->protocol_end(); P != E; ++P)
Chris Lattnerb752f282008-07-21 07:06:49 +0000356 MergeProtocolPropertiesIntoClass(IDecl, *P);
357 } else {
Argyrios Kyrtzidise8f0d302008-07-21 09:18:38 +0000358 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
359 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
360 E = MD->protocol_end(); P != E; ++P)
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000361 MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
Chris Lattnerb752f282008-07-21 07:06:49 +0000362 }
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000363}
364
Chris Lattner4d391482007-12-12 07:09:47 +0000365/// ActOnForwardProtocolDeclaration -
366Action::DeclTy *
367Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000368 const IdentifierLocPair *IdentList,
369 unsigned NumElts) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000370 llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
Chris Lattner4d391482007-12-12 07:09:47 +0000371
372 for (unsigned i = 0; i != NumElts; ++i) {
Chris Lattner7caeabd2008-07-21 22:17:28 +0000373 IdentifierInfo *Ident = IdentList[i].first;
Chris Lattnerc8581052008-03-16 20:19:15 +0000374 ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident];
Chris Lattner7caeabd2008-07-21 22:17:28 +0000375 if (PDecl == 0) // Not already seen?
376 PDecl = ObjCProtocolDecl::Create(Context, IdentList[i].second, Ident);
Chris Lattner4d391482007-12-12 07:09:47 +0000377
378 Protocols.push_back(PDecl);
379 }
Anders Carlsson15281452008-11-04 16:57:32 +0000380
381 ObjCForwardProtocolDecl *PDecl =
382 ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
383 &Protocols[0], Protocols.size());
384
385 CheckObjCDeclScope(PDecl);
386 return PDecl;
Chris Lattner4d391482007-12-12 07:09:47 +0000387}
388
Chris Lattner7caeabd2008-07-21 22:17:28 +0000389Sema::DeclTy *Sema::
390ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
391 IdentifierInfo *ClassName, SourceLocation ClassLoc,
392 IdentifierInfo *CategoryName,
393 SourceLocation CategoryLoc,
Chris Lattner6bd6d0b2008-07-26 04:07:02 +0000394 DeclTy * const *ProtoRefs,
Chris Lattner7caeabd2008-07-21 22:17:28 +0000395 unsigned NumProtoRefs,
396 SourceLocation EndProtoLoc) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000397 ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
Chris Lattner4d391482007-12-12 07:09:47 +0000398
Chris Lattner61f9d412008-03-16 20:34:23 +0000399 ObjCCategoryDecl *CDecl =
Chris Lattner68c82cf2008-03-16 20:47:45 +0000400 ObjCCategoryDecl::Create(Context, AtInterfaceLoc, CategoryName);
Chris Lattner4d391482007-12-12 07:09:47 +0000401 CDecl->setClassInterface(IDecl);
Fariborz Jahanian7c453b32008-01-17 20:33:24 +0000402
403 /// Check that class of this category is already completely declared.
404 if (!IDecl || IDecl->isForwardDecl())
405 Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
Steve Naroffd100c802008-06-05 15:03:27 +0000406 else {
Fariborz Jahanian7c453b32008-01-17 20:33:24 +0000407 /// Check for duplicate interface declaration for this category
408 ObjCCategoryDecl *CDeclChain;
409 for (CDeclChain = IDecl->getCategoryList(); CDeclChain;
410 CDeclChain = CDeclChain->getNextClassCategory()) {
Steve Naroffd100c802008-06-05 15:03:27 +0000411 if (CategoryName && CDeclChain->getIdentifier() == CategoryName) {
Steve Naroff74199b62008-06-05 04:33:44 +0000412 Diag(CategoryLoc, diag::warn_dup_category_def, ClassName->getName(),
Fariborz Jahanian7c453b32008-01-17 20:33:24 +0000413 CategoryName->getName());
414 break;
415 }
Chris Lattner4d391482007-12-12 07:09:47 +0000416 }
Steve Naroffd100c802008-06-05 15:03:27 +0000417 if (!CDeclChain)
418 CDecl->insertNextClassCategory();
Fariborz Jahanian7c453b32008-01-17 20:33:24 +0000419 }
Chris Lattner4d391482007-12-12 07:09:47 +0000420
421 if (NumProtoRefs) {
Chris Lattner6bd6d0b2008-07-26 04:07:02 +0000422 CDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
423 CDecl->setLocEnd(EndProtoLoc);
Chris Lattner4d391482007-12-12 07:09:47 +0000424 }
Anders Carlsson15281452008-11-04 16:57:32 +0000425
426 CheckObjCDeclScope(CDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000427 return CDecl;
428}
429
430/// ActOnStartCategoryImplementation - Perform semantic checks on the
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000431/// category implementation declaration and build an ObjCCategoryImplDecl
Chris Lattner4d391482007-12-12 07:09:47 +0000432/// object.
433Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
434 SourceLocation AtCatImplLoc,
435 IdentifierInfo *ClassName, SourceLocation ClassLoc,
436 IdentifierInfo *CatName, SourceLocation CatLoc) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000437 ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
Chris Lattner75c9cae2008-03-16 20:53:07 +0000438 ObjCCategoryImplDecl *CDecl =
439 ObjCCategoryImplDecl::Create(Context, AtCatImplLoc, CatName, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000440 /// Check that class of this category is already completely declared.
441 if (!IDecl || IDecl->isForwardDecl())
442 Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
443
444 /// TODO: Check that CatName, category name, is not used in another
445 // implementation.
Steve Naroffe84a8642008-09-28 14:55:53 +0000446 ObjCCategoryImpls.push_back(CDecl);
Anders Carlsson15281452008-11-04 16:57:32 +0000447
448 CheckObjCDeclScope(CDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000449 return CDecl;
450}
451
452Sema::DeclTy *Sema::ActOnStartClassImplementation(
453 SourceLocation AtClassImplLoc,
454 IdentifierInfo *ClassName, SourceLocation ClassLoc,
455 IdentifierInfo *SuperClassname,
456 SourceLocation SuperClassLoc) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000457 ObjCInterfaceDecl* IDecl = 0;
Chris Lattner4d391482007-12-12 07:09:47 +0000458 // Check for another declaration kind with the same name.
Steve Naroffb327ce02008-04-02 14:35:35 +0000459 Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000460 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +0000461 Diag(ClassLoc, diag::err_redefinition_different_kind,
462 ClassName->getName());
463 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
464 }
465 else {
466 // Is there an interface declaration of this class; if not, warn!
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000467 IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000468 if (!IDecl)
469 Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
470 }
471
472 // Check that super class name is valid class name
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000473 ObjCInterfaceDecl* SDecl = 0;
Chris Lattner4d391482007-12-12 07:09:47 +0000474 if (SuperClassname) {
475 // Check if a different kind of symbol declared in this scope.
Steve Naroffb327ce02008-04-02 14:35:35 +0000476 PrevDecl = LookupDecl(SuperClassname, Decl::IDNS_Ordinary, TUScope);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000477 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +0000478 Diag(SuperClassLoc, diag::err_redefinition_different_kind,
479 SuperClassname->getName());
480 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
481 }
482 else {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000483 SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000484 if (!SDecl)
485 Diag(SuperClassLoc, diag::err_undef_superclass,
486 SuperClassname->getName(), ClassName->getName());
487 else if (IDecl && IDecl->getSuperClass() != SDecl) {
488 // This implementation and its interface do not have the same
489 // super class.
490 Diag(SuperClassLoc, diag::err_conflicting_super_class,
491 SDecl->getName());
492 Diag(SDecl->getLocation(), diag::err_previous_definition);
493 }
494 }
495 }
496
497 if (!IDecl) {
498 // Legacy case of @implementation with no corresponding @interface.
499 // Build, chain & install the interface decl into the identifier.
Daniel Dunbarf6414922008-08-20 18:02:42 +0000500
501 // FIXME: Do we support attributes on the @implementation? If so
502 // we should copy them over.
Chris Lattnerb752f282008-07-21 07:06:49 +0000503 IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, ClassName,
Steve Naroffd6a07aa2008-04-11 19:35:35 +0000504 ClassLoc, false, true);
Steve Naroff31102512008-04-02 18:30:49 +0000505 ObjCInterfaceDecls[ClassName] = IDecl;
Chris Lattner4d391482007-12-12 07:09:47 +0000506 IDecl->setSuperClass(SDecl);
507 IDecl->setLocEnd(ClassLoc);
508
509 // Remember that this needs to be removed when the scope is popped.
510 TUScope->AddDecl(IDecl);
511 }
512
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000513 ObjCImplementationDecl* IMPDecl =
Chris Lattner75c9cae2008-03-16 20:53:07 +0000514 ObjCImplementationDecl::Create(Context, AtClassImplLoc, ClassName,
515 IDecl, SDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000516
Anders Carlsson15281452008-11-04 16:57:32 +0000517 if (CheckObjCDeclScope(IMPDecl))
518 return IMPDecl;
519
Chris Lattner4d391482007-12-12 07:09:47 +0000520 // Check that there is no duplicate implementation of this class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000521 if (ObjCImplementations[ClassName])
Chris Lattner75c9cae2008-03-16 20:53:07 +0000522 // FIXME: Don't leak everything!
Chris Lattner4d391482007-12-12 07:09:47 +0000523 Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
524 else // add it to the list.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000525 ObjCImplementations[ClassName] = IMPDecl;
Chris Lattner4d391482007-12-12 07:09:47 +0000526 return IMPDecl;
527}
528
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000529void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
530 ObjCIvarDecl **ivars, unsigned numIvars,
Chris Lattner4d391482007-12-12 07:09:47 +0000531 SourceLocation RBrace) {
532 assert(ImpDecl && "missing implementation decl");
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000533 ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(ImpDecl->getIdentifier());
Chris Lattner4d391482007-12-12 07:09:47 +0000534 if (!IDecl)
535 return;
536 /// Check case of non-existing @interface decl.
537 /// (legacy objective-c @implementation decl without an @interface decl).
538 /// Add implementations's ivar to the synthesize class's ivar list.
539 if (IDecl->ImplicitInterfaceDecl()) {
540 IDecl->addInstanceVariablesToClass(ivars, numIvars, RBrace);
541 return;
542 }
543 // If implementation has empty ivar list, just return.
544 if (numIvars == 0)
545 return;
546
547 assert(ivars && "missing @implementation ivars");
548
549 // Check interface's Ivar list against those in the implementation.
550 // names and types must match.
551 //
Chris Lattner4d391482007-12-12 07:09:47 +0000552 unsigned j = 0;
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000553 ObjCInterfaceDecl::ivar_iterator
Chris Lattner4c525092007-12-12 17:58:05 +0000554 IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end();
555 for (; numIvars > 0 && IVI != IVE; ++IVI) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000556 ObjCIvarDecl* ImplIvar = ivars[j++];
557 ObjCIvarDecl* ClsIvar = *IVI;
Chris Lattner4d391482007-12-12 07:09:47 +0000558 assert (ImplIvar && "missing implementation ivar");
559 assert (ClsIvar && "missing class ivar");
Chris Lattner1b63eef2008-07-27 00:05:05 +0000560 if (Context.getCanonicalType(ImplIvar->getType()) !=
561 Context.getCanonicalType(ClsIvar->getType())) {
Chris Lattner4d391482007-12-12 07:09:47 +0000562 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type,
563 ImplIvar->getIdentifier()->getName());
564 Diag(ClsIvar->getLocation(), diag::err_previous_definition,
565 ClsIvar->getIdentifier()->getName());
566 }
567 // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed
568 // as error.
569 else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
570 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name,
571 ImplIvar->getIdentifier()->getName());
572 Diag(ClsIvar->getLocation(), diag::err_previous_definition,
573 ClsIvar->getIdentifier()->getName());
Chris Lattner609e4c72007-12-12 18:11:49 +0000574 return;
Chris Lattner4d391482007-12-12 07:09:47 +0000575 }
576 --numIvars;
Chris Lattner4d391482007-12-12 07:09:47 +0000577 }
Chris Lattner609e4c72007-12-12 18:11:49 +0000578
579 if (numIvars > 0)
Chris Lattner0e391052007-12-12 18:19:52 +0000580 Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
Chris Lattner609e4c72007-12-12 18:11:49 +0000581 else if (IVI != IVE)
Chris Lattner0e391052007-12-12 18:19:52 +0000582 Diag((*IVI)->getLocation(), diag::err_inconsistant_ivar_count);
Chris Lattner4d391482007-12-12 07:09:47 +0000583}
584
Steve Naroff3c2eb662008-02-10 21:38:56 +0000585void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
586 bool &IncompleteImpl) {
587 if (!IncompleteImpl) {
588 Diag(ImpLoc, diag::warn_incomplete_impl);
589 IncompleteImpl = true;
590 }
591 Diag(ImpLoc, diag::warn_undef_method_impl, method->getSelector().getName());
592}
593
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000594/// FIXME: Type hierarchies in Objective-C can be deep. We could most
595/// likely improve the efficiency of selector lookups and type
596/// checking by associating with each protocol / interface / category
597/// the flattened instance tables. If we used an immutable set to keep
598/// the table then it wouldn't add significant memory cost and it
599/// would be handy for lookups.
600
Steve Naroffefe7f362008-02-08 22:06:17 +0000601/// CheckProtocolMethodDefs - This routine checks unimplemented methods
Chris Lattner4d391482007-12-12 07:09:47 +0000602/// Declared in protocol, and those referenced by it.
Steve Naroffefe7f362008-02-08 22:06:17 +0000603void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
604 ObjCProtocolDecl *PDecl,
Chris Lattner4d391482007-12-12 07:09:47 +0000605 bool& IncompleteImpl,
Steve Naroffefe7f362008-02-08 22:06:17 +0000606 const llvm::DenseSet<Selector> &InsMap,
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000607 const llvm::DenseSet<Selector> &ClsMap,
608 ObjCInterfaceDecl *IDecl) {
609 ObjCInterfaceDecl *Super = IDecl->getSuperClass();
610
611 // If a method lookup fails locally we still need to look and see if
612 // the method was implemented by a base class or an inherited
613 // protocol. This lookup is slow, but occurs rarely in correct code
614 // and otherwise would terminate in a warning.
615
Chris Lattner4d391482007-12-12 07:09:47 +0000616 // check unimplemented instance methods.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000617 for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
Steve Naroff58dbdeb2007-12-14 23:37:57 +0000618 E = PDecl->instmeth_end(); I != E; ++I) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000619 ObjCMethodDecl *method = *I;
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000620 if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
621 !InsMap.count(method->getSelector()) &&
622 (!Super || !Super->lookupInstanceMethod(method->getSelector())))
Steve Naroff3c2eb662008-02-10 21:38:56 +0000623 WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
Chris Lattner4d391482007-12-12 07:09:47 +0000624 }
625 // check unimplemented class methods
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000626 for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
Steve Naroff58dbdeb2007-12-14 23:37:57 +0000627 E = PDecl->classmeth_end(); I != E; ++I) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000628 ObjCMethodDecl *method = *I;
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000629 if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
630 !ClsMap.count(method->getSelector()) &&
631 (!Super || !Super->lookupClassMethod(method->getSelector())))
Steve Naroff3c2eb662008-02-10 21:38:56 +0000632 WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
Steve Naroff58dbdeb2007-12-14 23:37:57 +0000633 }
Chris Lattner780f3292008-07-21 21:32:27 +0000634 // Check on this protocols's referenced protocols, recursively.
635 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
636 E = PDecl->protocol_end(); PI != E; ++PI)
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000637 CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000638}
639
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000640void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
641 ObjCInterfaceDecl* IDecl) {
Chris Lattner4d391482007-12-12 07:09:47 +0000642 llvm::DenseSet<Selector> InsMap;
643 // Check and see if instance methods in class interface have been
644 // implemented in the implementation class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000645 for (ObjCImplementationDecl::instmeth_iterator I = IMPDecl->instmeth_begin(),
Chris Lattner4c525092007-12-12 17:58:05 +0000646 E = IMPDecl->instmeth_end(); I != E; ++I)
647 InsMap.insert((*I)->getSelector());
Chris Lattner4d391482007-12-12 07:09:47 +0000648
649 bool IncompleteImpl = false;
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000650 for (ObjCInterfaceDecl::instmeth_iterator I = IDecl->instmeth_begin(),
Chris Lattner4c525092007-12-12 17:58:05 +0000651 E = IDecl->instmeth_end(); I != E; ++I)
Fariborz Jahanian46070342008-05-07 20:53:44 +0000652 if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector()))
Steve Naroff3c2eb662008-02-10 21:38:56 +0000653 WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
Chris Lattner4c525092007-12-12 17:58:05 +0000654
Chris Lattner4d391482007-12-12 07:09:47 +0000655 llvm::DenseSet<Selector> ClsMap;
656 // Check and see if class methods in class interface have been
657 // implemented in the implementation class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000658 for (ObjCImplementationDecl::classmeth_iterator I =IMPDecl->classmeth_begin(),
Chris Lattner4c525092007-12-12 17:58:05 +0000659 E = IMPDecl->classmeth_end(); I != E; ++I)
660 ClsMap.insert((*I)->getSelector());
Chris Lattner4d391482007-12-12 07:09:47 +0000661
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000662 for (ObjCInterfaceDecl::classmeth_iterator I = IDecl->classmeth_begin(),
Chris Lattner4c525092007-12-12 17:58:05 +0000663 E = IDecl->classmeth_end(); I != E; ++I)
Steve Naroff3c2eb662008-02-10 21:38:56 +0000664 if (!ClsMap.count((*I)->getSelector()))
665 WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
Chris Lattner4d391482007-12-12 07:09:47 +0000666
667 // Check the protocol list for unimplemented methods in the @implementation
668 // class.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000669 const ObjCList<ObjCProtocolDecl> &Protocols =
670 IDecl->getReferencedProtocols();
671 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
672 E = Protocols.end(); I != E; ++I)
673 CheckProtocolMethodDefs(IMPDecl->getLocation(), *I,
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000674 IncompleteImpl, InsMap, ClsMap, IDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000675}
676
677/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000678/// category interface are implemented in the category @implementation.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000679void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
680 ObjCCategoryDecl *CatClassDecl) {
Chris Lattner4d391482007-12-12 07:09:47 +0000681 llvm::DenseSet<Selector> InsMap;
682 // Check and see if instance methods in category interface have been
683 // implemented in its implementation class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000684 for (ObjCCategoryImplDecl::instmeth_iterator I =CatImplDecl->instmeth_begin(),
Chris Lattner4c525092007-12-12 17:58:05 +0000685 E = CatImplDecl->instmeth_end(); I != E; ++I)
686 InsMap.insert((*I)->getSelector());
Chris Lattner4d391482007-12-12 07:09:47 +0000687
688 bool IncompleteImpl = false;
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000689 for (ObjCCategoryDecl::instmeth_iterator I = CatClassDecl->instmeth_begin(),
Steve Naroff58dbdeb2007-12-14 23:37:57 +0000690 E = CatClassDecl->instmeth_end(); I != E; ++I)
Steve Naroff3c2eb662008-02-10 21:38:56 +0000691 if (!InsMap.count((*I)->getSelector()))
692 WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
693
Chris Lattner4d391482007-12-12 07:09:47 +0000694 llvm::DenseSet<Selector> ClsMap;
695 // Check and see if class methods in category interface have been
696 // implemented in its implementation class.
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000697 for (ObjCCategoryImplDecl::classmeth_iterator
Chris Lattner4c525092007-12-12 17:58:05 +0000698 I = CatImplDecl->classmeth_begin(), E = CatImplDecl->classmeth_end();
699 I != E; ++I)
700 ClsMap.insert((*I)->getSelector());
Chris Lattner4d391482007-12-12 07:09:47 +0000701
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000702 for (ObjCCategoryDecl::classmeth_iterator I = CatClassDecl->classmeth_begin(),
Steve Naroff58dbdeb2007-12-14 23:37:57 +0000703 E = CatClassDecl->classmeth_end(); I != E; ++I)
Steve Naroff3c2eb662008-02-10 21:38:56 +0000704 if (!ClsMap.count((*I)->getSelector()))
705 WarnUndefinedMethod(CatImplDecl->getLocation(), *I, IncompleteImpl);
Chris Lattner4d391482007-12-12 07:09:47 +0000706
707 // Check the protocol list for unimplemented methods in the @implementation
708 // class.
Chris Lattner780f3292008-07-21 21:32:27 +0000709 for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),
710 E = CatClassDecl->protocol_end(); PI != E; ++PI)
711 CheckProtocolMethodDefs(CatImplDecl->getLocation(), *PI, IncompleteImpl,
Daniel Dunbar7ad1b1f2008-09-04 20:01:15 +0000712 InsMap, ClsMap, CatClassDecl->getClassInterface());
Chris Lattner4d391482007-12-12 07:09:47 +0000713}
714
715/// ActOnForwardClassDeclaration -
716Action::DeclTy *
717Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
718 IdentifierInfo **IdentList, unsigned NumElts)
719{
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000720 llvm::SmallVector<ObjCInterfaceDecl*, 32> Interfaces;
Chris Lattner4d391482007-12-12 07:09:47 +0000721
722 for (unsigned i = 0; i != NumElts; ++i) {
723 // Check for another declaration kind with the same name.
Steve Naroffb327ce02008-04-02 14:35:35 +0000724 Decl *PrevDecl = LookupDecl(IdentList[i], Decl::IDNS_Ordinary, TUScope);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000725 if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Steve Naroffc7333882008-06-05 22:57:10 +0000726 // GCC apparently allows the following idiom:
727 //
728 // typedef NSObject < XCElementTogglerP > XCElementToggler;
729 // @class XCElementToggler;
730 //
731 // FIXME: Make an extension?
732 TypedefDecl *TDD = dyn_cast<TypedefDecl>(PrevDecl);
733 if (!TDD || !isa<ObjCInterfaceType>(TDD->getUnderlyingType())) {
734 Diag(AtClassLoc, diag::err_redefinition_different_kind,
735 IdentList[i]->getName());
736 Diag(PrevDecl->getLocation(), diag::err_previous_definition);
737 }
Chris Lattner4d391482007-12-12 07:09:47 +0000738 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000739 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000740 if (!IDecl) { // Not already seen? Make a forward decl.
Chris Lattnerb752f282008-07-21 07:06:49 +0000741 IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, IdentList[i],
Steve Naroffd6a07aa2008-04-11 19:35:35 +0000742 SourceLocation(), true);
Steve Naroff31102512008-04-02 18:30:49 +0000743 ObjCInterfaceDecls[IdentList[i]] = IDecl;
Chris Lattner4d391482007-12-12 07:09:47 +0000744
745 // Remember that this needs to be removed when the scope is popped.
746 TUScope->AddDecl(IDecl);
747 }
748
749 Interfaces.push_back(IDecl);
750 }
751
Anders Carlsson15281452008-11-04 16:57:32 +0000752 ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, AtClassLoc,
753 &Interfaces[0],
754 Interfaces.size());
755
756 CheckObjCDeclScope(CDecl);
757 return CDecl;
Chris Lattner4d391482007-12-12 07:09:47 +0000758}
759
760
761/// MatchTwoMethodDeclarations - Checks that two methods have matching type and
762/// returns true, or false, accordingly.
763/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000764bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
Steve Narofffe6b0dc2008-10-21 10:37:50 +0000765 const ObjCMethodDecl *PrevMethod,
766 bool matchBasedOnSizeAndAlignment) {
767 QualType T1 = Context.getCanonicalType(Method->getResultType());
768 QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
769
770 if (T1 != T2) {
771 // The result types are different.
772 if (!matchBasedOnSizeAndAlignment)
Chris Lattner4d391482007-12-12 07:09:47 +0000773 return false;
Steve Narofffe6b0dc2008-10-21 10:37:50 +0000774 // Incomplete types don't have a size and alignment.
775 if (T1->isIncompleteType() || T2->isIncompleteType())
776 return false;
777 // Check is based on size and alignment.
778 if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
779 return false;
780 }
781 for (unsigned i = 0, e = Method->getNumParams(); i != e; ++i) {
782 T1 = Context.getCanonicalType(Method->getParamDecl(i)->getType());
783 T2 = Context.getCanonicalType(PrevMethod->getParamDecl(i)->getType());
784 if (T1 != T2) {
785 // The result types are different.
786 if (!matchBasedOnSizeAndAlignment)
787 return false;
788 // Incomplete types don't have a size and alignment.
789 if (T1->isIncompleteType() || T2->isIncompleteType())
790 return false;
791 // Check is based on size and alignment.
792 if (Context.getTypeInfo(T1) != Context.getTypeInfo(T2))
793 return false;
794 }
Chris Lattner4d391482007-12-12 07:09:47 +0000795 }
796 return true;
797}
798
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000799void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
800 ObjCMethodList &FirstMethod = InstanceMethodPool[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +0000801 if (!FirstMethod.Method) {
802 // Haven't seen a method with this selector name yet - add it.
803 FirstMethod.Method = Method;
804 FirstMethod.Next = 0;
805 } else {
806 // We've seen a method with this name, now check the type signature(s).
807 bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
808
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000809 for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
Chris Lattner4d391482007-12-12 07:09:47 +0000810 Next = Next->Next)
811 match = MatchTwoMethodDeclarations(Method, Next->Method);
812
813 if (!match) {
814 // We have a new signature for an existing method - add it.
815 // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000816 struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
Chris Lattner4d391482007-12-12 07:09:47 +0000817 FirstMethod.Next = OMI;
818 }
819 }
820}
821
Steve Naroff6f5f41c2008-10-21 10:50:19 +0000822// FIXME: Finish implementing -Wno-strict-selector-match.
Steve Naroff037cda52008-09-30 14:38:43 +0000823ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
824 SourceRange R) {
825 ObjCMethodList &MethList = InstanceMethodPool[Sel];
Steve Narofffe6b0dc2008-10-21 10:37:50 +0000826 bool issueWarning = false;
Steve Naroff037cda52008-09-30 14:38:43 +0000827
828 if (MethList.Method && MethList.Next) {
Steve Narofffe6b0dc2008-10-21 10:37:50 +0000829 for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
830 // This checks if the methods differ by size & alignment.
831 if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
832 issueWarning = true;
833 }
834 if (issueWarning && (MethList.Method && MethList.Next)) {
Steve Naroff037cda52008-09-30 14:38:43 +0000835 Diag(R.getBegin(), diag::warn_multiple_method_decl, Sel.getName(), R);
836 Diag(MethList.Method->getLocStart(), diag::warn_using_decl,
837 MethList.Method->getSourceRange());
838 for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
839 Diag(Next->Method->getLocStart(), diag::warn_also_found_decl,
840 Next->Method->getSourceRange());
841 }
842 return MethList.Method;
843}
844
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000845void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
846 ObjCMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +0000847 if (!FirstMethod.Method) {
848 // Haven't seen a method with this selector name yet - add it.
849 FirstMethod.Method = Method;
850 FirstMethod.Next = 0;
851 } else {
852 // We've seen a method with this name, now check the type signature(s).
853 bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
854
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000855 for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
Chris Lattner4d391482007-12-12 07:09:47 +0000856 Next = Next->Next)
857 match = MatchTwoMethodDeclarations(Method, Next->Method);
858
859 if (!match) {
860 // We have a new signature for an existing method - add it.
861 // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000862 struct ObjCMethodList *OMI = new ObjCMethodList(Method, FirstMethod.Next);
Chris Lattner4d391482007-12-12 07:09:47 +0000863 FirstMethod.Next = OMI;
864 }
865 }
866}
867
Steve Naroffa56f6162007-12-18 01:30:32 +0000868// Note: For class/category implemenations, allMethods/allProperties is
869// always null.
Chris Lattner4d391482007-12-12 07:09:47 +0000870void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
871 DeclTy **allMethods, unsigned allNum,
872 DeclTy **allProperties, unsigned pNum) {
873 Decl *ClassDecl = static_cast<Decl *>(classDecl);
874
Steve Naroffa56f6162007-12-18 01:30:32 +0000875 // FIXME: If we don't have a ClassDecl, we have an error. We should consider
876 // always passing in a decl. If the decl has an error, isInvalidDecl()
Chris Lattner4d391482007-12-12 07:09:47 +0000877 // should be true.
878 if (!ClassDecl)
879 return;
880
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000881 llvm::SmallVector<ObjCMethodDecl*, 32> insMethods;
882 llvm::SmallVector<ObjCMethodDecl*, 16> clsMethods;
Chris Lattner4d391482007-12-12 07:09:47 +0000883
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000884 llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
885 llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
Chris Lattner4d391482007-12-12 07:09:47 +0000886
887 bool isInterfaceDeclKind =
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000888 isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
889 || isa<ObjCProtocolDecl>(ClassDecl);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000890 bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000891
Seo Sanghyeonfe5042e2008-07-05 02:01:25 +0000892 if (pNum != 0) {
Chris Lattner55d13b42008-03-16 21:23:50 +0000893 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
894 IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000895 else if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
896 CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
897 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(ClassDecl))
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000898 PDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000899 else
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000900 assert(false && "ActOnAtEnd - property declaration misplaced");
Seo Sanghyeonfe5042e2008-07-05 02:01:25 +0000901 }
Chris Lattner4d391482007-12-12 07:09:47 +0000902
903 for (unsigned i = 0; i < allNum; i++ ) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000904 ObjCMethodDecl *Method =
905 cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i]));
Chris Lattner4d391482007-12-12 07:09:47 +0000906
907 if (!Method) continue; // Already issued a diagnostic.
908 if (Method->isInstance()) {
909 /// Check for instance method of the same name with incompatible types
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000910 const ObjCMethodDecl *&PrevMethod = InsMap[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +0000911 bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
912 : false;
913 if (isInterfaceDeclKind && PrevMethod && !match
914 || checkIdenticalMethods && match) {
915 Diag(Method->getLocation(), diag::error_duplicate_method_decl,
916 Method->getSelector().getName());
917 Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
918 } else {
919 insMethods.push_back(Method);
920 InsMap[Method->getSelector()] = Method;
921 /// The following allows us to typecheck messages to "id".
922 AddInstanceMethodToGlobalPool(Method);
923 }
924 }
925 else {
926 /// Check for class method of the same name with incompatible types
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000927 const ObjCMethodDecl *&PrevMethod = ClsMap[Method->getSelector()];
Chris Lattner4d391482007-12-12 07:09:47 +0000928 bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod)
929 : false;
930 if (isInterfaceDeclKind && PrevMethod && !match
931 || checkIdenticalMethods && match) {
932 Diag(Method->getLocation(), diag::error_duplicate_method_decl,
933 Method->getSelector().getName());
934 Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
935 } else {
936 clsMethods.push_back(Method);
937 ClsMap[Method->getSelector()] = Method;
Steve Naroffa56f6162007-12-18 01:30:32 +0000938 /// The following allows us to typecheck messages to "Class".
939 AddFactoryMethodToGlobalPool(Method);
Chris Lattner4d391482007-12-12 07:09:47 +0000940 }
941 }
942 }
Steve Naroff5e0a74f2008-09-29 14:20:56 +0000943 // Save the size so we can detect if we've added any property methods.
944 unsigned int insMethodsSizePriorToPropAdds = insMethods.size();
945 unsigned int clsMethodsSizePriorToPropAdds = clsMethods.size();
Chris Lattner4d391482007-12-12 07:09:47 +0000946
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000947 if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000948 // Compares properties declared in this class to those of its
Fariborz Jahanian02edb982008-05-01 00:03:38 +0000949 // super class.
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000950 ComparePropertiesInBaseAndSuper(I);
951 MergeProtocolPropertiesIntoClass(I, I);
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000952 for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
953 e = I->classprop_end(); i != e; ++i)
954 I->addPropertyMethods(Context, *i, insMethods);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000955 I->addMethods(&insMethods[0], insMethods.size(),
956 &clsMethods[0], clsMethods.size(), AtEndLoc);
957
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000958 } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000959 for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
960 e = P->classprop_end(); i != e; ++i)
961 P->addPropertyMethods(Context, *i, insMethods);
Chris Lattner4d391482007-12-12 07:09:47 +0000962 P->addMethods(&insMethods[0], insMethods.size(),
963 &clsMethods[0], clsMethods.size(), AtEndLoc);
964 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000965 else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000966 // FIXME: Need to compare properties to those in interface?
967
968 // FIXME: If we merge properties into class we should probably
969 // merge them into category as well?
970 for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
971 e = C->classprop_end(); i != e; ++i)
972 C->addPropertyMethods(Context, *i, insMethods);
Chris Lattner4d391482007-12-12 07:09:47 +0000973 C->addMethods(&insMethods[0], insMethods.size(),
974 &clsMethods[0], clsMethods.size(), AtEndLoc);
975 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000976 else if (ObjCImplementationDecl *IC =
977 dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +0000978 IC->setLocEnd(AtEndLoc);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000979 if (ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
Chris Lattner4d391482007-12-12 07:09:47 +0000980 ImplMethodsVsClassMethods(IC, IDecl);
981 } else {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000982 ObjCCategoryImplDecl* CatImplClass = cast<ObjCCategoryImplDecl>(ClassDecl);
Chris Lattner4d391482007-12-12 07:09:47 +0000983 CatImplClass->setLocEnd(AtEndLoc);
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000984 ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface();
Chris Lattner4d391482007-12-12 07:09:47 +0000985 // Find category interface decl and then check that all methods declared
Daniel Dunbarb20ef3e2008-08-27 05:40:03 +0000986 // in this interface are implemented in the category @implementation.
Chris Lattner4d391482007-12-12 07:09:47 +0000987 if (IDecl) {
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000988 for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
Chris Lattner4d391482007-12-12 07:09:47 +0000989 Categories; Categories = Categories->getNextClassCategory()) {
990 if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
991 ImplCategoryMethodsVsIntfMethods(CatImplClass, Categories);
992 break;
993 }
994 }
995 }
996 }
Steve Naroff5e0a74f2008-09-29 14:20:56 +0000997 // Add any synthesized methods to the global pool. This allows us to
998 // handle the following, which is supported by GCC (and part of the design).
999 //
1000 // @interface Foo
1001 // @property double bar;
1002 // @end
1003 //
1004 // void thisIsUnfortunate() {
1005 // id foo;
1006 // double bar = [foo bar];
1007 // }
1008 //
1009 if (insMethodsSizePriorToPropAdds < insMethods.size())
1010 for (unsigned i = insMethodsSizePriorToPropAdds; i < insMethods.size(); i++)
1011 AddInstanceMethodToGlobalPool(insMethods[i]);
1012 if (clsMethodsSizePriorToPropAdds < clsMethods.size())
1013 for (unsigned i = clsMethodsSizePriorToPropAdds; i < clsMethods.size(); i++)
1014 AddFactoryMethodToGlobalPool(clsMethods[i]);
Chris Lattner4d391482007-12-12 07:09:47 +00001015}
1016
1017
1018/// CvtQTToAstBitMask - utility routine to produce an AST bitmask for
1019/// objective-c's type qualifier from the parser version of the same info.
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001020static Decl::ObjCDeclQualifier
1021CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
1022 Decl::ObjCDeclQualifier ret = Decl::OBJC_TQ_None;
1023 if (PQTVal & ObjCDeclSpec::DQ_In)
1024 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_In);
1025 if (PQTVal & ObjCDeclSpec::DQ_Inout)
1026 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Inout);
1027 if (PQTVal & ObjCDeclSpec::DQ_Out)
1028 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Out);
1029 if (PQTVal & ObjCDeclSpec::DQ_Bycopy)
1030 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Bycopy);
1031 if (PQTVal & ObjCDeclSpec::DQ_Byref)
1032 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Byref);
1033 if (PQTVal & ObjCDeclSpec::DQ_Oneway)
1034 ret = (Decl::ObjCDeclQualifier)(ret | Decl::OBJC_TQ_Oneway);
Chris Lattner4d391482007-12-12 07:09:47 +00001035
1036 return ret;
1037}
1038
1039Sema::DeclTy *Sema::ActOnMethodDeclaration(
1040 SourceLocation MethodLoc, SourceLocation EndLoc,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001041 tok::TokenKind MethodType, DeclTy *classDecl,
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001042 ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
Chris Lattner4d391482007-12-12 07:09:47 +00001043 Selector Sel,
1044 // optional arguments. The number of types/arguments is obtained
1045 // from the Sel.getNumArgs().
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001046 ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
Chris Lattner4d391482007-12-12 07:09:47 +00001047 AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
1048 bool isVariadic) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001049 Decl *ClassDecl = static_cast<Decl*>(classDecl);
Steve Naroffda323ad2008-02-29 21:48:07 +00001050
1051 // Make sure we can establish a context for the method.
1052 if (!ClassDecl) {
1053 Diag(MethodLoc, diag::error_missing_method_context);
1054 return 0;
1055 }
Chris Lattner4d391482007-12-12 07:09:47 +00001056 QualType resultDeclType;
1057
1058 if (ReturnType)
1059 resultDeclType = QualType::getFromOpaquePtr(ReturnType);
1060 else // get the type for "id".
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001061 resultDeclType = Context.getObjCIdType();
Chris Lattner4d391482007-12-12 07:09:47 +00001062
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001063 ObjCMethodDecl* ObjCMethod =
1064 ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
Daniel Dunbarf6414922008-08-20 18:02:42 +00001065 ClassDecl,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001066 MethodType == tok::minus, isVariadic,
Fariborz Jahanian46070342008-05-07 20:53:44 +00001067 false,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001068 MethodDeclKind == tok::objc_optional ?
1069 ObjCMethodDecl::Optional :
1070 ObjCMethodDecl::Required);
1071
Chris Lattner0ed844b2008-04-04 06:12:32 +00001072 llvm::SmallVector<ParmVarDecl*, 16> Params;
1073
1074 for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
1075 // FIXME: arg->AttrList must be stored too!
1076 QualType argType;
1077
1078 if (ArgTypes[i])
1079 argType = QualType::getFromOpaquePtr(ArgTypes[i]);
1080 else
1081 argType = Context.getObjCIdType();
1082 ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
1083 SourceLocation(/*FIXME*/),
1084 ArgNames[i], argType,
Chris Lattner04421082008-04-08 04:40:51 +00001085 VarDecl::None, 0, 0);
Chris Lattner0ed844b2008-04-04 06:12:32 +00001086 Param->setObjCDeclQualifier(
1087 CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
1088 Params.push_back(Param);
1089 }
1090
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001091 ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
1092 ObjCMethod->setObjCDeclQualifier(
1093 CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
1094 const ObjCMethodDecl *PrevMethod = 0;
Daniel Dunbar35682492008-09-26 04:12:28 +00001095
1096 if (AttrList)
1097 ProcessDeclAttributeList(ObjCMethod, AttrList);
Chris Lattner4d391482007-12-12 07:09:47 +00001098
1099 // For implementations (which can be very "coarse grain"), we add the
1100 // method now. This allows the AST to implement lookup methods that work
1101 // incrementally (without waiting until we parse the @end). It also allows
1102 // us to flag multiple declaration errors as they occur.
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001103 if (ObjCImplementationDecl *ImpDecl =
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001104 dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +00001105 if (MethodType == tok::minus) {
Steve Naroff94a5c332007-12-19 22:27:04 +00001106 PrevMethod = ImpDecl->getInstanceMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001107 ImpDecl->addInstanceMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001108 } else {
Steve Naroff94a5c332007-12-19 22:27:04 +00001109 PrevMethod = ImpDecl->getClassMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001110 ImpDecl->addClassMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001111 }
1112 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001113 else if (ObjCCategoryImplDecl *CatImpDecl =
Chris Lattner6c4ae5d2008-03-16 00:49:28 +00001114 dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
Chris Lattner4d391482007-12-12 07:09:47 +00001115 if (MethodType == tok::minus) {
Steve Naroff94a5c332007-12-19 22:27:04 +00001116 PrevMethod = CatImpDecl->getInstanceMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001117 CatImpDecl->addInstanceMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001118 } else {
Steve Naroff94a5c332007-12-19 22:27:04 +00001119 PrevMethod = CatImpDecl->getClassMethod(Sel);
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001120 CatImpDecl->addClassMethod(ObjCMethod);
Chris Lattner4d391482007-12-12 07:09:47 +00001121 }
1122 }
1123 if (PrevMethod) {
1124 // You can never have two method definitions with the same name.
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001125 Diag(ObjCMethod->getLocation(), diag::error_duplicate_method_decl,
1126 ObjCMethod->getSelector().getName());
Chris Lattner4d391482007-12-12 07:09:47 +00001127 Diag(PrevMethod->getLocation(), diag::err_previous_declaration);
1128 }
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001129 return ObjCMethod;
Chris Lattner4d391482007-12-12 07:09:47 +00001130}
1131
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001132void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
1133 SourceLocation Loc,
1134 unsigned &Attributes) {
1135 // FIXME: Improve the reported location.
1136
1137 // readonly and readwrite conflict.
1138 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1139 (Attributes & ObjCDeclSpec::DQ_PR_readwrite)) {
1140 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1141 "readonly", "readwrite");
1142 Attributes ^= ObjCDeclSpec::DQ_PR_readonly;
1143 }
1144
1145 // Check for copy or retain on non-object types.
1146 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
1147 !Context.isObjCObjectPointerType(PropertyTy)) {
1148 Diag(Loc, diag::err_objc_property_requires_object,
1149 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
1150 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
1151 }
1152
1153 // Check for more than one of { assign, copy, retain }.
1154 if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
1155 if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1156 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1157 "assign", "copy");
1158 Attributes ^= ObjCDeclSpec::DQ_PR_copy;
1159 }
1160 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1161 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1162 "assign", "retain");
1163 Attributes ^= ObjCDeclSpec::DQ_PR_retain;
1164 }
1165 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1166 if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1167 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive,
1168 "copy", "retain");
1169 Attributes ^= ObjCDeclSpec::DQ_PR_retain;
1170 }
1171 }
1172
1173 // Warn if user supplied no assignment attribute, property is
1174 // readwrite, and this is an object type.
1175 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
1176 ObjCDeclSpec::DQ_PR_retain)) &&
1177 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1178 Context.isObjCObjectPointerType(PropertyTy)) {
1179 // Skip this warning in gc-only mode.
1180 if (getLangOptions().getGCMode() != LangOptions::GCOnly)
1181 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
1182
1183 // If non-gc code warn that this is likely inappropriate.
1184 if (getLangOptions().getGCMode() == LangOptions::NonGC)
1185 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
1186
1187 // FIXME: Implement warning dependent on NSCopying being
1188 // implemented. See also:
1189 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
1190 // (please trim this list while you are at it).
1191 }
1192}
1193
Fariborz Jahanian1de1e742008-04-14 23:36:35 +00001194Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
1195 FieldDeclarator &FD,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +00001196 ObjCDeclSpec &ODS,
Fariborz Jahanian5251e132008-05-06 18:09:04 +00001197 Selector GetterSel,
1198 Selector SetterSel,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +00001199 tok::ObjCKeywordKind MethodImplKind) {
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +00001200 QualType T = GetTypeForDeclarator(FD.D, S);
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001201 unsigned Attributes = ODS.getPropertyAttributes();
1202
1203 // May modify Attributes.
1204 CheckObjCPropertyAttributes(T, AtLoc, Attributes);
1205
Fariborz Jahanian1de1e742008-04-14 23:36:35 +00001206 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, AtLoc,
1207 FD.D.getIdentifier(), T);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +00001208 // Regardless of setter/getter attribute, we save the default getter/setter
1209 // selector names in anticipation of declaration of setter/getter methods.
1210 PDecl->setGetterName(GetterSel);
1211 PDecl->setSetterName(SetterSel);
Chris Lattner4d391482007-12-12 07:09:47 +00001212
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001213 if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001214 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
Chris Lattner4d391482007-12-12 07:09:47 +00001215
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001216 if (Attributes & ObjCDeclSpec::DQ_PR_getter)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001217 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
Chris Lattner4d391482007-12-12 07:09:47 +00001218
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001219 if (Attributes & ObjCDeclSpec::DQ_PR_setter)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001220 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
Chris Lattner4d391482007-12-12 07:09:47 +00001221
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001222 if (Attributes & ObjCDeclSpec::DQ_PR_assign)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001223 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
Chris Lattner4d391482007-12-12 07:09:47 +00001224
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001225 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001226 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
Chris Lattner4d391482007-12-12 07:09:47 +00001227
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001228 if (Attributes & ObjCDeclSpec::DQ_PR_retain)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001229 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
Chris Lattner4d391482007-12-12 07:09:47 +00001230
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001231 if (Attributes & ObjCDeclSpec::DQ_PR_copy)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001232 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
Chris Lattner4d391482007-12-12 07:09:47 +00001233
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001234 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
Ted Kremeneka526c5c2008-01-07 19:49:32 +00001235 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
Chris Lattner4d391482007-12-12 07:09:47 +00001236
Fariborz Jahanian46b55e52008-05-05 18:51:55 +00001237 if (MethodImplKind == tok::objc_required)
1238 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
1239 else if (MethodImplKind == tok::objc_optional)
1240 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
1241
Chris Lattner4d391482007-12-12 07:09:47 +00001242 return PDecl;
1243}
1244
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001245/// ActOnPropertyImplDecl - This routine performs semantic checks and
1246/// builds the AST node for a property implementation declaration; declared
1247/// as @synthesize or @dynamic.
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001248///
1249Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
1250 SourceLocation PropertyLoc,
1251 bool Synthesize,
1252 DeclTy *ClassCatImpDecl,
1253 IdentifierInfo *PropertyId,
1254 IdentifierInfo *PropertyIvar) {
1255 Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
1256 // Make sure we have a context for the property implementation declaration.
1257 if (!ClassImpDecl) {
1258 Diag(AtLoc, diag::error_missing_property_context);
1259 return 0;
1260 }
1261 ObjCPropertyDecl *property = 0;
1262 ObjCInterfaceDecl* IDecl = 0;
1263 // Find the class or category class where this property must have
1264 // a declaration.
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001265 ObjCImplementationDecl *IC = 0;
1266 ObjCCategoryImplDecl* CatImplClass = 0;
1267 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001268 IDecl = getObjCInterfaceDecl(IC->getIdentifier());
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001269 // We always synthesize an interface for an implementation
1270 // without an interface decl. So, IDecl is always non-zero.
1271 assert(IDecl &&
1272 "ActOnPropertyImplDecl - @implementation without @interface");
1273
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001274 // Look for this property declaration in the @implementation's @interface
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001275 property = IDecl->FindPropertyDeclaration(PropertyId);
1276 if (!property) {
Daniel Dunbar95e61fb2008-09-23 21:53:23 +00001277 Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName());
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001278 return 0;
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001279 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001280 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001281 else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001282 if (Synthesize) {
1283 Diag(AtLoc, diag::error_synthesize_category_decl);
1284 return 0;
1285 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001286 IDecl = CatImplClass->getClassInterface();
1287 if (!IDecl) {
1288 Diag(AtLoc, diag::error_missing_property_interface);
1289 return 0;
1290 }
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001291 ObjCCategoryDecl *Category =
1292 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
1293
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001294 // If category for this implementation not found, it is an error which
1295 // has already been reported eralier.
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001296 if (!Category)
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001297 return 0;
1298 // Look for this property declaration in @implementation's category
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001299 property = Category->FindPropertyDeclaration(PropertyId);
1300 if (!property) {
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001301 Diag(PropertyLoc, diag::error_bad_category_property_decl,
Fariborz Jahanian559c0c42008-04-21 19:04:53 +00001302 Category->getName());
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001303 return 0;
1304 }
1305 }
1306 else {
1307 Diag(AtLoc, diag::error_bad_property_context);
1308 return 0;
1309 }
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001310 ObjCIvarDecl *Ivar = 0;
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001311 // Check that we have a valid, previously declared ivar for @synthesize
1312 if (Synthesize) {
1313 // @synthesize
Fariborz Jahanian6cdf16d2008-04-21 21:57:36 +00001314 if (!PropertyIvar)
1315 PropertyIvar = PropertyId;
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001316 // Check that this is a previously declared 'ivar' in 'IDecl' interface
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001317 Ivar = IDecl->FindIvarDeclaration(PropertyIvar);
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001318 if (!Ivar) {
Fariborz Jahanian6cdf16d2008-04-21 21:57:36 +00001319 Diag(PropertyLoc, diag::error_missing_property_ivar_decl,
1320 PropertyId->getName());
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001321 return 0;
1322 }
Steve Naroff3ce52d62008-09-30 10:07:56 +00001323 QualType PropType = Context.getCanonicalType(property->getType());
1324 QualType IvarType = Context.getCanonicalType(Ivar->getType());
1325
Steve Narofffbbe0ac2008-09-30 00:24:17 +00001326 // Check that type of property and its ivar are type compatible.
Steve Naroff3ce52d62008-09-30 10:07:56 +00001327 if (PropType != IvarType) {
Steve Naroff4fa4ab62008-10-16 14:59:30 +00001328 if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
Steve Naroff3ce52d62008-09-30 10:07:56 +00001329 Diag(PropertyLoc, diag::error_property_ivar_type, property->getName(),
1330 Ivar->getName());
1331 return 0;
1332 }
Fariborz Jahanianc35b9e42008-04-21 21:05:54 +00001333 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001334 } else if (PropertyIvar) {
1335 // @dynamic
1336 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
1337 return 0;
1338 }
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001339 assert (property && "ActOnPropertyImplDecl - property declaration missing");
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001340 ObjCPropertyImplDecl *PIDecl =
1341 ObjCPropertyImplDecl::Create(Context, AtLoc, PropertyLoc, property,
1342 (Synthesize ?
Daniel Dunbar9f0afd42008-08-26 04:47:31 +00001343 ObjCPropertyImplDecl::Synthesize
1344 : ObjCPropertyImplDecl::Dynamic),
1345 Ivar);
Fariborz Jahanian628b96f2008-04-23 00:06:01 +00001346 if (IC)
1347 IC->addPropertyImplementation(PIDecl);
1348 else
1349 CatImplClass->addPropertyImplementation(PIDecl);
1350
1351 return PIDecl;
Fariborz Jahanianf624f812008-04-18 00:19:30 +00001352}
Anders Carlsson15281452008-11-04 16:57:32 +00001353
1354bool Sema::CheckObjCDeclScope(Decl *D)
1355{
1356 if (isa<TranslationUnitDecl>(CurContext))
1357 return false;
1358
1359 Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
1360 D->setInvalidDecl();
1361
1362 return true;
1363}