Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: class-dump/src/CDStructureTable.m

Issue 7793008: Add the 3.3.3 sources for class-dump. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « class-dump/src/CDStructureTable.h ('k') | class-dump/src/CDSymbol.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // -*- mode: ObjC -*-
2
3 // This file is part of class-dump, a utility for examining the Objective-C seg ment of Mach-O files.
4 // Copyright (C) 1997-1998, 2000-2001, 2004-2010 Steve Nygard.
5
6 #import "CDStructureTable.h"
7
8 #import "NSArray-Extensions.h"
9 #import "NSError-CDExtensions.h"
10 #import "NSString-Extensions.h"
11 #import "CDClassDump.h"
12 #import "CDSymbolReferences.h"
13 #import "CDType.h"
14 #import "CDTypeController.h"
15 #import "CDTypeFormatter.h"
16 #import "CDTypeName.h"
17 #import "CDStructureInfo.h"
18
19 // Phase 0 - This is driven by CDClassDump, registering types from all of the cl asses, categories, and protocols.
20 // - This collects all the top level types (or struct/unions?), keeps a reference count, and flags any that were used in a method.
21 // - If a top level struct was used in a method, then the type MUST be d eclared at the top.
22 // - At the end of phase 0, these types are recursively visited, renamin g structs whose name starts with $ (like $_12345) to ?, so
23 // that we'll treat them as anonymous structures.
24 // - Those names must be generated by the compiler. It can end up wi th different numbers for the same type.
25
26 // Phase 1 - This goes through all the types collected in phase 0, and recursive ly registers each structure and union with the type controller.
27 // - We are not concerned about reference counts or the isUsedInMethod f lags.
28 // - Since structures and unions can be nested in each other, we need to process each table before doing the end-of-phase work.
29 // - We record the maximum structure depth.
30 // - Since the deepest union may be buriend in a structure instead of referenced at the top level, we can't calculate the max depth from phase 0.
31 // - On the other hand, since we're only interested in the max combine d depth of structures and unions, the end result would be the same.
32 // - The result of phase 1 is phase1_groupedByDepth: a dictionary keyed by the structure depth, containing arrays of CDStructureInfo.
33
34 // Phase 2 - This is driven by CDTypeController.
35 // - The goal of phase 2 is to gather member names and types (@"NSObject " vs just @).
36 // - It goes through all of the phase1 groups, shallowest to deepest.
37 // - For each level group:
38 // - First it merges the results of all previous groups with the types at this depth.
39 // - Then we group the CDStructureInfos, named structures by name, ano n structures by reallyBareTypeString
40 // - If they could be combined, the combined CDStructureInfo is to p hase2_namedStructureInfo or phase2_anonStructureInfo.
41 // - If they couldn't be combined, the uncombined CDStructureInfos a re added to phase2_nameExceptions or phase2_anonExceptions.
42
43 // Phase 3 - Using all of the information available from the merged types from p hase 2, we merge these types with the types from phase 0
44 // to fill in missing member names, and the occasional object type.
45
46 // After all the phases are done, typedef names are generated for all anonymous structures, and then field names are added for missing fields.
47 // - bitfields don't need to have a name, so they can be blank.
48 // - the typedef name is calculated from a hash of the typeString.
49 // - Doing it before adding missing fields means we could change the field na mes without changing the typedef name.
50 // - Makes the name independant of the order they were encountered (like the previous indexes were). You can get meaningful diffs between
51 // framework changes now.
52
53 static BOOL debug = NO;
54 static BOOL debugNamedStructures = NO;
55 static BOOL debugAnonStructures = NO;
56
57 @implementation CDStructureTable
58
59 - (id)init;
60 {
61 if ([super init] == nil)
62 return nil;
63
64 identifier = nil;
65 anonymousBaseName = nil;
66
67 phase0_structureInfo = [[NSMutableDictionary alloc] init];
68
69 phase1_structureInfo = [[NSMutableDictionary alloc] init];
70 phase1_maxDepth = 0;
71 phase1_groupedByDepth = [[NSMutableDictionary alloc] init];
72
73 phase2_namedStructureInfo = [[NSMutableDictionary alloc] init];
74 phase2_anonStructureInfo = [[NSMutableDictionary alloc] init];
75 phase2_nameExceptions = [[NSMutableArray alloc] init];
76 phase2_anonExceptions = [[NSMutableArray alloc] init];
77
78 phase3_namedStructureInfo = [[NSMutableDictionary alloc] init];
79 phase3_anonStructureInfo = [[NSMutableDictionary alloc] init];
80 phase3_nameExceptions = [[NSMutableDictionary alloc] init];
81 phase3_anonExceptions = [[NSMutableDictionary alloc] init];
82
83 phase3_exceptionalNames = [[NSMutableSet alloc] init];
84 phase3_inMethodNameExceptions = [[NSMutableSet alloc] init];
85
86 flags.shouldDebug = NO;
87
88 debugNames = [[NSMutableSet alloc] init];
89 debugAnon = [[NSMutableSet alloc] init];
90
91 return self;
92 }
93
94 - (void)dealloc;
95 {
96 [identifier release];
97 [anonymousBaseName release];
98
99 [phase0_structureInfo release];
100
101 [phase1_structureInfo release];
102 [phase1_groupedByDepth release];
103
104 [phase2_namedStructureInfo release];
105 [phase2_anonStructureInfo release];
106 [phase2_nameExceptions release];
107 [phase2_anonExceptions release];
108
109 [phase3_namedStructureInfo release];
110 [phase3_anonStructureInfo release];
111 [phase3_nameExceptions release];
112 [phase3_anonExceptions release];
113
114 [phase3_exceptionalNames release];
115 [phase3_inMethodNameExceptions release];
116
117 [debugNames release];
118 [debugAnon release];
119
120 [super dealloc];
121 }
122
123 - (NSString *)identifier;
124 {
125 return identifier;
126 }
127
128 - (void)setIdentifier:(NSString *)newIdentifier;
129 {
130 if (newIdentifier == identifier)
131 return;
132
133 [identifier release];
134 identifier = [newIdentifier retain];
135 }
136
137 - (NSString *)anonymousBaseName;
138 {
139 return anonymousBaseName;
140 }
141
142 - (void)setAnonymousBaseName:(NSString *)newName;
143 {
144 if (newName == anonymousBaseName)
145 return;
146
147 [anonymousBaseName release];
148 anonymousBaseName = [newName retain];
149 }
150
151 - (BOOL)shouldDebug;
152 {
153 return flags.shouldDebug;
154 }
155
156 - (void)setShouldDebug:(BOOL)newFlag;
157 {
158 flags.shouldDebug = newFlag;
159 }
160
161 //
162 // Phase 0
163 //
164
165 - (void)phase0RegisterStructure:(CDType *)aStructure usedInMethod:(BOOL)isUsedIn Method;
166 {
167 NSString *key;
168 CDStructureInfo *info;
169
170 key = [aStructure typeString];
171 info = [phase0_structureInfo objectForKey:key];
172 if (info == nil) {
173 info = [[CDStructureInfo alloc] initWithType:aStructure];
174 if (isUsedInMethod)
175 [info setIsUsedInMethod:YES];
176 [phase0_structureInfo setObject:info forKey:key];
177 [info release];
178 } else {
179 [info addReferenceCount:1];
180 if (isUsedInMethod)
181 [info setIsUsedInMethod:YES];
182 }
183 }
184
185 - (void)finishPhase0;
186 {
187 if (debug) NSLog(@"[%@] %s, changing struct names that start with $", identi fier, _cmd);
188 for (CDStructureInfo *info in [phase0_structureInfo allValues]) {
189 [[info type] phase0RecursivelyFixStructureNames:debug];
190 }
191
192 if ([debugNames count] > 0) {
193 NSLog(@"================================================================ ======");
194 NSLog(@"[%@] %s", identifier, _cmd);
195 NSLog(@"debug names: %@", [[debugNames allObjects] componentsJoinedByStr ing:@", "]);
196 for (CDStructureInfo *info in [[phase0_structureInfo allValues] sortedAr rayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
197 if ([debugNames containsObject:[[[info type] typeName] description]] )
198 NSLog(@"%@", [info shortDescription]);
199 }
200 NSLog(@"================================================================ ======");
201 }
202
203 if ([debugAnon count] > 0) {
204 NSLog(@"================================================================ ======");
205 NSLog(@"[%@] %s", identifier, _cmd);
206 NSLog(@"debug anon: %@", [[debugAnon allObjects] componentsJoinedByStrin g:@", "]);
207 for (CDStructureInfo *info in [[phase0_structureInfo allValues] sortedAr rayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
208 if ([debugAnon containsObject:[[info type] reallyBareTypeString]])
209 NSLog(@"%@", [info shortDescription]);
210 }
211 NSLog(@"================================================================ ======");
212 }
213 }
214
215 - (void)logPhase0Info;
216 {
217 NSLog(@"==================================================================== ==");
218 NSLog(@"[%@] %s", identifier, _cmd);
219 for (CDStructureInfo *info in [[phase0_structureInfo allValues] sortedArrayU singSelector:@selector(ascendingCompareByStructureDepth:)]) {
220 NSLog(@"%@", [info shortDescription]);
221 }
222 NSLog(@"==================================================================== ==");
223 }
224
225 //
226 // Phase 1
227 //
228
229 - (void)phase1WithTypeController:(CDTypeController *)typeController;
230 {
231 for (CDStructureInfo *info in [phase0_structureInfo allValues]) {
232 [[info type] phase1RegisterStructuresWithObject:typeController];
233 }
234 }
235
236 // Need to gather all of the structures, since some substructures may have membe r names we'd otherwise miss.
237 - (void)phase1RegisterStructure:(CDType *)aStructure;
238 {
239 NSString *key;
240 CDStructureInfo *info;
241
242 key = [aStructure typeString];
243 info = [phase1_structureInfo objectForKey:key];
244 if (info == nil) {
245 info = [[CDStructureInfo alloc] initWithType:aStructure];
246 [phase1_structureInfo setObject:info forKey:key];
247 [info release];
248 }
249 }
250
251 // Need to merge names bottom-up to catch cases like: {?=@@iiffff{_NSRect={_NSPo int=ff}{_NSSize=ff}}{?=b1b1b1b1b1b27}}
252
253 - (void)finishPhase1;
254 {
255 if (debug) {
256 NSLog(@"================================================================ ======");
257 NSLog(@"[%@] %s", identifier, _cmd);
258 }
259
260 // The deepest union may not be at the top level (buried in a structure inst ead), so need to get the depth here.
261 // But we'll take the max of structure and union depths in the CDTypeControl ler anyway.
262
263 for (CDStructureInfo *info in [phase1_structureInfo allValues]) {
264 NSUInteger depth;
265
266 depth = [[info type] structureDepth];
267 if (phase1_maxDepth < depth)
268 phase1_maxDepth = depth;
269 }
270 if (debug) NSLog(@"[%@] Maximum structure depth is: %u", identifier, phase1_ maxDepth);
271
272 for (CDStructureInfo *info in [phase1_structureInfo allValues]) {
273 NSNumber *key;
274 NSMutableArray *group;
275
276 key = [NSNumber numberWithUnsignedInteger:[[info type] structureDepth]];
277 group = [phase1_groupedByDepth objectForKey:key];
278 if (group == nil) {
279 group = [[NSMutableArray alloc] init];
280 [group addObject:info];
281 [phase1_groupedByDepth setObject:group forKey:key];
282 [group release];
283 } else {
284 [group addObject:info];
285 }
286 }
287
288 if (debug) NSLog(@"depth groups: %@", [[phase1_groupedByDepth allKeys] sorte dArrayUsingSelector:@selector(compare:)]);
289 }
290
291 - (NSUInteger)phase1_maxDepth;
292 {
293 return phase1_maxDepth;
294 }
295
296 //
297 // Phase 2
298 //
299
300 // From lowest to highest depths:
301 // - Go through all infos at that level
302 // - recursively (bottom up) try to merge substructures into that type, to get names/full types
303 // - merge all mergeable infos at that level
304
305 - (void)phase2AtDepth:(NSUInteger)depth typeController:(CDTypeController *)typeC ontroller;
306 {
307 NSNumber *depthKey;
308 NSArray *infos;
309 NSMutableDictionary *nameDict, *anonDict;
310
311 //NSLog(@"[%@] %s, depth: %u", identifier, _cmd, depth);
312 depthKey = [NSNumber numberWithUnsignedInt:depth];
313 infos = [phase1_groupedByDepth objectForKey:depthKey];
314
315 for (CDStructureInfo *info in infos) {
316 // recursively (bottom up) try to merge substructures into that type, to get names/full types
317 //NSLog(@"----------------------------------------");
318 //NSLog(@"Trying phase2Merge with on %@", [[info type] typeString]);
319 [[info type] phase2MergeWithTypeController:typeController debug:debug];
320 }
321
322 // merge all mergeable infos at that level
323 nameDict = [NSMutableDictionary dictionary];
324 anonDict = [NSMutableDictionary dictionary];
325
326 // Group named structures by name.
327 // Group anon structures by reallyBareTypeString.
328 for (CDStructureInfo *info in infos) {
329 NSString *name;
330 NSMutableArray *group;
331
332 name = [[[info type] typeName] description];
333
334 if ([@"?" isEqualToString:name]) {
335 NSString *key;
336
337 key = [[info type] reallyBareTypeString];
338 group = [anonDict objectForKey:key];
339 if (group == nil) {
340 group = [[NSMutableArray alloc] init];
341 [group addObject:info];
342 [anonDict setObject:group forKey:key];
343 [group release];
344 } else {
345 [group addObject:info];
346 }
347 } else {
348 group = [nameDict objectForKey:name];
349 if (group == nil) {
350 group = [[NSMutableArray alloc] init];
351 [group addObject:info];
352 [nameDict setObject:group forKey:name];
353 [group release];
354 } else {
355 [group addObject:info];
356 }
357 }
358 }
359
360 // Now... for each group, make sure we can combine them all together.
361 // If not, this means that either the types or the member names conflicted, and we save the entire group as an exception.
362 for (NSString *key in [nameDict allKeys]) {
363 NSMutableArray *group;
364 CDStructureInfo *combined = nil;
365 BOOL canBeCombined = YES;
366
367 //NSLog(@"key... %@", key);
368 group = [nameDict objectForKey:key];
369 for (CDStructureInfo *info in group) {
370 if (combined == nil) {
371 combined = [info copy];
372 } else {
373 //NSLog(@"old: %@", [[combined type] typeString]);
374 //NSLog(@"new: %@", [[info type] typeString]);
375 if ([[combined type] canMergeWithType:[info type]]) {
376 [[combined type] mergeWithType:[info type]];
377 [combined addReferenceCount:[info referenceCount]];
378 #if 0
379 if ([info isUsedInMethod])
380 [combined setIsUsedInMethod:YES];
381 #endif
382 } else {
383 canBeCombined = NO;
384 break;
385 }
386 }
387 }
388
389 if (canBeCombined) {
390 CDStructureInfo *previousInfo;
391
392 previousInfo = [phase2_namedStructureInfo objectForKey:key];
393 if (previousInfo != nil) {
394 // struct _Vector_impl in HALLab.
395 [phase2_nameExceptions addObject:previousInfo];
396 //[phase2_nameExceptions addObjectsFromArray:group]; // Or just add the combined?
397 [phase2_nameExceptions addObject:combined];
398 [phase2_namedStructureInfo removeObjectForKey:key];
399 if (debugNamedStructures) {
400 NSLog(@"[%@] %s, WARNING: depth %u name %@ has conflict(?) a t lower level", identifier, _cmd, depth, key);
401 NSLog(@"previous: %@", [[phase2_namedStructureInfo objectFor Key:key] shortDescription]);
402 NSLog(@" current: %@", [combined shortDescription]);
403 }
404 } else {
405 [phase2_namedStructureInfo setObject:combined forKey:key];
406 }
407 } else {
408 if (debugNamedStructures) {
409 NSLog(@"----------------------------------------");
410 NSLog(@"Can't be combined: %@", key);
411 NSLog(@"group: %@", group);
412 }
413 [phase2_nameExceptions addObjectsFromArray:group];
414 }
415
416 [combined release];
417 }
418
419 //NSLog(@"================================================================== ====");
420 for (NSString *key in [anonDict allKeys]) {
421 NSMutableArray *group;
422 CDStructureInfo *combined = nil;
423 BOOL canBeCombined = YES;
424
425 //NSLog(@"key... %@", key);
426 group = [anonDict objectForKey:key];
427 for (CDStructureInfo *info in group) {
428 if (combined == nil) {
429 combined = [info copy];
430 //NSLog(@"info: %@", [info shortDescription]);
431 //NSLog(@"combined: %@", [combined shortDescription]);
432 } else {
433 //NSLog(@"old: %@", [combined shortDescription]);
434 //NSLog(@"new: %@", [info shortDescription]);
435 if ([[combined type] canMergeWithType:[info type]]) {
436 [[combined type] mergeWithType:[info type]];
437 [combined addReferenceCount:[info referenceCount]];
438 #if 0
439 if ([info isUsedInMethod])
440 [combined setIsUsedInMethod:YES];
441 #endif
442 } else {
443 if (debugAnonStructures) {
444 NSLog(@"previous: %@", [[combined type] typeString]);
445 NSLog(@" This: %@", [[info type] typeString]);
446 }
447 canBeCombined = NO;
448 break;
449 }
450 }
451 }
452
453 if (canBeCombined) {
454 if ([phase2_anonStructureInfo objectForKey:key] != nil) {
455 // This shouldn't happen, but the named case might.
456 NSLog(@"[%@] %s, WARNING: depth %u type %@ has conflict(?) at lo wer level", identifier, _cmd, depth, key);
457 NSLog(@"previous: %@", [[phase2_anonStructureInfo objectForKey:k ey] shortDescription]);
458 NSLog(@" current: %@", [combined shortDescription]);
459 }
460 [phase2_anonStructureInfo setObject:combined forKey:key];
461 } else {
462 if (debugAnonStructures) {
463 NSLog(@"----------------------------------------");
464 NSLog(@"Can't be combined: %@", key);
465 NSLog(@"group: %@", group);
466 }
467 [phase2_anonExceptions addObjectsFromArray:group];
468 }
469
470 [combined release];
471 }
472 }
473
474 - (CDType *)phase2ReplacementForType:(CDType *)type;
475 {
476 NSString *name;
477
478 name = [[type typeName] description];
479 if ([@"?" isEqualToString:name]) {
480 return [(CDStructureInfo *)[phase2_anonStructureInfo objectForKey:[type reallyBareTypeString]] type];
481 } else {
482 return [(CDStructureInfo *)[phase2_namedStructureInfo objectForKey:name] type];
483 }
484
485 return nil;
486 }
487
488 - (void)finishPhase2;
489 {
490 if ([debugNames count] > 0) {
491 NSLog(@"================================================================ ======");
492 NSLog(@"[%@] %s", identifier, _cmd);
493 NSLog(@"debug names: %@", [[debugNames allObjects] componentsJoinedByStr ing:@", "]);
494 for (CDStructureInfo *info in [[phase2_namedStructureInfo allValues] sor tedArrayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
495 if ([debugNames containsObject:[[[info type] typeName] description]] )
496 NSLog(@"%@", [info shortDescription]);
497 }
498 NSLog(@"================================================================ ======");
499 }
500
501 if ([debugAnon count] > 0) {
502 NSLog(@"================================================================ ======");
503 NSLog(@"[%@] %s", identifier, _cmd);
504 NSLog(@"debug anon: %@", [[debugAnon allObjects] componentsJoinedByStrin g:@", "]);
505 for (CDStructureInfo *info in [[phase2_anonStructureInfo allValues] sort edArrayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
506 if ([debugAnon containsObject:[[info type] reallyBareTypeString]])
507 NSLog(@"%@", [info shortDescription]);
508 }
509 NSLog(@"================================================================ ======");
510 }
511
512 //[self logPhase2Info];
513 }
514
515 - (void)logPhase2Info;
516 {
517 #if 0
518 NSLog(@"==================================================================== ==");
519 NSLog(@"[%@] %s, named:", identifier, _cmd);
520 for (CDStructureInfo *info in [[phase2_namedStructureInfo allValues] sortedA rrayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
521 NSLog(@"%@", [info shortDescription]);
522 }
523 #endif
524 #if 0
525 NSLog(@"==================================================================== ==");
526 NSLog(@"[%@] %s, anon:", identifier, _cmd);
527 for (CDStructureInfo *info in [[phase2_anonStructureInfo allValues] sortedAr rayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
528 NSLog(@"%@", [info shortDescription]);
529 }
530 #endif
531 #if 1
532 NSLog(@"==================================================================== ==");
533 NSLog(@"[%@] %s, named exceptions:", identifier, _cmd);
534 for (CDStructureInfo *info in [phase2_nameExceptions sortedArrayUsingSelecto r:@selector(ascendingCompareByStructureDepth:)]) {
535 NSLog(@"%@", [info shortDescription]);
536 }
537 #endif
538 #if 0
539 NSLog(@"==================================================================== ==");
540 NSLog(@"[%@] %s, anon exceptions:", identifier, _cmd);
541 for (CDStructureInfo *info in [phase2_anonExceptions sortedArrayUsingSelecto r:@selector(ascendingCompareByStructureDepth:)]) {
542 NSLog(@"%@", [info shortDescription]);
543 }
544 #endif
545 }
546
547 //
548 // Phase 3
549 //
550
551 - (void)phase2ReplacementOnPhase0WithTypeController:(CDTypeController *)typeCont roller;
552 {
553 if (debug) {
554 NSLog(@"================================================================ ======");
555 NSLog(@"[%@] > %s", identifier, _cmd);
556 }
557
558 for (CDStructureInfo *info in [phase0_structureInfo allValues]) {
559 [[info type] phase2MergeWithTypeController:typeController debug:debug];
560 }
561
562 if (debug) NSLog(@"[%@] < %s", identifier, _cmd);
563 }
564
565 // Go through all updated phase0_structureInfo types
566 // - start merging these into a new table
567 // - If this is the first time a structure has been added:
568 // - add one reference for each subtype
569 // - otherwise just merge them.
570 // - end result should be CDStructureInfos with counts and method reference flag s
571
572 - (void)buildPhase3Exceptions;
573 {
574 for (CDStructureInfo *info in phase2_nameExceptions) {
575 CDStructureInfo *newInfo;
576
577 newInfo = [info copy];
578 [newInfo setReferenceCount:0];
579 [newInfo setIsUsedInMethod:NO];
580 [phase3_nameExceptions setObject:newInfo forKey:[[newInfo type] typeStri ng]];
581 [phase3_exceptionalNames addObject:[newInfo name]];
582 [newInfo release];
583 }
584
585 for (CDStructureInfo *info in phase2_anonExceptions) {
586 CDStructureInfo *newInfo;
587
588 newInfo = [info copy];
589 [newInfo setReferenceCount:0];
590 [newInfo setIsUsedInMethod:NO];
591 [phase3_anonExceptions setObject:newInfo forKey:[[newInfo type] typeStri ng]];
592 [newInfo release];
593 }
594
595 //NSLog(@"phase3 name exceptions: %@", [[phase3_nameExceptions allKeys] comp onentsJoinedByString:@", "]);
596 //NSLog(@"phase3 anon exceptions: %@", [[phase3_anonExceptions allKeys] comp onentsJoinedByString:@"\n"]);
597 //exit(99);
598 }
599
600 - (void)phase3WithTypeController:(CDTypeController *)typeController;
601 {
602 //NSLog(@"[%@] > %s", identifier, _cmd);
603
604 for (CDStructureInfo *info in [[phase0_structureInfo allValues] sortedArrayU singSelector:@selector(ascendingCompareByStructureDepth:)]) {
605 [self phase3RegisterStructure:[info type] count:[info referenceCount] us edInMethod:[info isUsedInMethod] typeController:typeController];
606 }
607
608 //NSLog(@"[%@] < %s", identifier, _cmd);
609 }
610
611 - (void)phase3RegisterStructure:(CDType *)aStructure
612 count:(NSUInteger)referenceCount
613 usedInMethod:(BOOL)isUsedInMethod
614 typeController:(CDTypeController *)typeController;
615 {
616 NSString *name;
617
618 //NSLog(@"[%@] > %s", identifier, _cmd);
619
620 name = [[aStructure typeName] description];
621 if ([@"?" isEqualToString:name]) {
622 NSString *key;
623 CDStructureInfo *info;
624
625 key = [aStructure reallyBareTypeString];
626 //NSLog(@"key: %@, isUsedInMethod: %u", key, isUsedInMethod);
627 info = [phase3_anonExceptions objectForKey:[aStructure typeString]];
628 if (info != nil) {
629 if (debugAnonStructures) NSLog(@"%s, anon key %@ has exception from phase 2", _cmd, [aStructure typeString]);
630 [info addReferenceCount:referenceCount];
631 if (isUsedInMethod)
632 [info setIsUsedInMethod:isUsedInMethod];
633
634 if ([info referenceCount] == referenceCount) { // i.e. the first tim e we've encounter this struct
635 // And then... add 1 reference for each substructure, stopping r ecursion when we've encountered a previous structure
636 [aStructure phase3RegisterMembersWithTypeController:typeControll er];
637 }
638 } else {
639 info = [phase3_anonStructureInfo objectForKey:key];
640 if (info == nil) {
641 info = [[CDStructureInfo alloc] initWithType:aStructure];
642 [info setReferenceCount:referenceCount];
643 if (isUsedInMethod)
644 [info setIsUsedInMethod:isUsedInMethod];
645 [phase3_anonStructureInfo setObject:info forKey:key];
646 [info release];
647
648 // And then... add 1 reference for each substructure, stopping r ecursion when we've encountered a previous structure
649 [aStructure phase3RegisterMembersWithTypeController:typeControll er];
650 } else {
651 [info addReferenceCount:referenceCount];
652 if (isUsedInMethod)
653 [info setIsUsedInMethod:isUsedInMethod];
654 }
655 }
656 } else {
657 CDStructureInfo *info;
658
659 if ([debugNames containsObject:name]) NSLog(@"[%@] %s, type= %@", identi fier, _cmd, [aStructure typeString]);
660 //NSLog(@"[%@] %s, name: %@", identifier, _cmd, name);
661 if ([phase3_exceptionalNames containsObject:name]) {
662 if (debugNamedStructures) NSLog(@"%s, name %@ has exception from pha se 2", _cmd, name);
663 info = [phase3_nameExceptions objectForKey:[aStructure typeString]];
664 // Info can be nil. For example, from {_CommandStackEntry}
665 if (info != nil) {
666 [info addReferenceCount:referenceCount];
667 if (isUsedInMethod)
668 [phase3_inMethodNameExceptions addObject:name];
669
670 if ([info referenceCount] == referenceCount) { // i.e. the first time we've encounter this struct
671 // And then... add 1 reference for each substructure, stoppi ng recursion when we've encountered a previous structure
672 [aStructure phase3RegisterMembersWithTypeController:typeCont roller];
673 }
674 }
675 } else {
676 info = [phase3_namedStructureInfo objectForKey:name];
677 if (info == nil) {
678 if ([debugNames containsObject:name]) NSLog(@"[%@] %s, info was nil for %@", identifier, _cmd, name);
679 info = [[CDStructureInfo alloc] initWithType:aStructure];
680 [info setReferenceCount:referenceCount];
681 if (isUsedInMethod)
682 [info setIsUsedInMethod:isUsedInMethod];
683 [phase3_namedStructureInfo setObject:info forKey:name];
684 [info release];
685
686 // And then... add 1 reference for each substructure, stopping r ecursion when we've encountered a previous structure
687 [aStructure phase3RegisterMembersWithTypeController:typeControll er];
688 } else {
689 if ([debugNames containsObject:name]) NSLog(@"[%@] %s, info befo re: %@", identifier, _cmd, [info shortDescription]);
690 // Handle the case where {foo} occurs before {foo=iii}
691 if ([[[info type] members] count] == 0) {
692 [[info type] mergeWithType:aStructure];
693
694 // And then... add 1 reference for each substructure, stoppi ng recursion when we've encountered a previous structure
695 [aStructure phase3RegisterMembersWithTypeController:typeCont roller];
696 }
697 [info addReferenceCount:referenceCount];
698 if (isUsedInMethod)
699 [info setIsUsedInMethod:isUsedInMethod];
700 if ([debugNames containsObject:name]) {
701 NSLog(@"[%@] %s, added ref count: %u, isUsedInMethod: %u", i dentifier, _cmd, referenceCount, isUsedInMethod);
702 NSLog(@"[%@] %s, info after: %@", identifier, _cmd, [info sh ortDescription]);
703 }
704 }
705 }
706 }
707
708 //NSLog(@"[%@] < %s", identifier, _cmd);
709 }
710
711 - (void)finishPhase3;
712 {
713 if ([debugNames count] > 0) {
714 NSLog(@"================================================================ ======");
715 NSLog(@"[%@] %s", identifier, _cmd);
716 NSLog(@"names: %@", [[debugNames allObjects] componentsJoinedByString:@" , "]);
717 for (CDStructureInfo *info in [[phase3_namedStructureInfo allValues] sor tedArrayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
718 if ([debugNames containsObject:[[[info type] typeName] description]] )
719 NSLog(@"%@", [info shortDescription]);
720 }
721 for (CDStructureInfo *info in [phase3_nameExceptions allValues]) {
722 if ([debugNames containsObject:[info name]])
723 NSLog(@"%@ is in the name exceptions", [info name]);
724 }
725 NSLog(@"================================================================ ======");
726 }
727
728 if ([debugAnon count] > 0) {
729 NSLog(@"================================================================ ======");
730 NSLog(@"[%@] %s", identifier, _cmd);
731 NSLog(@"debug anon: %@", [[debugAnon allObjects] componentsJoinedByStrin g:@", "]);
732 for (CDStructureInfo *info in [[phase3_anonStructureInfo allValues] sort edArrayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
733 if ([debugAnon containsObject:[[info type] reallyBareTypeString]])
734 NSLog(@"%@", [info shortDescription]);
735 }
736 for (NSString *str in debugAnon)
737 if ([phase3_anonExceptions objectForKey:str] != nil)
738 NSLog(@"%@ is in the anon exceptions", str);
739 NSLog(@"================================================================ ======");
740 }
741
742 //[self logPhase3Info];
743 }
744
745 - (void)logPhase3Info;
746 {
747 NSLog(@"[%@] > %s", identifier, _cmd);
748 #if 0
749 NSLog(@"-------------------------------------------------------------------- --");
750 NSLog(@"named:");
751 for (NSString *name in [[phase3_namedStructureInfo allKeys] sortedArrayUsing Selector:@selector(compare:)]) {
752 CDStructureInfo *info;
753
754 info = [phase3_namedStructureInfo objectForKey:name];
755 NSLog(@"%@", [info shortDescription]);
756 }
757
758 NSLog(@"-------------------------------------------------------------------- --");
759 NSLog(@"anon:");
760 for (CDStructureInfo *info in [[phase3_anonStructureInfo allValues] sortedAr rayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
761 NSLog(@"%@", [info shortDescription]);
762 }
763 #endif
764 NSLog(@"==================================================================== ==");
765 NSLog(@"[%@] %s, anon exceptions:", identifier, _cmd);
766 for (CDStructureInfo *info in [[phase3_anonExceptions allValues] sortedArray UsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
767 NSLog(@"%@", [info shortDescription]);
768 }
769
770 NSLog(@"[%@] < %s", identifier, _cmd);
771 }
772
773 - (CDType *)phase3ReplacementForType:(CDType *)type;
774 {
775 NSString *name;
776
777 name = [[type typeName] description];
778 if ([@"?" isEqualToString:name]) {
779 return [(CDStructureInfo *)[phase3_anonStructureInfo objectForKey:[type reallyBareTypeString]] type];
780 } else {
781 return [(CDStructureInfo *)[phase3_namedStructureInfo objectForKey:name] type];
782 }
783
784 return nil;
785 }
786
787 //
788 // Other
789 //
790
791 // TODO (2003-12-23): Add option to show/hide this section
792 // TODO (2003-12-23): sort by name or by dependency
793 // TODO (2003-12-23): declare in modules where they were first used
794
795 - (void)appendNamedStructuresToString:(NSMutableString *)resultString
796 formatter:(CDTypeFormatter *)aTypeFormatter
797 symbolReferences:(CDSymbolReferences *)symbolReferences
798 markName:(NSString *)markName;
799 {
800 BOOL hasAddedMark = NO;
801 BOOL hasShownExceptions = NO;
802
803 for (NSString *key in [[phase3_namedStructureInfo allKeys] sortedArrayUsingS elector:@selector(compare:)]) {
804 CDStructureInfo *info;
805 BOOL shouldShow;
806
807 info = [phase3_namedStructureInfo objectForKey:key];
808 shouldShow = ![self shouldExpandStructureInfo:info];
809 if (shouldShow || debugNamedStructures) {
810 CDType *type;
811
812 if (hasAddedMark == NO) {
813 [resultString appendFormat:@"#pragma mark %@\n\n", markName];
814 hasAddedMark = YES;
815 }
816
817 type = [info type];
818 if ([[aTypeFormatter typeController] shouldShowName:[[type typeName] description]]) {
819 NSString *formattedString;
820
821 if (debugNamedStructures) {
822 [resultString appendFormat:@"// would normally show? %u\n", shouldShow];
823 [resultString appendFormat:@"// depth: %u, ref count: %u, us ed in method? %u\n", [[info type] structureDepth], [info referenceCount], [info isUsedInMethod]];
824 }
825 formattedString = [aTypeFormatter formatVariable:nil parsedType: type symbolReferences:symbolReferences];
826 if (formattedString != nil) {
827 [resultString appendString:formattedString];
828 [resultString appendString:@";\n\n"];
829 }
830 }
831 }
832 }
833
834 for (CDStructureInfo *info in [[phase3_nameExceptions allValues] sortedArray UsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
835 BOOL shouldShow;
836
837 shouldShow = ![self shouldExpandStructureInfo:info];
838 if (shouldShow || debugNamedStructures) {
839 CDType *type;
840
841 if (hasAddedMark == NO) {
842 [resultString appendFormat:@"#pragma mark %@\n\n", markName];
843 hasAddedMark = YES;
844 }
845
846 if (hasShownExceptions == NO) {
847 [resultString appendString:@"#if 0\n"];
848 [resultString appendString:@"// Names with conflicting types:\n" ];
849 hasShownExceptions = YES;
850 }
851
852 type = [info type];
853 if ([[aTypeFormatter typeController] shouldShowName:[[type typeName] description]]) {
854 NSString *formattedString;
855
856 if (debugNamedStructures) {
857 [resultString appendFormat:@"// depth: %u, ref count: %u, us ed in method? %u\n", [[info type] structureDepth], [info referenceCount], [info isUsedInMethod]];
858 //[resultString appendFormat:@"// typedefName: %@\n", [info typedefName]];
859 }
860 formattedString = [aTypeFormatter formatVariable:nil parsedType: type symbolReferences:symbolReferences];
861 if (formattedString != nil) {
862 [resultString appendFormat:@"typedef %@ %@;\n\n", formattedS tring, [info typedefName]];
863 }
864 }
865 }
866 }
867 if (hasShownExceptions)
868 [resultString appendString:@"#endif\n\n"];
869
870 if (debugNamedStructures) {
871 [resultString appendString:@"\n// Name exceptions:\n"];
872 for (CDStructureInfo *info in [[phase3_nameExceptions allValues] sortedA rrayUsingSelector:@selector(ascendingCompareByStructureDepth:)])
873 [resultString appendFormat:@"// %@\n", [info shortDescription]];
874 [resultString appendString:@"\n"];
875 }
876 }
877
878 - (void)appendTypedefsToString:(NSMutableString *)resultString
879 formatter:(CDTypeFormatter *)aTypeFormatter
880 symbolReferences:(CDSymbolReferences *)symbolReferences
881 markName:(NSString *)markName;
882 {
883 BOOL hasAddedMark = NO;
884 BOOL hasShownExceptions = NO;
885
886 for (CDStructureInfo *info in [[phase3_anonStructureInfo allValues] sortedAr rayUsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
887 BOOL shouldShow;
888
889 shouldShow = ![self shouldExpandStructureInfo:info];
890 if (shouldShow || debugAnonStructures) {
891 NSString *formattedString;
892
893 if (hasAddedMark == NO) {
894 [resultString appendFormat:@"#pragma mark %@\n\n", markName];
895 hasAddedMark = YES;
896 }
897
898 if (debugAnonStructures) {
899 [resultString appendFormat:@"// would normally show? %u\n", shou ldShow];
900 [resultString appendFormat:@"// %@\n", [[info type] reallyBareTy peString]];
901 [resultString appendFormat:@"// depth: %u, ref: %u, used in meth od? %u\n", [[info type] structureDepth], [info referenceCount], [info isUsedInMe thod]];
902 }
903 formattedString = [aTypeFormatter formatVariable:nil parsedType:[inf o type] symbolReferences:symbolReferences];
904 if (formattedString != nil) {
905 [resultString appendFormat:@"typedef %@ %@;\n\n", formattedStrin g, [info typedefName]];
906 }
907 }
908 }
909
910 // TODO (2009-08-25): Need same ref count rules for anon exceptions.
911 for (CDStructureInfo *info in [[phase3_anonExceptions allValues] sortedArray UsingSelector:@selector(ascendingCompareByStructureDepth:)]) {
912 BOOL shouldShow;
913
914 shouldShow = ![self shouldExpandStructureInfo:info];
915 if (shouldShow || debugAnonStructures) {
916 NSString *formattedString;
917
918 if (hasAddedMark == NO) {
919 [resultString appendFormat:@"#pragma mark %@\n\n", markName];
920 hasAddedMark = YES;
921 }
922
923 if (hasShownExceptions == NO) {
924 [resultString appendString:@"// Ambiguous groups\n"];
925 hasShownExceptions = YES;
926 }
927
928 if (debugAnonStructures) {
929 [resultString appendFormat:@"// %@\n", [[info type] reallyBareTy peString]];
930 [resultString appendFormat:@"// depth: %u, ref: %u, used in meth od? %u\n", [[info type] structureDepth], [info referenceCount], [info isUsedInMe thod]];
931 }
932 formattedString = [aTypeFormatter formatVariable:nil parsedType:[inf o type] symbolReferences:symbolReferences];
933 if (formattedString != nil) {
934 //[resultString appendFormat:@"%@;\n\n", formattedString];
935 [resultString appendFormat:@"typedef %@ %@;\n\n", formattedStrin g, [info typedefName]];
936 }
937 }
938 }
939
940 for (NSString *key in [[phase3_namedStructureInfo allKeys] sortedArrayUsingS elector:@selector(compare:)]) {
941 CDStructureInfo *info;
942 BOOL shouldShow;
943
944 info = [phase3_namedStructureInfo objectForKey:key];
945 shouldShow = [[info type] isTemplateType] && [info isUsedInMethod];
946 if (shouldShow || debugAnonStructures) {
947 NSString *formattedString;
948
949 if (hasAddedMark == NO) {
950 [resultString appendFormat:@"#pragma mark %@\n\n", markName];
951 hasAddedMark = YES;
952 }
953
954 if (hasShownExceptions == NO) {
955 [resultString appendString:@"// Template types\n"];
956 hasShownExceptions = YES;
957 }
958
959 if (debugAnonStructures) {
960 [resultString appendFormat:@"// %@\n", [[info type] reallyBareTy peString]];
961 [resultString appendFormat:@"// depth: %u, ref: %u, used in meth od? %u\n", [[info type] structureDepth], [info referenceCount], [info isUsedInMe thod]];
962 }
963 formattedString = [aTypeFormatter formatVariable:nil parsedType:[inf o type] symbolReferences:symbolReferences];
964 if (formattedString != nil) {
965 //[resultString appendFormat:@"%@;\n\n", formattedString];
966 [resultString appendFormat:@"typedef %@ %@;\n\n", formattedStrin g, [info typedefName]];
967 }
968 }
969 }
970 }
971
972 - (void)generateTypedefNames;
973 {
974 for (CDStructureInfo *info in [phase3_anonStructureInfo allValues]) {
975 [info generateTypedefName:anonymousBaseName];
976 }
977
978 // And do the same for each of the anon exceptions
979 for (CDStructureInfo *info in [phase3_anonExceptions allValues]) {
980 [info generateTypedefName:anonymousBaseName];
981 }
982
983 for (CDStructureInfo *info in [phase3_nameExceptions allValues]) {
984 [info generateTypedefName:[NSString stringWithFormat:@"%@_", [[[info typ e] typeName] name]]];
985 [[[info type] typeName] setName:@"?"];
986 }
987
988 for (CDStructureInfo *info in [phase3_namedStructureInfo allValues]) {
989 if ([[info type] isTemplateType] && [info isUsedInMethod]) {
990 [info generateTypedefName:[NSString stringWithFormat:@"%@_", [[[info type] typeName] name]]];
991 }
992 }
993 }
994
995 - (void)generateMemberNames;
996 {
997 for (CDStructureInfo *info in [phase3_namedStructureInfo allValues]) {
998 [[info type] generateMemberNames];
999 }
1000
1001 for (CDStructureInfo *info in [phase3_anonStructureInfo allValues]) {
1002 [[info type] generateMemberNames];
1003 }
1004
1005 for (CDStructureInfo *info in [phase3_nameExceptions allValues]) {
1006 [[info type] generateMemberNames];
1007 }
1008
1009 // And do the same for each of the anon exceptions
1010 for (CDStructureInfo *info in [phase3_anonExceptions allValues]) {
1011 [[info type] generateMemberNames];
1012 }
1013 }
1014
1015 - (BOOL)shouldExpandStructureInfo:(CDStructureInfo *)info;
1016 {
1017 return (info == nil)
1018 || ([info isUsedInMethod] == NO
1019 && ([[info type] isTemplateType] == NO || [info isUsedInMethod] == N O)
1020 && [info referenceCount] < 2
1021 && (([[info name] hasPrefix:@"_"] && [[info name] hasUnderscoreCapit alPrefix] == NO) // TODO: Don't need the first hasPrefix check now.
1022 || [@"?" isEqualToString:[info name]]));
1023 }
1024
1025 // For automatic expansion?
1026 - (BOOL)shouldExpandType:(CDType *)type;
1027 {
1028 NSString *name;
1029 CDStructureInfo *info;
1030
1031 name = [[type typeName] description];
1032 if ([@"?" isEqualToString:name]) {
1033 NSString *key;
1034
1035 key = [type reallyBareTypeString];
1036 info = [phase3_anonStructureInfo objectForKey:key];
1037 if (info == nil) {
1038 // Look for an exception
1039 info = [phase3_anonExceptions objectForKey:[type typeString]];
1040 }
1041 } else {
1042 info = [phase3_namedStructureInfo objectForKey:name];
1043 if (info == nil) {
1044 info = [phase3_nameExceptions objectForKey:[type typeString]];
1045 if (info != nil) {
1046 //NSLog(@"[%@] %s, found phase3 name exception... %@", identifie r, _cmd, [info shortDescription]);
1047 //return NO;
1048 }
1049 }
1050 }
1051
1052 return [self shouldExpandStructureInfo:info];
1053 }
1054
1055 - (NSString *)typedefNameForType:(CDType *)type;
1056 {
1057 CDStructureInfo *info;
1058
1059 info = [phase3_anonStructureInfo objectForKey:[type reallyBareTypeString]];
1060 if (info == nil) {
1061 info = [phase3_anonExceptions objectForKey:[type typeString]];
1062 //NSLog(@"fallback typedef info? %@ -- %@", [info shortDescription], [in fo typedefName]);
1063 }
1064
1065 if (info == nil) {
1066 // Check name exceptions
1067 info = [phase3_nameExceptions objectForKey:[type typeString]];
1068 #if 0
1069 if (info != nil)
1070 NSLog(@"Got typedef name for phase3 name exception: %@", [info typed efName]);
1071 #endif
1072 }
1073
1074 if (info == nil) {
1075 info = [phase3_namedStructureInfo objectForKey:[[type typeName] descript ion]];
1076 }
1077 #if 0
1078 if ([type isTemplateType] && [info typedefName] == nil) {
1079 NSLog(@"Warning: no typedef name for type: %@", [type typeString]);
1080 }
1081 #endif
1082
1083 return [info typedefName];
1084 }
1085
1086 - (void)debugName:(NSString *)name;
1087 {
1088 [debugNames addObject:name];
1089 }
1090
1091 - (void)debugAnon:(NSString *)str;
1092 {
1093 [debugAnon addObject:str];
1094 }
1095
1096 @end
OLDNEW
« no previous file with comments | « class-dump/src/CDStructureTable.h ('k') | class-dump/src/CDSymbol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698