 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
67.6% |
184 / 272 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
81.6% |
222 / 272 |
| |
|
Line Coverage: |
81.1% |
296 / 365 |
| |
 |
|
 |
1 : //===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the Objective-C related Decl classes.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/AST/DeclObjC.h"
15 : #include "clang/AST/ASTContext.h"
16 : #include "clang/AST/Stmt.h"
17 : #include "llvm/ADT/STLExtras.h"
18 : using namespace clang;
19 :
20 : //===----------------------------------------------------------------------===//
21 : // ObjCListBase
22 : //===----------------------------------------------------------------------===//
23 :
24 18: void ObjCListBase::Destroy(ASTContext &Ctx) {
25 18: Ctx.Deallocate(List);
26 18: NumElts = 0;
27 18: List = 0;
28 18: }
29 :
30 4864: void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
0: branch 0 not taken
4864: branch 1 taken
31 4864: assert(List == 0 && "Elements already set!");
2599: branch 0 taken
2265: branch 1 taken
32 4864: if (Elts == 0) return; // Setting to an empty list is a noop.
33 :
34 :
35 2599: List = new (Ctx) void*[Elts];
36 2599: NumElts = Elts;
37 2599: memcpy(List, InList, sizeof(void*)*Elts);
38 : }
39 :
40 : void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
41 631: const SourceLocation *Locs, ASTContext &Ctx) {
32: branch 0 taken
599: branch 1 taken
42 631: if (Elts == 0)
43 32: return;
44 :
599: branch 1 taken
0: branch 2 not taken
889: branch 4 taken
599: branch 5 taken
45 599: Locations = new (Ctx) SourceLocation[Elts];
46 599: memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
47 599: set(InList, Elts, Ctx);
48 : }
49 :
50 2: void ObjCProtocolList::Destroy(ASTContext &Ctx) {
51 2: Ctx.Deallocate(Locations);
52 2: Locations = 0;
53 2: ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
54 2: }
55 :
56 : //===----------------------------------------------------------------------===//
57 : // ObjCInterfaceDecl
58 : //===----------------------------------------------------------------------===//
59 :
60 : /// getIvarDecl - This method looks up an ivar in this ContextDecl.
61 : ///
62 : ObjCIvarDecl *
63 3952: ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
64 : lookup_const_iterator Ivar, IvarEnd;
808: branch 4 taken
3209: branch 5 taken
65 4017: for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
743: branch 1 taken
65: branch 2 taken
66 808: if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
67 743: return ivar;
68 : }
69 3209: return 0;
70 : }
71 :
72 : // Get the local instance/class method declared in this interface.
73 : ObjCMethodDecl *
74 11843: ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
75 : // Since instance & class methods can have the same name, the loop below
76 : // ensures we get the correct method.
77 : //
78 : // @interface Whatever
79 : // - (int) class_method;
80 : // + (float) class_method;
81 : // @end
82 : //
83 : lookup_const_iterator Meth, MethEnd;
4014: branch 4 taken
7955: branch 5 taken
84 11969: for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
85 4014: ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
4014: branch 0 taken
0: branch 1 not taken
3888: branch 3 taken
126: branch 4 taken
3888: branch 5 taken
126: branch 6 taken
86 4014: if (MD && MD->isInstanceMethod() == isInstance)
87 3888: return MD;
88 : }
89 7955: return 0;
90 : }
91 :
92 : /// FindPropertyDeclaration - Finds declaration of the property given its name
93 : /// in 'PropertyId' and returns it. It returns 0, if not found.
94 : /// FIXME: Convert to DeclContext lookup...
95 : ///
96 : ObjCPropertyDecl *
97 770: ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
3643: branch 4 taken
318: branch 5 taken
98 3961: for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
452: branch 2 taken
3191: branch 3 taken
99 3643: if ((*I)->getIdentifier() == PropertyId)
100 452: return *I;
101 :
102 318: const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
67: branch 0 taken
251: branch 1 taken
103 318: if (PID) {
10: branch 1 taken
60: branch 2 taken
104 137: for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
105 67: E = PID->protocol_end(); I != E; ++I)
7: branch 1 taken
3: branch 2 taken
106 10: if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
107 7: return P;
108 : }
109 :
208: branch 1 taken
103: branch 2 taken
110 311: if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
111 : // Look through categories.
41: branch 2 taken
205: branch 3 taken
112 246: for (ObjCCategoryDecl *Category = OID->getCategoryList();
113 : Category; Category = Category->getNextClassCategory()) {
3: branch 1 taken
38: branch 2 taken
114 41: if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
115 3: return P;
116 : }
117 : // Look through protocols.
78: branch 1 taken
178: branch 2 taken
118 461: for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
119 205: E = OID->protocol_end(); I != E; ++I) {
27: branch 1 taken
51: branch 2 taken
120 78: if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
121 27: return P;
122 : }
106: branch 1 taken
72: branch 2 taken
123 178: if (OID->getSuperClass())
124 106: return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
43: branch 1 taken
60: branch 2 taken
125 103: } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
126 : // Look through protocols.
1: branch 1 taken
42: branch 2 taken
127 86: for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
128 43: E = OCD->protocol_end(); I != E; ++I) {
1: branch 1 taken
0: branch 2 not taken
129 1: if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
130 1: return P;
131 : }
132 : }
133 174: return 0;
134 : }
135 :
136 : /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
137 : /// with name 'PropertyId' in the primary class; including those in protocols
138 : /// (direct or indirect) used by the promary class.
139 : /// FIXME: Convert to DeclContext lookup...
140 : ///
141 : ObjCPropertyDecl *
142 : ObjCContainerDecl::FindPropertyVisibleInPrimaryClass(
143 47: IdentifierInfo *PropertyId) const {
47: branch 1 taken
0: branch 2 not taken
144 47: assert(isa<ObjCInterfaceDecl>(this) && "FindPropertyVisibleInPrimaryClass");
1090: branch 4 taken
15: branch 5 taken
145 1105: for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
32: branch 2 taken
1058: branch 3 taken
146 1090: if ((*I)->getIdentifier() == PropertyId)
147 32: return *I;
148 15: const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
149 : // Look through protocols.
4: branch 1 taken
11: branch 2 taken
150 30: for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
151 15: E = OID->protocol_end(); I != E; ++I)
4: branch 1 taken
0: branch 2 not taken
152 4: if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
153 4: return P;
154 11: return 0;
155 : }
156 :
157 : void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
158 : ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
159 : const SourceLocation *Locs,
160 5: ASTContext &C)
161 : {
3: branch 1 taken
2: branch 2 taken
162 5: if (ReferencedProtocols.empty()) {
163 3: ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
164 3: return;
165 : }
166 : // Check for duplicate protocol in class's protocol list.
167 : // This is (O)2. But it is extremely rare and number of protocols in
168 : // class or its extension are very few.
169 2: llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
170 2: llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
4: branch 0 taken
2: branch 1 taken
171 6: for (unsigned i = 0; i < ExtNum; i++) {
172 4: bool protocolExists = false;
173 4: ObjCProtocolDecl *ProtoInExtension = ExtList[i];
4: branch 2 taken
2: branch 3 taken
174 6: for (protocol_iterator p = protocol_begin(), e = protocol_end();
175 : p != e; p++) {
176 4: ObjCProtocolDecl *Proto = (*p);
2: branch 1 taken
2: branch 2 taken
177 4: if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
178 2: protocolExists = true;
179 2: break;
180 : }
181 : }
182 : // Do we want to warn on a protocol in extension class which
183 : // already exist in the class? Probably not.
2: branch 0 taken
2: branch 1 taken
184 4: if (!protocolExists) {
185 2: ProtocolRefs.push_back(ProtoInExtension);
186 2: ProtocolLocs.push_back(Locs[i]);
187 : }
188 : }
0: branch 1 not taken
2: branch 2 taken
189 2: if (ProtocolRefs.empty())
190 0: return;
191 : // Merge ProtocolRefs into class's protocol list;
192 2: protocol_loc_iterator pl = protocol_loc_begin();
2: branch 2 taken
2: branch 3 taken
193 4: for (protocol_iterator p = protocol_begin(), e = protocol_end();
194 : p != e; ++p, ++pl) {
195 2: ProtocolRefs.push_back(*p);
196 2: ProtocolLocs.push_back(*pl);
197 : }
198 2: ReferencedProtocols.Destroy(C);
199 2: unsigned NumProtoRefs = ProtocolRefs.size();
2: branch 4 taken
0: branch 5 not taken
2: branch 7 taken
0: branch 8 not taken
200 2: setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
201 : }
202 :
203 : ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
204 2646: ObjCInterfaceDecl *&clsDeclared) {
205 2646: ObjCInterfaceDecl* ClassDecl = this;
3952: branch 0 taken
1903: branch 1 taken
206 8501: while (ClassDecl != NULL) {
743: branch 1 taken
3209: branch 2 taken
207 3952: if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
208 743: clsDeclared = ClassDecl;
209 743: return I;
210 : }
211 3209: ClassDecl = ClassDecl->getSuperClass();
212 : }
213 1903: return NULL;
214 : }
215 :
216 : /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
217 : /// class whose name is passed as argument. If it is not one of the super classes
218 : /// the it returns NULL.
219 : ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
220 1: const IdentifierInfo*ICName) {
221 1: ObjCInterfaceDecl* ClassDecl = this;
2: branch 0 taken
0: branch 1 not taken
222 3: while (ClassDecl != NULL) {
1: branch 1 taken
1: branch 2 taken
223 2: if (ClassDecl->getIdentifier() == ICName)
224 1: return ClassDecl;
225 1: ClassDecl = ClassDecl->getSuperClass();
226 : }
227 0: return NULL;
228 : }
229 :
230 : /// lookupMethod - This method returns an instance/class method by looking in
231 : /// the class, its categories, and its super classes (using a linear search).
232 : ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
233 2442: bool isInstance) const {
234 2442: const ObjCInterfaceDecl* ClassDecl = this;
235 2442: ObjCMethodDecl *MethodDecl = 0;
236 :
3370: branch 0 taken
1022: branch 1 taken
237 6834: while (ClassDecl != NULL) {
1112: branch 1 taken
2258: branch 2 taken
238 3370: if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
239 1112: return MethodDecl;
240 :
241 : // Didn't find one yet - look through protocols.
242 : const ObjCList<ObjCProtocolDecl> &Protocols =
243 2258: ClassDecl->getReferencedProtocols();
2285: branch 1 taken
2018: branch 2 taken
244 6561: for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
245 2258: E = Protocols.end(); I != E; ++I)
240: branch 1 taken
2045: branch 2 taken
246 2285: if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
247 240: return MethodDecl;
248 :
249 : // Didn't find one yet - now look through categories.
250 2018: ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
338: branch 0 taken
1950: branch 1 taken
251 4306: while (CatDecl) {
64: branch 1 taken
274: branch 2 taken
252 338: if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
253 64: return MethodDecl;
254 :
255 : // Didn't find one yet - look through protocols.
256 : const ObjCList<ObjCProtocolDecl> &Protocols =
257 274: CatDecl->getReferencedProtocols();
4: branch 1 taken
270: branch 2 taken
258 548: for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
259 274: E = Protocols.end(); I != E; ++I)
4: branch 1 taken
0: branch 2 not taken
260 4: if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
261 4: return MethodDecl;
262 270: CatDecl = CatDecl->getNextClassCategory();
263 : }
264 1950: ClassDecl = ClassDecl->getSuperClass();
265 : }
266 1022: return NULL;
267 : }
268 :
269 : ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
270 115: const Selector &Sel) {
271 115: ObjCMethodDecl *Method = 0;
64: branch 1 taken
51: branch 2 taken
272 115: if (ObjCImplementationDecl *ImpDecl = getImplementation())
273 64: Method = ImpDecl->getInstanceMethod(Sel);
274 :
111: branch 0 taken
4: branch 1 taken
51: branch 3 taken
60: branch 4 taken
51: branch 5 taken
64: branch 6 taken
275 115: if (!Method && getSuperClass())
276 51: return getSuperClass()->lookupPrivateInstanceMethod(Sel);
277 64: return Method;
278 : }
279 :
280 : //===----------------------------------------------------------------------===//
281 : // ObjCMethodDecl
282 : //===----------------------------------------------------------------------===//
283 :
284 : ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
285 : SourceLocation beginLoc,
286 : SourceLocation endLoc,
287 : Selector SelInfo, QualType T,
288 : DeclContext *contextDecl,
289 : bool isInstance,
290 : bool isVariadic,
291 : bool isSynthesized,
292 3906: ImplementationControl impControl) {
293 : return new (C) ObjCMethodDecl(beginLoc, endLoc,
294 : SelInfo, T, contextDecl,
295 : isInstance,
3906: branch 1 taken
0: branch 2 not taken
296 3906: isVariadic, isSynthesized, impControl);
297 : }
298 :
299 0: void ObjCMethodDecl::Destroy(ASTContext &C) {
0: branch 0 not taken
0: branch 1 not taken
300 0: if (Body) Body->Destroy(C);
0: branch 0 not taken
0: branch 1 not taken
301 0: if (SelfDecl) SelfDecl->Destroy(C);
302 :
0: branch 2 not taken
0: branch 3 not taken
303 0: for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
0: branch 0 not taken
0: branch 1 not taken
304 0: if (*I) (*I)->Destroy(C);
305 :
306 0: ParamInfo.Destroy(C);
307 :
308 0: Decl::Destroy(C);
309 0: }
310 :
311 : /// \brief A definition will return its interface declaration.
312 : /// An interface declaration will return its definition.
313 : /// Otherwise it will return itself.
314 0: ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
315 0: ASTContext &Ctx = getASTContext();
316 0: ObjCMethodDecl *Redecl = 0;
317 0: Decl *CtxD = cast<Decl>(getDeclContext());
318 :
0: branch 1 not taken
0: branch 2 not taken
319 0: if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
0: branch 1 not taken
0: branch 2 not taken
320 0: if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
321 0: Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
322 :
0: branch 1 not taken
0: branch 2 not taken
323 0: } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
0: branch 1 not taken
0: branch 2 not taken
324 0: if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
325 0: Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
326 :
0: branch 0 not taken
0: branch 1 not taken
327 0: } else if (ObjCImplementationDecl *ImplD =
328 0: dyn_cast<ObjCImplementationDecl>(CtxD)) {
0: branch 1 not taken
0: branch 2 not taken
329 0: if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
330 0: Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
331 :
0: branch 0 not taken
0: branch 1 not taken
332 0: } else if (ObjCCategoryImplDecl *CImplD =
333 0: dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
0: branch 1 not taken
0: branch 2 not taken
334 0: if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
335 0: Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
336 : }
337 :
0: branch 0 not taken
0: branch 1 not taken
338 0: return Redecl ? Redecl : this;
339 : }
340 :
341 59: ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
342 59: Decl *CtxD = cast<Decl>(getDeclContext());
343 :
8: branch 1 taken
51: branch 2 taken
344 59: if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
8: branch 1 taken
0: branch 2 not taken
345 8: if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
3: branch 0 taken
5: branch 1 taken
346 8: if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
347 8: isInstanceMethod()))
348 3: return MD;
349 :
0: branch 0 not taken
51: branch 1 taken
350 51: } else if (ObjCCategoryImplDecl *CImplD =
351 51: dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
0: branch 1 not taken
0: branch 2 not taken
352 0: if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
0: branch 0 not taken
0: branch 1 not taken
353 0: if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
354 0: isInstanceMethod()))
355 0: return MD;
356 : }
357 :
358 56: return this;
359 : }
360 :
361 : void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
362 1029: const ObjCInterfaceDecl *OID) {
363 1029: QualType selfTy;
851: branch 1 taken
178: branch 2 taken
364 1029: if (isInstanceMethod()) {
365 : // There may be no interface context due to error in declaration
366 : // of the interface (which has been reported). Recover gracefully.
850: branch 0 taken
1: branch 1 taken
367 851: if (OID) {
368 850: selfTy = Context.getObjCInterfaceType(OID);
369 850: selfTy = Context.getObjCObjectPointerType(selfTy);
370 : } else {
371 1: selfTy = Context.getObjCIdType();
372 : }
373 : } else // we have a factory method.
374 178: selfTy = Context.getObjCClassType();
375 :
376 : setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
377 1029: &Context.Idents.get("self"), selfTy));
378 :
379 : setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
380 : &Context.Idents.get("_cmd"),
381 1029: Context.getObjCSelType()));
382 1029: }
383 :
384 3841: ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
29: branch 2 taken
3812: branch 3 taken
385 3841: if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
386 29: return ID;
0: branch 2 not taken
3812: branch 3 taken
387 3812: if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
388 0: return CD->getClassInterface();
3812: branch 2 taken
0: branch 3 not taken
389 3812: if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
390 3812: return IMD->getClassInterface();
391 :
0: branch 2 not taken
0: branch 3 not taken
392 0: assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
393 0: assert(false && "unknown method context");
394 : return 0;
395 : }
396 :
397 : //===----------------------------------------------------------------------===//
398 : // ObjCInterfaceDecl
399 : //===----------------------------------------------------------------------===//
400 :
401 : ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
402 : DeclContext *DC,
403 : SourceLocation atLoc,
404 : IdentifierInfo *Id,
405 : SourceLocation ClassLoc,
406 3225: bool ForwardDecl, bool isInternal){
407 : return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
3225: branch 1 taken
0: branch 2 not taken
408 3225: isInternal);
409 : }
410 :
411 : ObjCInterfaceDecl::
412 : ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
413 3225: SourceLocation CLoc, bool FD, bool isInternal)
414 : : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
415 : TypeForDecl(0), SuperClass(0),
416 : CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
417 3225: ClassLoc(CLoc) {
418 3225: }
419 :
420 0: void ObjCInterfaceDecl::Destroy(ASTContext &C) {
0: branch 2 not taken
0: branch 3 not taken
421 0: for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
0: branch 0 not taken
0: branch 1 not taken
422 0: if (*I) (*I)->Destroy(C);
423 :
424 0: IVars.Destroy(C);
425 : // FIXME: CategoryList?
426 :
427 : // FIXME: Because there is no clear ownership
428 : // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
429 : // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
430 0: Decl::Destroy(C);
431 0: }
432 :
433 1075: ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
434 : return getASTContext().getObjCImplementation(
435 1075: const_cast<ObjCInterfaceDecl*>(this));
436 : }
437 :
438 571: void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
439 571: getASTContext().setObjCImplementation(this, ImplD);
440 571: }
441 :
442 :
443 : /// FindCategoryDeclaration - Finds category declaration in the list of
444 : /// categories for this class and returns it. Name of the category is passed
445 : /// in 'CategoryId'. If category not found, return 0;
446 : ///
447 : ObjCCategoryDecl *
448 88: ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
73: branch 2 taken
24: branch 3 taken
449 97: for (ObjCCategoryDecl *Category = getCategoryList();
450 : Category; Category = Category->getNextClassCategory())
64: branch 1 taken
9: branch 2 taken
451 73: if (Category->getIdentifier() == CategoryId)
452 64: return Category;
453 24: return 0;
454 : }
455 :
456 : ObjCMethodDecl *
457 159: ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
46: branch 2 taken
149: branch 3 taken
458 195: for (ObjCCategoryDecl *Category = getCategoryList();
459 : Category; Category = Category->getNextClassCategory())
12: branch 1 taken
34: branch 2 taken
460 46: if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
10: branch 1 taken
2: branch 2 taken
461 12: if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
462 10: return MD;
463 149: return 0;
464 : }
465 :
466 145: ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
21: branch 2 taken
139: branch 3 taken
467 160: for (ObjCCategoryDecl *Category = getCategoryList();
468 : Category; Category = Category->getNextClassCategory())
10: branch 1 taken
11: branch 2 taken
469 21: if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
6: branch 1 taken
4: branch 2 taken
470 10: if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
471 6: return MD;
472 139: return 0;
473 : }
474 :
475 : /// ClassImplementsProtocol - Checks that 'lProto' protocol
476 : /// has been implemented in IDecl class, its super class or categories (if
477 : /// lookupCategory is true).
478 : bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
479 : bool lookupCategory,
480 102: bool RHSIsQualifiedID) {
481 102: ObjCInterfaceDecl *IDecl = this;
482 : // 1st, look up the class.
483 : const ObjCList<ObjCProtocolDecl> &Protocols =
484 102: IDecl->getReferencedProtocols();
485 :
50: branch 1 taken
69: branch 2 taken
486 221: for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
487 102: E = Protocols.end(); PI != E; ++PI) {
33: branch 2 taken
17: branch 3 taken
488 50: if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
489 33: return true;
490 : // This is dubious and is added to be compatible with gcc. In gcc, it is
491 : // also allowed assigning a protocol-qualified 'id' type to a LHS object
492 : // when protocol in qualified LHS is in list of protocols in the rhs 'id'
493 : // object. This IMO, should be a bug.
494 : // FIXME: Treat this as an extension, and flag this as an error when GCC
495 : // extensions are not enabled.
0: branch 0 not taken
17: branch 1 taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
17: branch 7 taken
496 17: if (RHSIsQualifiedID &&
497 : getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
498 0: return true;
499 : }
500 :
501 : // 2nd, look up the category.
69: branch 0 taken
0: branch 1 not taken
502 69: if (lookupCategory)
8: branch 2 taken
61: branch 3 taken
503 69: for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
504 : CDecl = CDecl->getNextClassCategory()) {
8: branch 1 taken
0: branch 2 not taken
505 16: for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
506 8: E = CDecl->protocol_end(); PI != E; ++PI)
8: branch 2 taken
0: branch 3 not taken
507 8: if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
508 8: return true;
509 : }
510 :
511 : // 3rd, look up the super class(s)
16: branch 1 taken
45: branch 2 taken
512 61: if (IDecl->getSuperClass())
513 : return
514 : IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
515 16: RHSIsQualifiedID);
516 :
517 45: return false;
518 : }
519 :
520 : //===----------------------------------------------------------------------===//
521 : // ObjCIvarDecl
522 : //===----------------------------------------------------------------------===//
523 :
524 : ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
525 : SourceLocation L, IdentifierInfo *Id,
526 : QualType T, TypeSourceInfo *TInfo,
527 729: AccessControl ac, Expr *BW) {
729: branch 1 taken
0: branch 2 not taken
528 729: return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
529 : }
530 :
531 :
532 :
533 : //===----------------------------------------------------------------------===//
534 : // ObjCAtDefsFieldDecl
535 : //===----------------------------------------------------------------------===//
536 :
537 : ObjCAtDefsFieldDecl
538 : *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
539 21: IdentifierInfo *Id, QualType T, Expr *BW) {
21: branch 1 taken
0: branch 2 not taken
540 21: return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
541 : }
542 :
543 0: void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
544 0: this->~ObjCAtDefsFieldDecl();
545 0: C.Deallocate((void *)this);
546 0: }
547 :
548 : //===----------------------------------------------------------------------===//
549 : // ObjCProtocolDecl
550 : //===----------------------------------------------------------------------===//
551 :
552 : ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
553 : SourceLocation L,
554 727: IdentifierInfo *Id) {
727: branch 1 taken
0: branch 2 not taken
555 727: return new (C) ObjCProtocolDecl(DC, L, Id);
556 : }
557 :
558 0: void ObjCProtocolDecl::Destroy(ASTContext &C) {
559 0: ReferencedProtocols.Destroy(C);
560 0: ObjCContainerDecl::Destroy(C);
561 0: }
562 :
563 27: ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
564 27: ObjCProtocolDecl *PDecl = this;
565 :
9: branch 1 taken
18: branch 2 taken
566 27: if (Name == getIdentifier())
567 9: return PDecl;
568 :
1: branch 2 taken
17: branch 3 taken
569 18: for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1: branch 1 taken
0: branch 2 not taken
570 1: if ((PDecl = (*I)->lookupProtocolNamed(Name)))
571 1: return PDecl;
572 :
573 17: return NULL;
574 : }
575 :
576 : // lookupMethod - Lookup a instance/class method in the protocol and protocols
577 : // it inherited.
578 : ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
579 2410: bool isInstance) const {
580 2410: ObjCMethodDecl *MethodDecl = NULL;
581 :
271: branch 1 taken
2139: branch 2 taken
582 2410: if ((MethodDecl = getMethod(Sel, isInstance)))
583 271: return MethodDecl;
584 :
89: branch 2 taken
2114: branch 3 taken
585 2203: for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
25: branch 1 taken
64: branch 2 taken
586 89: if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
587 25: return MethodDecl;
588 2114: return NULL;
589 : }
590 :
591 : //===----------------------------------------------------------------------===//
592 : // ObjCClassDecl
593 : //===----------------------------------------------------------------------===//
594 :
595 : ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
596 : ObjCInterfaceDecl *const *Elts,
597 : const SourceLocation *Locs,
598 : unsigned nElts,
599 393: ASTContext &C)
600 393: : Decl(ObjCClass, DC, L) {
601 393: setClassList(C, Elts, Locs, nElts);
602 393: }
603 :
604 : void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
605 397: const SourceLocation *Locs, unsigned Num) {
606 : ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
607 397: llvm::alignof<ObjCClassRef>());
1260: branch 0 taken
397: branch 1 taken
608 1657: for (unsigned i = 0; i < Num; ++i)
1260: branch 1 taken
0: branch 2 not taken
609 1260: new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
610 :
611 397: NumDecls = Num;
612 397: }
613 :
614 : ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
615 : SourceLocation L,
616 : ObjCInterfaceDecl *const *Elts,
617 : const SourceLocation *Locs,
618 393: unsigned nElts) {
393: branch 1 taken
0: branch 2 not taken
619 393: return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
620 : }
621 :
622 0: void ObjCClassDecl::Destroy(ASTContext &C) {
623 : // ObjCInterfaceDecls registered with a DeclContext will get destroyed
624 : // when the DeclContext is destroyed. For those created only by a forward
625 : // declaration, the first @class that created the ObjCInterfaceDecl gets
626 : // to destroy it.
627 : // FIXME: Note that this ownership role is very brittle; a better
628 : // polict is surely need in the future.
0: branch 2 not taken
0: branch 3 not taken
629 0: for (iterator I = begin(), E = end(); I !=E ; ++I) {
630 0: ObjCInterfaceDecl *ID = I->getInterface();
0: branch 1 not taken
0: branch 2 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
631 0: if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
632 0: ID->Destroy(C);
633 : }
634 :
635 0: C.Deallocate(ForwardDecls);
636 0: Decl::Destroy(C);
637 0: }
638 :
639 3328: SourceRange ObjCClassDecl::getSourceRange() const {
640 : // FIXME: We should include the semicolon
0: branch 0 not taken
3328: branch 1 taken
641 3328: assert(NumDecls);
642 3328: return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation());
643 : }
644 :
645 : //===----------------------------------------------------------------------===//
646 : // ObjCForwardProtocolDecl
647 : //===----------------------------------------------------------------------===//
648 :
649 : ObjCForwardProtocolDecl::
650 : ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
651 : ObjCProtocolDecl *const *Elts, unsigned nElts,
652 71: const SourceLocation *Locs, ASTContext &C)
653 71: : Decl(ObjCForwardProtocol, DC, L) {
654 71: ReferencedProtocols.set(Elts, nElts, Locs, C);
655 71: }
656 :
657 :
658 : ObjCForwardProtocolDecl *
659 : ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
660 : SourceLocation L,
661 : ObjCProtocolDecl *const *Elts,
662 : unsigned NumElts,
663 71: const SourceLocation *Locs) {
71: branch 1 taken
0: branch 2 not taken
664 71: return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
665 : }
666 :
667 0: void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
668 0: ReferencedProtocols.Destroy(C);
669 0: Decl::Destroy(C);
670 0: }
671 :
672 : //===----------------------------------------------------------------------===//
673 : // ObjCCategoryDecl
674 : //===----------------------------------------------------------------------===//
675 :
676 : ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
677 : SourceLocation AtLoc,
678 : SourceLocation ClassNameLoc,
679 : SourceLocation CategoryNameLoc,
680 211: IdentifierInfo *Id) {
211: branch 1 taken
0: branch 2 not taken
681 211: return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
682 : }
683 :
684 151: ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
685 : return getASTContext().getObjCImplementation(
686 151: const_cast<ObjCCategoryDecl*>(this));
687 : }
688 :
689 64: void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
690 64: getASTContext().setObjCImplementation(this, ImplD);
691 64: }
692 :
693 :
694 : //===----------------------------------------------------------------------===//
695 : // ObjCCategoryImplDecl
696 : //===----------------------------------------------------------------------===//
697 :
698 : ObjCCategoryImplDecl *
699 : ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
700 : SourceLocation L,IdentifierInfo *Id,
701 68: ObjCInterfaceDecl *ClassInterface) {
68: branch 1 taken
0: branch 2 not taken
702 68: return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
703 : }
704 :
705 0: ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
706 0: return getClassInterface()->FindCategoryDeclaration(getIdentifier());
707 : }
708 :
709 :
710 287: void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
711 : // FIXME: The context should be correct before we get here.
712 287: property->setLexicalDeclContext(this);
713 287: addDecl(property);
714 287: }
715 :
716 2: void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
717 2: ASTContext &Ctx = getASTContext();
718 :
2: branch 0 taken
0: branch 1 not taken
719 2: if (ObjCImplementationDecl *ImplD
720 2: = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
2: branch 0 taken
0: branch 1 not taken
721 2: if (IFace)
722 2: Ctx.setObjCImplementation(IFace, ImplD);
723 :
0: branch 0 not taken
0: branch 1 not taken
724 0: } else if (ObjCCategoryImplDecl *ImplD =
725 0: dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
0: branch 2 not taken
0: branch 3 not taken
726 0: if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
727 0: Ctx.setObjCImplementation(CD, ImplD);
728 : }
729 :
730 2: ClassInterface = IFace;
731 2: }
732 :
733 : /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
734 : /// properties implemented in this category @implementation block and returns
735 : /// the implemented property that uses it.
736 : ///
737 : ObjCPropertyImplDecl *ObjCImplDecl::
738 213: FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1412: branch 4 taken
211: branch 5 taken
739 1623: for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
740 1412: ObjCPropertyImplDecl *PID = *i;
1390: branch 1 taken
22: branch 2 taken
2: branch 5 taken
1388: branch 6 taken
2: branch 7 taken
1410: branch 8 taken
741 1412: if (PID->getPropertyIvarDecl() &&
742 : PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
743 2: return PID;
744 : }
745 211: return 0;
746 : }
747 :
748 : /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
749 : /// added to the list of those properties @synthesized/@dynamic in this
750 : /// category @implementation block.
751 : ///
752 : ObjCPropertyImplDecl *ObjCImplDecl::
753 465: FindPropertyImplDecl(IdentifierInfo *Id) const {
4211: branch 4 taken
322: branch 5 taken
754 4533: for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
755 4211: ObjCPropertyImplDecl *PID = *i;
143: branch 2 taken
4068: branch 3 taken
756 4211: if (PID->getPropertyDecl()->getIdentifier() == Id)
757 143: return PID;
758 : }
759 322: return 0;
760 : }
761 :
762 : //===----------------------------------------------------------------------===//
763 : // ObjCImplementationDecl
764 : //===----------------------------------------------------------------------===//
765 :
766 : ObjCImplementationDecl *
767 : ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
768 : SourceLocation L,
769 : ObjCInterfaceDecl *ClassInterface,
770 575: ObjCInterfaceDecl *SuperDecl) {
575: branch 1 taken
0: branch 2 not taken
771 575: return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
772 : }
773 :
774 : //===----------------------------------------------------------------------===//
775 : // ObjCCompatibleAliasDecl
776 : //===----------------------------------------------------------------------===//
777 :
778 : ObjCCompatibleAliasDecl *
779 : ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
780 : SourceLocation L,
781 : IdentifierInfo *Id,
782 6: ObjCInterfaceDecl* AliasedClass) {
6: branch 1 taken
0: branch 2 not taken
783 6: return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
784 : }
785 :
786 : //===----------------------------------------------------------------------===//
787 : // ObjCPropertyDecl
788 : //===----------------------------------------------------------------------===//
789 :
790 : ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
791 : SourceLocation L,
792 : IdentifierInfo *Id,
793 : SourceLocation AtLoc,
794 : QualType T,
795 449: PropertyControl propControl) {
449: branch 1 taken
0: branch 2 not taken
796 449: return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
797 : }
798 :
799 :
800 : //===----------------------------------------------------------------------===//
801 : // ObjCPropertyImplDecl
802 : //===----------------------------------------------------------------------===//
803 :
804 : ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
805 : DeclContext *DC,
806 : SourceLocation atLoc,
807 : SourceLocation L,
808 : ObjCPropertyDecl *property,
809 : Kind PK,
810 289: ObjCIvarDecl *ivar) {
289: branch 1 taken
0: branch 2 not taken
811 289: return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
812 : }
813 :
814 :
Generated: 2010-02-10 01:31 by zcov