Changeset 54dd994 for src/SymTab
- Timestamp:
- Jun 24, 2019, 10:30:47 AM (7 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, stuck-waitfor-destruct
- Children:
- 84917e2
- Parents:
- 3c6e417 (diff), 9e0a360 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/SymTab
- Files:
-
- 5 edited
-
Autogen.cc (modified) (3 diffs)
-
Autogen.h (modified) (8 diffs)
-
FixFunction.cc (modified) (4 diffs)
-
FixFunction.h (modified) (1 diff)
-
Validate.cc (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
r3c6e417 r54dd994 24 24 #include <vector> // for vector 25 25 26 #include "AST/Decl.hpp" 26 27 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 27 28 #include "Common/PassVisitor.h" // for PassVisitor … … 209 210 } 210 211 212 bool isUnnamedBitfield( const ast::ObjectDecl * obj ) { 213 return obj && obj->name.empty() && obj->bitfieldWidth; 214 } 215 211 216 /// inserts a forward declaration for functionDecl into declsToAdd 212 217 void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) { … … 388 393 389 394 void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) { 390 InitTweak::InitExpander srcParam( src );395 InitTweak::InitExpander_old srcParam( src ); 391 396 392 397 // assign to destination -
src/SymTab/Autogen.h
r3c6e417 r54dd994 17 17 18 18 #include <cassert> // for assert 19 #include <iterator> // for back_inserter 19 20 #include <string> // for string 20 21 22 #include "AST/Decl.hpp" 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 25 #include "AST/Node.hpp" 26 #include "AST/Stmt.hpp" 27 #include "AST/Type.hpp" 21 28 #include "CodeGen/OperatorTable.h" 22 29 #include "Common/UniqueName.h" // for UniqueName 30 #include "Common/utility.h" // for splice 23 31 #include "InitTweak/InitTweak.h" // for InitExpander 24 32 #include "SynTree/Constant.h" // for Constant … … 36 44 /// returns true if obj's name is the empty string and it has a bitfield width 37 45 bool isUnnamedBitfield( ObjectDecl * obj ); 46 bool isUnnamedBitfield( const ast::ObjectDecl * obj ); 38 47 39 48 /// generate the type of an assignment function for paramType. … … 49 58 FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true ); 50 59 60 /// Enum for loop direction 61 enum LoopDirection { LoopBackward, LoopForward }; 62 51 63 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 52 64 template< typename OutputIterator > 53 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 65 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 66 67 template< typename OutIter > 68 ast::ptr< ast::Stmt > genCall( 69 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 70 const CodeLocation & loc, const std::string & fname, OutIter && out, 71 const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward ); 54 72 55 73 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 56 74 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 57 75 template< typename OutputIterator > 58 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {76 Statement * genScalarCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) { 59 77 bool isReferenceCtorDtor = false; 60 78 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { … … 106 124 } 107 125 126 /// inserts into out a generated call expression to function fname with arguments dstParam and 127 /// srcParam. Should only be called with non-array types. 128 /// optionally returns a statement which must be inserted prior to the containing loop, if 129 /// there is one 130 template< typename OutIter > 131 ast::ptr< ast::Stmt > genScalarCall( 132 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 133 const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type, 134 const ast::Type * addCast = nullptr 135 ) { 136 bool isReferenceCtorDtor = false; 137 if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { 138 // reference constructors are essentially application of the rebind operator. 139 // apply & to both arguments, do not need a cast 140 fname = "?=?"; 141 dstParam = new ast::AddressExpr{ dstParam }; 142 addCast = nullptr; 143 isReferenceCtorDtor = true; 144 } 145 146 // want to be able to generate assignment, ctor, and dtor generically, so fname is one of 147 // "?=?", "?{}", or "^?{}" 148 ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } }; 149 150 if ( addCast ) { 151 // cast to T& with qualifiers removed, so that qualified objects can be constructed and 152 // destructed with the same functions as non-qualified objects. Unfortunately, lvalue 153 // is considered a qualifier - for AddressExpr to resolve, its argument must have an 154 // lvalue-qualified type, so remove all qualifiers except lvalue. 155 // xxx -- old code actually removed lvalue too... 156 ast::ptr< ast::Type > guard = addCast; // prevent castType from mutating addCast 157 ast::ptr< ast::Type > castType = addCast; 158 ast::remove_qualifiers( 159 castType, 160 ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic ); 161 dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } }; 162 } 163 fExpr->args.emplace_back( dstParam ); 164 165 const ast::Stmt * listInit = srcParam.buildListInit( fExpr ); 166 167 // fetch next set of arguments 168 ++srcParam; 169 170 // return if adding reference fails -- will happen on default ctor and dtor 171 if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit; 172 173 std::vector< ast::ptr< ast::Expr > > args = *srcParam; 174 splice( fExpr->args, args ); 175 176 *out++ = new ast::ExprStmt{ loc, fExpr }; 177 178 srcParam.clearArrayIndices(); 179 180 return listInit; 181 } 182 108 183 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 109 184 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 110 185 template< typename OutputIterator > 111 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {186 void genArrayCall( InitTweak::InitExpander_old & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) { 112 187 static UniqueName indexName( "_index" ); 113 188 … … 170 245 } 171 246 247 /// Store in out a loop which calls fname on each element of the array with srcParam and 248 /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0 249 template< typename OutIter > 250 void genArrayCall( 251 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 252 const CodeLocation & loc, const std::string & fname, OutIter && out, 253 const ast::ArrayType * array, const ast::Type * addCast = nullptr, 254 LoopDirection forward = LoopForward 255 ) { 256 static UniqueName indexName( "_index" ); 257 258 // for a flexible array member nothing is done -- user must define own assignment 259 if ( ! array->dimension ) return; 260 261 if ( addCast ) { 262 // peel off array layer from cast 263 addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base; 264 } 265 266 ast::ptr< ast::Expr > begin, end, cmp, update; 267 268 if ( forward ) { 269 // generate: for ( int i = 0; i < N; ++i ) 270 begin = ast::ConstantExpr::from_int( loc, 0 ); 271 end = array->dimension; 272 cmp = new ast::NameExpr{ loc, "?<?" }; 273 update = new ast::NameExpr{ loc, "++?" }; 274 } else { 275 // generate: for ( int i = N-1; i >= 0; --i ) 276 begin = new ast::UntypedExpr{ 277 loc, new ast::NameExpr{ loc, "?-?" }, 278 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } }; 279 end = ast::ConstantExpr::from_int( loc, 0 ); 280 cmp = new ast::NameExpr{ loc, "?>=?" }; 281 update = new ast::NameExpr{ loc, "--?" }; 282 } 283 284 ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{ 285 loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt }, 286 new ast::SingleInit{ loc, begin } }; 287 288 ast::ptr< ast::Expr > cond = new ast::UntypedExpr{ 289 loc, cmp, { new ast::VariableExpr{ loc, index }, end } }; 290 291 ast::ptr< ast::Expr > inc = new ast::UntypedExpr{ 292 loc, update, { new ast::VariableExpr{ loc, index } } }; 293 294 ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{ 295 loc, new ast::NameExpr{ loc, "?[?]" }, 296 { dstParam, new ast::VariableExpr{ loc, index } } }; 297 298 // srcParam must keep track of the array indices to build the source parameter and/or 299 // array list initializer 300 srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension ); 301 302 // for stmt's body, eventually containing call 303 ast::CompoundStmt * body = new ast::CompoundStmt{ loc }; 304 ast::ptr< ast::Stmt > listInit = genCall( 305 srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast, 306 forward ); 307 308 // block containing the stmt and index variable 309 ast::CompoundStmt * block = new ast::CompoundStmt{ loc }; 310 block->push_back( new ast::DeclStmt{ loc, index } ); 311 if ( listInit ) { block->push_back( listInit ); } 312 block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } ); 313 314 *out++ = block; 315 } 316 172 317 template< typename OutputIterator > 173 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {318 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) { 174 319 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 175 320 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 180 325 } 181 326 327 template< typename OutIter > 328 ast::ptr< ast::Stmt > genCall( 329 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 330 const CodeLocation & loc, const std::string & fname, OutIter && out, 331 const ast::Type * type, const ast::Type * addCast, LoopDirection forward 332 ) { 333 if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) { 334 genArrayCall( 335 srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast, 336 forward ); 337 return {}; 338 } else { 339 return genScalarCall( 340 srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast ); 341 } 342 } 343 182 344 /// inserts into out a generated call expression to function fname with arguments dstParam 183 345 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the … … 185 347 /// ImplicitCtorDtorStmt node. 186 348 template< typename OutputIterator > 187 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {349 void genImplicitCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 188 350 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 189 351 assert( obj ); … … 213 375 } 214 376 } 377 378 static inline ast::ptr< ast::Stmt > genImplicitCall( 379 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 380 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 381 LoopDirection forward = LoopForward 382 ) { 383 // unnamed bit fields are not copied as they cannot be accessed 384 if ( isUnnamedBitfield( obj ) ) return {}; 385 386 ast::ptr< ast::Type > addCast = nullptr; 387 if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) { 388 assert( dstParam->result ); 389 addCast = dstParam->result; 390 } 391 392 std::vector< ast::ptr< ast::Stmt > > stmts; 393 genCall( 394 srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward ); 395 396 if ( stmts.empty() ) { 397 return {}; 398 } else if ( stmts.size() == 1 ) { 399 const ast::Stmt * callStmt = stmts.front(); 400 if ( addCast ) { 401 // implicitly generated ctor/dtor calls should be wrapped so that later passes are 402 // aware they were generated. 403 callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt }; 404 } 405 return callStmt; 406 } else { 407 assert( false ); 408 return {}; 409 } 410 } 215 411 } // namespace SymTab 216 412 -
src/SymTab/FixFunction.cc
r3c6e417 r54dd994 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
r3c6e417 r54dd994 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
r3c6e417 r54dd994 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.