- Timestamp:
- Jun 28, 2018, 3:29:37 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- c653b37
- Parents:
- 69918cea
- git-author:
- Rob Schluntz <rschlunt@…> (06/28/18 15:29:31)
- git-committer:
- Rob Schluntz <rschlunt@…> (06/28/18 15:29:37)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
r69918cea ra12c81f3 88 88 }; 89 89 90 struct FixQualifiedTypes final : public WithIndexer { 91 Type * postmutate( QualifiedType * ); 92 }; 93 90 94 struct HoistStruct final : public WithDeclsToAdd, public WithGuards { 91 95 /// Flattens nested struct types … … 282 286 PassVisitor<LabelAddressFixer> labelAddrFixer; 283 287 PassVisitor<HoistTypeDecls> hoistDecls; 288 PassVisitor<FixQualifiedTypes> fixQual; 284 289 285 290 acceptAll( translationUnit, hoistDecls ); … … 288 293 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling 289 294 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 295 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed 290 296 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 291 297 EliminateTypedef::eliminateTypedef( translationUnit ); // … … 341 347 void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) { 342 348 handleType( expr->type ); 349 } 350 351 352 Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) { 353 // TODO: change asserts to SemanticErrors as necessary 354 Type * parent = qualType->parent; 355 Type * child = qualType->child; 356 if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) { 357 // .T => lookup T at global scope 358 if ( StructInstType * inst = dynamic_cast< StructInstType * >( child ) ) { 359 auto aggr = indexer.globalLookupStruct( inst->name ); 360 return new StructInstType( qualType->get_qualifiers(), aggr ); 361 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( child ) ) { 362 auto aggr = indexer.globalLookupUnion( inst->name ); 363 return new UnionInstType( qualType->get_qualifiers(), aggr ); 364 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( child ) ) { 365 auto aggr = indexer.globalLookupEnum( inst->name ); 366 return new EnumInstType( qualType->get_qualifiers(), aggr ); 367 } else if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) { 368 auto td = indexer.globalLookupType( inst->name ); 369 assertf( td, "did not find type at global scope with name: %s", inst->name.c_str() ); 370 auto base = td->base; 371 if ( base ) return td->base->clone(); 372 assert( false ); 373 } else { 374 // .T => T is not a SUE type name 375 assert( false ); 376 } 377 } else { 378 // S.T => S must be an aggregate type, find the declaration for T in S. 379 AggregateDecl * aggr = nullptr; 380 if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) { 381 aggr = inst->baseStruct; 382 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) { 383 aggr = inst->baseUnion; 384 } else { 385 assert( false ); 386 } 387 assert( aggr ); // TODO: need to handle forward declarations 388 for ( Declaration * member : aggr->members ) { 389 if ( StructInstType * inst = dynamic_cast< StructInstType * >( child ) ) { 390 if ( StructDecl * aggr = dynamic_cast< StructDecl * >( member ) ) { 391 if ( aggr->name == inst->name ) { 392 return new StructInstType( qualType->get_qualifiers(), aggr ); 393 } 394 } 395 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( child ) ) { 396 if ( UnionDecl * aggr = dynamic_cast< UnionDecl * > ( member ) ) { 397 if ( aggr->name == inst->name ) { 398 return new UnionInstType( qualType->get_qualifiers(), aggr ); 399 } 400 } 401 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( child ) ) { 402 if ( EnumDecl * aggr = dynamic_cast< EnumDecl * > ( member ) ) { 403 if ( aggr->name == inst->name ) { 404 return new EnumInstType( qualType->get_qualifiers(), aggr ); 405 } 406 } 407 } else if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) { 408 // struct typedefs are being replaced by forward decls too early; move it to hoist struct 409 if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) { 410 if ( aggr->name == inst->name ) { 411 if ( aggr->base ) return aggr->base->clone(); 412 assert( false ); 413 } 414 } 415 } else { 416 // S.T - S is not an aggregate => error 417 assertf( false, "unhandled qualified child type: %s", toCString(qualType) ); 418 } 419 } 420 // failed to find a satisfying definition of type 421 assertf( false, "failed to find a satisfying definition of %s in %s", toCString(child), toCString(parent) ); 422 } 423 424 // ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup? 343 425 } 344 426
Note: See TracChangeset
for help on using the changeset viewer.