Changeset c1ed2ee
- Timestamp:
- Jun 21, 2019, 3:41:36 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 8d61d620
- Parents:
- 9af00d23
- Location:
- src
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Stmt.hpp
r9af00d23 rc1ed2ee 143 143 144 144 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * thenPart, 145 Stmt * const elsePart, std::vector<ptr<Stmt>> && inits,145 const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {}, 146 146 std::vector<Label> && labels = {} ) 147 147 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart), -
src/Common/utility.h
r9af00d23 rc1ed2ee 34 34 class Expression; 35 35 36 /// bring std::move into global scope 37 using std::move; 38 39 /// partner to move that copies any copyable type 40 template<typename T> 41 T copy( const T & x ) { return x; } 42 36 43 template< typename T > 37 44 static inline T * maybeClone( const T *orig ) { -
src/InitTweak/InitTweak.cc
r9af00d23 rc1ed2ee 22 22 23 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 24 25 #include "AST/Node.hpp" 26 #include "AST/Pass.hpp" 25 27 #include "AST/Stmt.hpp" 26 28 #include "AST/Type.hpp" … … 85 87 }; 86 88 87 struct InitFlattener : public WithShortCircuiting {89 struct InitFlattener_old : public WithShortCircuiting { 88 90 void previsit( SingleInit * singleInit ) { 89 91 visit_children = false; … … 93 95 }; 94 96 95 } 97 struct InitFlattener_new : public ast::WithShortCircuiting { 98 std::vector< ast::ptr< ast::Expr > > argList; 99 100 void previsit( const ast::SingleInit * singleInit ) { 101 visit_children = false; 102 argList.emplace_back( singleInit->value ); 103 } 104 }; 105 106 } // anonymous namespace 96 107 97 108 std::list< Expression * > makeInitList( Initializer * init ) { 98 PassVisitor<InitFlattener > flattener;109 PassVisitor<InitFlattener_old> flattener; 99 110 maybeAccept( init, flattener ); 100 111 return flattener.pass.argList; … … 114 125 115 126 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 116 #warning unimplmented 117 (void)init; 118 assert(false); 119 return {}; 127 ast::Pass< InitFlattener_new > flattener; 128 maybe_accept( init, flattener ); 129 return std::move( flattener.pass.argList ); 120 130 } 121 131 … … 309 319 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 310 320 virtual ast::ptr< ast::Stmt > buildListInit( 311 constast::UntypedExpr * callExpr, IndexList & indices ) = 0;321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 312 322 }; 313 323 314 324 namespace { 325 template< typename Out > 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 328 const ast::Init * init, Out & out 329 ) { 330 const CodeLocation & loc = init->location; 331 332 auto cond = new ast::UntypedExpr{ 333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } }; 334 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init ); 336 splice( callExpr->args, args ); 337 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } ); 339 340 out.emplace_back( new ast::ExprStmt{ 341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } ); 342 } 343 344 template< typename Out > 345 void build( 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 347 const ast::Init * init, Out & out 348 ) { 349 if ( indices.empty() ) return; 350 351 unsigned idx = 0; 352 353 const ast::Expr * index = indices[idx++]; 354 assert( idx != indices.size() ); 355 const ast::Expr * dimension = indices[idx++]; 356 357 if ( idx == indices.size() ) { 358 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 359 for ( const ast::Init * init : *listInit ) { 360 buildCallExpr( callExpr, index, dimension, init, out ); 361 } 362 } else { 363 buildCallExpr( callExpr, index, dimension, init, out ); 364 } 365 } else { 366 const CodeLocation & loc = init->location; 367 368 unsigned long cond = 0; 369 auto listInit = dynamic_cast< const ast::ListInit * >( init ); 370 if ( ! listInit ) { SemanticError( loc, "unbalanced list initializers" ); } 371 372 static UniqueName targetLabel( "L__autogen__" ); 373 ast::Label switchLabel{ 374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } }; 375 376 std::vector< ast::ptr< ast::Stmt > > branches; 377 for ( const ast::Init * init : *listInit ) { 378 auto condition = ast::ConstantExpr::from_ulong( loc, cond ); 379 ++cond; 380 381 std::vector< ast::ptr< ast::Stmt > > stmts; 382 build( callExpr, indices, init, stmts ); 383 stmts.emplace_back( 384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } ); 385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } ); 386 } 387 out.emplace_back( new ast::SwitchStmt{ loc, index, std::move( branches ) } ); 388 out.emplace_back( new ast::NullStmt{ loc, { switchLabel } } ); 389 } 390 } 391 315 392 class InitImpl_new final : public InitExpander_new::ExpanderImpl { 316 393 ast::ptr< ast::Init > init; … … 323 400 324 401 ast::ptr< ast::Stmt > buildListInit( 325 constast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 326 403 ) override { 327 #warning unimplemented 328 (void)callExpr; (void)indices; 329 assert(false); 330 return {}; 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 408 // statement consuming all of expander's elements 409 410 if ( ! init ) return {}; 411 412 std::list< ast::ptr< ast::Stmt > > stmts; 413 build( callExpr, indices, init, stmts ); 414 if ( stmts.empty() ) { 415 return {}; 416 } else { 417 auto block = new ast::CompoundStmt{ init->location, std::move( stmts ) }; 418 init = nullptr; // consumed in creating the list init 419 return block; 420 } 331 421 } 332 422 }; … … 340 430 InitExpander_new::IndexList & indices 341 431 ) override { 342 #warning unimplemented 343 (void)indices; 344 assert(false); 345 return {}; 432 if ( ! arg ) return {}; 433 434 const CodeLocation & loc = arg->location; 435 const ast::Expr * expr = arg; 436 for ( auto it = indices.rbegin(); it != indices.rend(); ++it ) { 437 // go through indices and layer on subscript exprs ?[?] 438 ++it; 439 expr = new ast::UntypedExpr{ 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 } 442 return { expr }; 346 443 } 347 444 348 445 ast::ptr< ast::Stmt > buildListInit( 349 constast::UntypedExpr *, InitExpander_new::IndexList &446 ast::UntypedExpr *, InitExpander_new::IndexList & 350 447 ) override { 351 448 return {}; … … 369 466 /// builds statement which has the same semantics as a C-style list initializer (for array 370 467 /// initializers) using callExpr as the base expression to perform initialization 371 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( constast::UntypedExpr * callExpr ) {468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { 372 469 return expander->buildListInit( callExpr, indices ); 373 470 } -
src/InitTweak/InitTweak.h
r9af00d23 rc1ed2ee 154 154 155 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization 157 ast::ptr< ast::Stmt > buildListInit( const ast::UntypedExpr * callExpr ); 156 /// initializers) using callExpr as the base expression to perform initialization. 157 /// Mutates callExpr 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); 158 159 159 160 void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ); -
src/ResolvExpr/AlternativeFinder.cc
r9af00d23 rc1ed2ee 56 56 #define PRINT( text ) if ( resolvep ) { text } 57 57 //#define DEBUG_COST 58 59 using std::move;60 61 /// copies any copyable type62 template<typename T>63 T copy(const T& x) { return x; }64 58 65 59 namespace ResolvExpr { -
src/ResolvExpr/CandidateFinder.cpp
r9af00d23 rc1ed2ee 39 39 #include "AST/SymbolTable.hpp" 40 40 #include "AST/Type.hpp" 41 #include "Common/utility.h" // for move, copy 41 42 #include "SymTab/Mangler.h" 42 43 #include "SymTab/Validate.h" // for validateType … … 46 47 47 48 namespace ResolvExpr { 48 49 using std::move;50 51 /// partner to move that copies any copyable type52 template<typename T>53 T copy( const T & x ) { return x; }54 49 55 50 const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost ) { -
src/SymTab/FixFunction.cc
r9af00d23 rc1ed2ee 18 18 #include <list> // for list 19 19 20 #include "Common/utility.h" // for maybeClone 20 #include "AST/Decl.hpp" 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 23 #include "Common/utility.h" // for maybeClone, copy 21 24 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarati... 22 25 #include "SynTree/Expression.h" // for Expression … … 24 27 25 28 namespace SymTab { 26 FixFunction::FixFunction() : isVoid( false ) {} 29 class FixFunction_old : public WithShortCircuiting { 30 typedef Mutator Parent; 31 public: 32 FixFunction_old() : isVoid( false ) {} 27 33 34 void premutate(FunctionDecl *functionDecl); 35 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 28 36 29 DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) { 37 Type * postmutate(ArrayType * arrayType); 38 39 void premutate(ArrayType * arrayType); 40 void premutate(VoidType * voidType); 41 void premutate(BasicType * basicType); 42 void premutate(PointerType * pointerType); 43 void premutate(StructInstType * aggregateUseType); 44 void premutate(UnionInstType * aggregateUseType); 45 void premutate(EnumInstType * aggregateUseType); 46 void premutate(TraitInstType * aggregateUseType); 47 void premutate(TypeInstType * aggregateUseType); 48 void premutate(TupleType * tupleType); 49 void premutate(VarArgsType * varArgsType); 50 void premutate(ZeroType * zeroType); 51 void premutate(OneType * oneType); 52 53 bool isVoid; 54 }; 55 56 DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) { 30 57 // can't delete function type because it may contain assertions, so transfer ownership to new object 31 58 ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes ); … … 41 68 // does not cause an error 42 69 43 Type * FixFunction ::postmutate(ArrayType *arrayType) {70 Type * FixFunction_old::postmutate(ArrayType *arrayType) { 44 71 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 45 72 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic ); … … 51 78 } 52 79 53 void FixFunction ::premutate(VoidType *) {80 void FixFunction_old::premutate(VoidType *) { 54 81 isVoid = true; 55 82 } 56 83 57 void FixFunction ::premutate(FunctionDecl *) { visit_children = false; }58 void FixFunction ::premutate(ArrayType *) { visit_children = false; }59 void FixFunction ::premutate(BasicType *) { visit_children = false; }60 void FixFunction ::premutate(PointerType *) { visit_children = false; }61 void FixFunction ::premutate(StructInstType *) { visit_children = false; }62 void FixFunction ::premutate(UnionInstType *) { visit_children = false; }63 void FixFunction ::premutate(EnumInstType *) { visit_children = false; }64 void FixFunction ::premutate(TraitInstType *) { visit_children = false; }65 void FixFunction ::premutate(TypeInstType *) { visit_children = false; }66 void FixFunction ::premutate(TupleType *) { visit_children = false; }67 void FixFunction ::premutate(VarArgsType *) { visit_children = false; }68 void FixFunction ::premutate(ZeroType *) { visit_children = false; }69 void FixFunction ::premutate(OneType *) { visit_children = false; }84 void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; } 85 void FixFunction_old::premutate(ArrayType *) { visit_children = false; } 86 void FixFunction_old::premutate(BasicType *) { visit_children = false; } 87 void FixFunction_old::premutate(PointerType *) { visit_children = false; } 88 void FixFunction_old::premutate(StructInstType *) { visit_children = false; } 89 void FixFunction_old::premutate(UnionInstType *) { visit_children = false; } 90 void FixFunction_old::premutate(EnumInstType *) { visit_children = false; } 91 void FixFunction_old::premutate(TraitInstType *) { visit_children = false; } 92 void FixFunction_old::premutate(TypeInstType *) { visit_children = false; } 93 void FixFunction_old::premutate(TupleType *) { visit_children = false; } 94 void FixFunction_old::premutate(VarArgsType *) { visit_children = false; } 95 void FixFunction_old::premutate(ZeroType *) { visit_children = false; } 96 void FixFunction_old::premutate(OneType *) { visit_children = false; } 70 97 71 98 bool fixFunction( DeclarationWithType *& dwt ) { 72 PassVisitor<FixFunction > fixer;99 PassVisitor<FixFunction_old> fixer; 73 100 dwt = dwt->acceptMutator( fixer ); 74 101 return fixer.pass.isVoid; 75 102 } 103 104 namespace { 105 struct FixFunction_new final : public ast::WithShortCircuiting { 106 bool isVoid = false; 107 108 void premutate( const ast::FunctionDecl * ) { visit_children = false; } 109 110 const ast::DeclWithType * postmutate( const ast::FunctionDecl * func ) { 111 return new ast::ObjectDecl{ 112 func->location, func->name, new ast::PointerType{ func->type }, nullptr, 113 func->storage, func->linkage, nullptr, copy( func->attributes ) }; 114 } 115 116 void premutate( const ast::ArrayType * ) { visit_children = false; } 117 118 const ast::Type * postmutate( const ast::ArrayType * array ) { 119 return new ast::PointerType{ 120 array->base, array->dimension, array->isVarLen, array->isStatic, 121 array->qualifiers }; 122 } 123 124 void premutate( const ast::VoidType * ) { isVoid = true; } 125 126 void premutate( const ast::BasicType * ) { visit_children = false; } 127 void premutate( const ast::PointerType * ) { visit_children = false; } 128 void premutate( const ast::StructInstType * ) { visit_children = false; } 129 void premutate( const ast::UnionInstType * ) { visit_children = false; } 130 void premutate( const ast::EnumInstType * ) { visit_children = false; } 131 void premutate( const ast::TraitInstType * ) { visit_children = false; } 132 void premutate( const ast::TypeInstType * ) { visit_children = false; } 133 void premutate( const ast::TupleType * ) { visit_children = false; } 134 void premutate( const ast::VarArgsType * ) { visit_children = false; } 135 void premutate( const ast::ZeroType * ) { visit_children = false; } 136 void premutate( const ast::OneType * ) { visit_children = false; } 137 }; 138 } // anonymous namespace 139 140 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) { 141 ast::Pass< FixFunction_new > fixer; 142 dwt = dwt->accept( fixer ); 143 isVoid |= fixer.pass.isVoid; 144 return dwt; 145 } 146 76 147 } // namespace SymTab 77 148 -
src/SymTab/FixFunction.h
r9af00d23 rc1ed2ee 19 19 #include "SynTree/SynTree.h" // for Types 20 20 21 namespace ast { 22 class DeclWithType; 23 } 24 21 25 namespace SymTab { 22 /// Replaces function and array types by equivalent pointer types. 23 class FixFunction : public WithShortCircuiting { 24 typedef Mutator Parent; 25 public: 26 FixFunction(); 26 /// Replaces function and array types by equivalent pointer types. Returns true if type is 27 /// void 28 bool fixFunction( DeclarationWithType *& ); 27 29 28 void premutate(FunctionDecl *functionDecl); 29 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 30 31 Type * postmutate(ArrayType * arrayType); 32 33 void premutate(ArrayType * arrayType); 34 void premutate(VoidType * voidType); 35 void premutate(BasicType * basicType); 36 void premutate(PointerType * pointerType); 37 void premutate(StructInstType * aggregateUseType); 38 void premutate(UnionInstType * aggregateUseType); 39 void premutate(EnumInstType * aggregateUseType); 40 void premutate(TraitInstType * aggregateUseType); 41 void premutate(TypeInstType * aggregateUseType); 42 void premutate(TupleType * tupleType); 43 void premutate(VarArgsType * varArgsType); 44 void premutate(ZeroType * zeroType); 45 void premutate(OneType * oneType); 46 47 bool isVoid; 48 }; 49 50 bool fixFunction( DeclarationWithType *& ); 30 /// Returns declaration with function and array types replaced by equivalent pointer types. 31 /// Sets isVoid to true if type is void 32 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ); 51 33 } // namespace SymTab 52 34 -
src/SymTab/Validate.cc
r9af00d23 rc1ed2ee 46 46 #include <utility> // for pair 47 47 48 #include "AST/Decl.hpp" 49 #include "AST/Node.hpp" 50 #include "AST/Pass.hpp" 51 #include "AST/SymbolTable.hpp" 52 #include "AST/Type.hpp" 48 53 #include "CodeGen/CodeGenerator.h" // for genName 49 54 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign … … 124 129 125 130 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 126 struct EnumAndPointerDecay {131 struct EnumAndPointerDecay_old { 127 132 void previsit( EnumDecl *aggregateDecl ); 128 133 void previsit( FunctionType *func ); … … 130 135 131 136 /// Associates forward declarations of aggregates with their definitions 132 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting {133 LinkReferenceToTypes ( const Indexer *indexer );137 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 138 LinkReferenceToTypes_old( const Indexer *indexer ); 134 139 void postvisit( TypeInstType *typeInst ); 135 140 … … 165 170 166 171 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 167 struct ForallPointerDecay final {172 struct ForallPointerDecay_old final { 168 173 void previsit( ObjectDecl * object ); 169 174 void previsit( FunctionDecl * func ); … … 290 295 291 296 void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) { 292 PassVisitor<EnumAndPointerDecay > epc;293 PassVisitor<LinkReferenceToTypes > lrt( nullptr );294 PassVisitor<ForallPointerDecay > fpd;297 PassVisitor<EnumAndPointerDecay_old> epc; 298 PassVisitor<LinkReferenceToTypes_old> lrt( nullptr ); 299 PassVisitor<ForallPointerDecay_old> fpd; 295 300 PassVisitor<CompoundLiteral> compoundliteral; 296 301 PassVisitor<ValidateGenericParameters> genericParams; … … 305 310 ReplaceTypedef::replaceTypedef( translationUnit ); 306 311 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 307 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 mangling312 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling 308 313 } 309 314 { … … 314 319 }); 315 320 Stats::Time::TimeBlock("Fix Qualified Types", [&]() { 316 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes , because aggregate members are accessed321 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 317 322 }); 318 323 Stats::Time::TimeBlock("Hoist Structs", [&]() { … … 326 331 Stats::Heap::newPass("validate-C"); 327 332 Stats::Time::BlockGuard guard("validate-C"); 328 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 333 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes_old 329 334 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 330 335 ReturnChecker::checkFunctionReturns( translationUnit ); … … 344 349 }); 345 350 Stats::Time::TimeBlock("Generate Autogen routines", [&]() { 346 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay 351 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old 347 352 }); 348 353 } … … 385 390 386 391 void validateType( Type *type, const Indexer *indexer ) { 387 PassVisitor<EnumAndPointerDecay > epc;388 PassVisitor<LinkReferenceToTypes > lrt( indexer );389 PassVisitor<ForallPointerDecay > fpd;392 PassVisitor<EnumAndPointerDecay_old> epc; 393 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); 394 PassVisitor<ForallPointerDecay_old> fpd; 390 395 type->accept( epc ); 391 396 type->accept( lrt ); … … 586 591 } 587 592 588 void EnumAndPointerDecay ::previsit( EnumDecl *enumDecl ) {593 void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) { 589 594 // Set the type of each member of the enumeration to be EnumConstant 590 595 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { … … 618 623 } 619 624 620 void EnumAndPointerDecay ::previsit( FunctionType *func ) {625 void EnumAndPointerDecay_old::previsit( FunctionType *func ) { 621 626 // Fix up parameters and return types 622 627 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 624 629 } 625 630 626 LinkReferenceToTypes ::LinkReferenceToTypes( const Indexer *other_indexer ) {631 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) { 627 632 if ( other_indexer ) { 628 633 local_indexer = other_indexer; … … 632 637 } 633 638 634 void LinkReferenceToTypes ::postvisit( EnumInstType *enumInst ) {639 void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) { 635 640 EnumDecl *st = local_indexer->lookupEnum( enumInst->name ); 636 641 // it's not a semantic error if the enum is not found, just an implicit forward declaration … … 652 657 } 653 658 654 void LinkReferenceToTypes ::postvisit( StructInstType *structInst ) {659 void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) { 655 660 StructDecl *st = local_indexer->lookupStruct( structInst->name ); 656 661 // it's not a semantic error if the struct is not found, just an implicit forward declaration … … 665 670 } 666 671 667 void LinkReferenceToTypes ::postvisit( UnionInstType *unionInst ) {672 void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) { 668 673 UnionDecl *un = local_indexer->lookupUnion( unionInst->name ); 669 674 // it's not a semantic error if the union is not found, just an implicit forward declaration … … 678 683 } 679 684 680 void LinkReferenceToTypes ::previsit( QualifiedType * ) {685 void LinkReferenceToTypes_old::previsit( QualifiedType * ) { 681 686 visit_children = false; 682 687 } 683 688 684 void LinkReferenceToTypes ::postvisit( QualifiedType * qualType ) {689 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 685 690 // linking only makes sense for the 'oldest ancestor' of the qualified type 686 691 qualType->parent->accept( *visitor ); … … 729 734 } 730 735 731 void LinkReferenceToTypes ::postvisit( TraitDecl * traitDecl ) {736 void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) { 732 737 if ( traitDecl->name == "sized" ) { 733 738 // "sized" is a special trait - flick the sized status on for the type variable … … 751 756 } 752 757 753 void LinkReferenceToTypes ::postvisit( TraitInstType * traitInst ) {758 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 754 759 // handle other traits 755 760 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name ); … … 777 782 } 778 783 779 void LinkReferenceToTypes ::postvisit( EnumDecl *enumDecl ) {784 void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) { 780 785 // visit enum members first so that the types of self-referencing members are updated properly 781 786 if ( enumDecl->body ) { … … 799 804 } 800 805 801 void LinkReferenceToTypes ::renameGenericParams( std::list< TypeDecl * > & params ) {806 void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) { 802 807 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 803 808 // forall(otype T) … … 817 822 } 818 823 819 void LinkReferenceToTypes ::previsit( StructDecl * structDecl ) {824 void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) { 820 825 renameGenericParams( structDecl->parameters ); 821 826 } 822 827 823 void LinkReferenceToTypes ::previsit( UnionDecl * unionDecl ) {828 void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) { 824 829 renameGenericParams( unionDecl->parameters ); 825 830 } 826 831 827 void LinkReferenceToTypes ::postvisit( StructDecl *structDecl ) {832 void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) { 828 833 // visit struct members first so that the types of self-referencing members are updated properly 829 834 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 839 844 } 840 845 841 void LinkReferenceToTypes ::postvisit( UnionDecl *unionDecl ) {846 void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) { 842 847 if ( unionDecl->body ) { 843 848 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); … … 851 856 } 852 857 853 void LinkReferenceToTypes ::postvisit( TypeInstType *typeInst ) {858 void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) { 854 859 // ensure generic parameter instances are renamed like the base type 855 860 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; … … 888 893 } 889 894 890 void ForallPointerDecay ::previsit( ObjectDecl *object ) {895 void ForallPointerDecay_old::previsit( ObjectDecl *object ) { 891 896 // ensure that operator names only apply to functions or function pointers 892 897 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 896 901 } 897 902 898 void ForallPointerDecay ::previsit( FunctionDecl *func ) {903 void ForallPointerDecay_old::previsit( FunctionDecl *func ) { 899 904 func->fixUniqueId(); 900 905 } 901 906 902 void ForallPointerDecay ::previsit( FunctionType * ftype ) {907 void ForallPointerDecay_old::previsit( FunctionType * ftype ) { 903 908 forallFixer( ftype->forall, ftype ); 904 909 } 905 910 906 void ForallPointerDecay ::previsit( StructDecl * aggrDecl ) {911 void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) { 907 912 forallFixer( aggrDecl->parameters, aggrDecl ); 908 913 } 909 914 910 void ForallPointerDecay ::previsit( UnionDecl * aggrDecl ) {915 void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) { 911 916 forallFixer( aggrDecl->parameters, aggrDecl ); 912 917 } … … 1368 1373 } 1369 1374 1370 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1371 #warning unimplemented 1372 (void)type; (void)symtab; 1373 assert(false); 1374 return nullptr; 1375 } 1375 namespace { 1376 /// Replaces enum types by int, and function/array types in function parameter and return 1377 /// lists by appropriate pointers 1378 struct EnumAndPointerDecay_new { 1379 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { 1380 // set the type of each member of the enumeration to be EnumConstant 1381 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1382 // build new version of object with EnumConstant 1383 ast::ptr< ast::ObjectDecl > obj = 1384 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1385 obj.get_and_mutate()->type = 1386 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1387 1388 // set into decl 1389 ast::EnumDecl * mut = mutate( enumDecl ); 1390 mut->members[i] = obj.get(); 1391 enumDecl = mut; 1392 } 1393 return enumDecl; 1394 } 1395 1396 static const ast::FunctionType * fixFunctionList( 1397 const ast::FunctionType * func, 1398 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1399 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1400 ) { 1401 const auto & dwts = func->*field; 1402 unsigned nvals = dwts.size(); 1403 bool hasVoid = false; 1404 for ( unsigned i = 0; i < nvals; ++i ) { 1405 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1406 } 1407 1408 // the only case in which "void" is valid is where it is the only one in the list 1409 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1410 SemanticError( 1411 dwts.front()->location, func, "invalid type void in function type" ); 1412 } 1413 1414 // one void is the only thing in the list, remove it 1415 if ( hasVoid ) { 1416 func = ast::mutate_field( 1417 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1418 } 1419 1420 return func; 1421 } 1422 1423 const ast::FunctionType * previsit( const ast::FunctionType * func ) { 1424 func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs ); 1425 return fixFunctionList( func, &ast::FunctionType::returns ); 1426 } 1427 }; 1428 1429 /// Associates forward declarations of aggregates with their definitions 1430 struct LinkReferenceToTypes_new final 1431 : public ast::WithSymbolTable, public ast::WithGuards, public 1432 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1433 1434 const ast::SymbolTable * localSyms; 1435 1436 LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {} 1437 1438 #warning incomplete 1439 }; 1440 1441 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1442 /// each object and function declaration a unique ID 1443 struct ForallPointerDecay_new { 1444 #warning incomplete 1445 }; 1446 } // anonymous namespace 1447 1448 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1449 ast::Pass< EnumAndPointerDecay_new > epc; 1450 ast::Pass< LinkReferenceToTypes_new > lrt{ symtab }; 1451 ast::Pass< ForallPointerDecay_new > fpd; 1452 1453 return type->accept( epc )->accept( lrt )->accept( fpd ); 1454 } 1455 1376 1456 } // namespace SymTab 1377 1457
Note: See TracChangeset
for help on using the changeset viewer.