OLD | NEW |
(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 |
OLD | NEW |