- Timestamp:
- Nov 14, 2022, 11:52:44 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 7d9598d8
- Parents:
- b77f0e1 (diff), 19a8c40 (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
- Files:
-
- 1 added
- 39 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rb77f0e1 r63be3387 234 234 } 235 235 return declWithTypePostamble( decl, node ); 236 } 237 238 // InlineMemberDecl vanish after EnumAndPointerDecay pass so no necessary to implement NewToOld 239 const ast::DeclWithType * visit( const ast::InlineMemberDecl * node ) override final { 240 assert( false ); 241 (void) node; 242 return nullptr; 236 243 } 237 244 … … 1614 1621 { old->get_funcSpec().val } 1615 1622 ); 1616 decl->enumInLine = old->enumInLine;1617 1623 cache.emplace(old, decl); 1618 1624 assert(cache.find( old ) != cache.end()); … … 1859 1865 decl->uniqueId = old->uniqueId; 1860 1866 decl->storage = { old->storageClasses.val }; 1867 1868 this->node = decl; 1869 } 1870 1871 virtual void visit( const InlineMemberDecl * old ) override final { 1872 if ( inCache( old ) ) { 1873 return; 1874 } 1875 auto&& type = GET_ACCEPT_1(type, Type); 1876 auto&& attr = GET_ACCEPT_V(attributes, Attribute); 1877 1878 auto decl = new ast::InlineMemberDecl( 1879 old->location, 1880 old->name, 1881 type, 1882 { old->get_storageClasses().val }, 1883 { old->linkage.val }, 1884 std::move(attr), 1885 { old->get_funcSpec().val } 1886 ); 1887 cache.emplace(old, decl); 1888 assert(cache.find( old ) != cache.end()); 1889 decl->scopeLevel = old->scopeLevel; 1890 decl->mangleName = old->mangleName; 1891 decl->isDeleted = old->isDeleted; 1892 decl->asmName = GET_ACCEPT_1(asmName, Expr); 1893 decl->uniqueId = old->uniqueId; 1894 decl->extension = old->extension; 1861 1895 1862 1896 this->node = decl; -
src/AST/Decl.hpp
rb77f0e1 r63be3387 105 105 ptr<Init> init; 106 106 ptr<Expr> bitfieldWidth; 107 bool enumInLine = false; // enum inline is not a real object declaration.108 // It is a place holder for a set of enum value (ObjectDecl)109 bool importValue = false; // if the value copied from somewhere else110 107 111 108 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, … … 400 397 }; 401 398 399 /// Static Assertion `_Static_assert( ... , ... );` 402 400 class StaticAssertDecl : public Decl { 403 401 public: … … 411 409 private: 412 410 StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 411 MUTATE_FRIEND 412 }; 413 414 /// Inline Member Declaration `inline TypeName;` 415 class InlineMemberDecl final : public DeclWithType { 416 public: 417 ptr<Type> type; 418 419 InlineMemberDecl( const CodeLocation & loc, const std::string & name, const Type * type, 420 Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall, 421 std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} ) 422 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ) {} 423 424 const Type * get_type() const override { return type; } 425 void set_type( const Type * ty ) override { type = ty; } 426 427 const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); } 428 private: 429 InlineMemberDecl * clone() const override { return new InlineMemberDecl{ *this }; } 413 430 MUTATE_FRIEND 414 431 }; -
src/AST/Fwd.hpp
rb77f0e1 r63be3387 37 37 class DirectiveDecl; 38 38 class StaticAssertDecl; 39 class InlineMemberDecl; 39 40 40 41 class Stmt; -
src/AST/Pass.hpp
rb77f0e1 r63be3387 141 141 const ast::DirectiveDecl * visit( const ast::DirectiveDecl * ) override final; 142 142 const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * ) override final; 143 const ast::DeclWithType * visit( const ast::InlineMemberDecl * ) override final; 143 144 const ast::CompoundStmt * visit( const ast::CompoundStmt * ) override final; 144 145 const ast::Stmt * visit( const ast::ExprStmt * ) override final; -
src/AST/Pass.impl.hpp
rb77f0e1 r63be3387 617 617 maybe_accept( node, &FunctionDecl::returns ); 618 618 maybe_accept( node, &FunctionDecl::type ); 619 maybe_accept( node, &FunctionDecl::attributes ); 619 620 // First remember that we are now within a function. 620 621 ValueGuard< bool > oldInFunction( inFunction ); … … 625 626 atFunctionTop = true; 626 627 maybe_accept( node, &FunctionDecl::stmts ); 627 maybe_accept( node, &FunctionDecl::attributes );628 628 } 629 629 } … … 800 800 801 801 VISIT_END( StaticAssertDecl, node ); 802 } 803 804 //-------------------------------------------------------------------------- 805 // InlineMemberDecl 806 template< typename core_t > 807 const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineMemberDecl * node ) { 808 VISIT_START( node ); 809 810 if ( __visit_children() ) { 811 { 812 guard_symtab guard { *this }; 813 maybe_accept( node, &InlineMemberDecl::type ); 814 } 815 } 816 817 VISIT_END( DeclWithType, node ); 802 818 } 803 819 -
src/AST/Print.cpp
rb77f0e1 r63be3387 398 398 virtual const ast::Decl * visit( const ast::StructDecl * node ) override final { 399 399 print(node); 400 return node; 401 } 402 403 virtual const ast::DeclWithType * visit( const ast::InlineMemberDecl * node ) override final { 404 os << "inline "; 405 if ( ! node->name.empty() ) os << node->name; 406 400 407 return node; 401 408 } -
src/AST/Type.cpp
rb77f0e1 r63be3387 147 147 // --- TypeInstType 148 148 149 bool TypeInstType::operator==( const TypeInstType & other ) const { 150 return base == other.base 151 && formal_usage == other.formal_usage 152 && expr_id == other.expr_id; 153 } 154 149 155 TypeInstType::TypeInstType( const TypeDecl * b, 150 156 CV::Qualifiers q, std::vector<ptr<Attribute>> && as ) … … 157 163 158 164 bool TypeInstType::isComplete() const { return base->sized; } 165 166 std::string TypeInstType::TypeEnvKey::typeString() const { 167 return std::string("_") + std::to_string(formal_usage) 168 + "_" + std::to_string(expr_id) + "_" + base->name; 169 } 170 171 bool TypeInstType::TypeEnvKey::operator==( 172 const TypeInstType::TypeEnvKey & other ) const { 173 return base == other.base 174 && formal_usage == other.formal_usage 175 && expr_id == other.expr_id; 176 } 177 178 bool TypeInstType::TypeEnvKey::operator<( 179 const TypeInstType::TypeEnvKey & other ) const { 180 // TypeEnvKey ordering is an arbitrary total ordering. 181 // It doesn't mean anything but allows for a sorting. 182 if ( base < other.base ) { 183 return true; 184 } else if ( other.base < base ) { 185 return false; 186 } else if ( formal_usage < other.formal_usage ) { 187 return true; 188 } else if ( other.formal_usage < formal_usage ) { 189 return false; 190 } else { 191 return expr_id < other.expr_id; 192 } 193 } 159 194 160 195 // --- TupleType -
src/AST/Type.hpp
rb77f0e1 r63be3387 408 408 409 409 TypeEnvKey() = default; 410 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0): base(base), formal_usage(formal_usage), expr_id(expr_id) {} 411 TypeEnvKey(const TypeInstType & inst): base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {} 412 std::string typeString() const { return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + base->name; } 413 bool operator==(const TypeEnvKey & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; } 410 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0) 411 : base(base), formal_usage(formal_usage), expr_id(expr_id) {} 412 TypeEnvKey(const TypeInstType & inst) 413 : base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {} 414 std::string typeString() const; 415 bool operator==(const TypeEnvKey & other) const; 416 bool operator<(const TypeEnvKey & other) const; 414 417 }; 415 418 416 bool operator==(const TypeInstType & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; }419 bool operator==(const TypeInstType & other) const; 417 420 418 421 TypeInstType( -
src/AST/Visitor.hpp
rb77f0e1 r63be3387 33 33 virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * ) = 0; 34 34 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * ) = 0; 35 virtual const ast::DeclWithType * visit( const ast::InlineMemberDecl * ) = 0; 35 36 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * ) = 0; 36 37 virtual const ast::Stmt * visit( const ast::ExprStmt * ) = 0; -
src/Common/CodeLocationTools.cpp
rb77f0e1 r63be3387 111 111 macro(DirectiveDecl, DirectiveDecl) \ 112 112 macro(StaticAssertDecl, StaticAssertDecl) \ 113 macro(InlineMemberDecl, DeclWithType) \ 113 114 macro(CompoundStmt, CompoundStmt) \ 114 115 macro(ExprStmt, Stmt) \ -
src/Common/PassVisitor.h
rb77f0e1 r63be3387 81 81 virtual void visit( StaticAssertDecl * assertDecl ) override final; 82 82 virtual void visit( const StaticAssertDecl * assertDecl ) override final; 83 virtual void visit( InlineMemberDecl * valueDecl ) override final; 84 virtual void visit( const InlineMemberDecl * valueDecl ) override final; 83 85 84 86 virtual void visit( CompoundStmt * compoundStmt ) override final; … … 273 275 virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) override final; 274 276 virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final; 277 virtual DeclarationWithType * mutate( InlineMemberDecl * valueDecl ) override final; 275 278 276 279 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override final; -
src/Common/PassVisitor.impl.h
rb77f0e1 r63be3387 607 607 indexerAddId( &func ); 608 608 maybeMutate_impl( node->type, *this ); 609 maybeMutate_impl( node->attributes, *this ); 609 610 // First remember that we are now within a function. 610 611 ValueGuard< bool > oldInFunction( inFunction ); … … 615 616 atFunctionTop = true; 616 617 maybeMutate_impl( node->statements, *this ); 617 maybeMutate_impl( node->attributes, *this );618 618 } 619 619 } … … 1044 1044 1045 1045 MUTATE_END( StaticAssertDecl, node ); 1046 } 1047 1048 //-------------------------------------------------------------------------- 1049 // InlineMemberDecl 1050 template< typename pass_type > 1051 void PassVisitor< pass_type >::visit( InlineMemberDecl * node ) { 1052 VISIT_START( node ); 1053 1054 maybeAccept_impl( node->type, *this ); 1055 1056 VISIT_END( node ); 1057 } 1058 1059 template< typename pass_type > 1060 void PassVisitor< pass_type >::visit( const InlineMemberDecl * node ) { 1061 VISIT_START( node ); 1062 1063 maybeAccept_impl( node->type, *this ); 1064 1065 VISIT_END( node ); 1066 } 1067 1068 template< typename pass_type > 1069 DeclarationWithType * PassVisitor< pass_type >::mutate( InlineMemberDecl * node ) { 1070 MUTATE_START( node ); 1071 1072 maybeMutate_impl( node->type, *this ); 1073 1074 MUTATE_END( DeclarationWithType, node ); 1046 1075 } 1047 1076 -
src/Common/utility.h
rb77f0e1 r63be3387 452 452 453 453 // ----------------------------------------------------------------------------- 454 // Helper struct and function to support 455 // for ( val : group_iterate( container1, container2, ... ) ) {} 456 // syntax to have a for each that iterates multiple containers of the same length 457 // TODO: update to use variadic arguments 458 459 template< typename T1, typename T2 > 460 struct group_iterate_t { 461 private: 462 std::tuple<T1, T2> args; 454 // Helper struct and function to support: 455 // for ( auto val : group_iterate( container1, container2, ... ) ) { ... } 456 // This iteraters through multiple containers of the same size. 457 458 template<typename... Args> 459 class group_iterate_t { 460 using Iterables = std::tuple<Args...>; 461 Iterables iterables; 462 463 // Getting the iterator and value types this way preserves const. 464 template<size_t I> using Iter = decltype(std::get<I>(iterables).begin()); 465 template<size_t I> using Data = decltype(*std::get<I>(iterables).begin()); 466 template<typename> struct base_iterator; 467 468 // This inner template puts the sequence of `0, 1, ... sizeof...(Args)-1` 469 // into a pack. These are the indexes into the tuples, so unpacking can 470 // go over each element of the tuple. 471 // The std::integer_sequence is just used to build that sequence. 472 // A library reference will probably explain it better than I can. 473 template<std::size_t... Indices> 474 struct base_iterator<std::integer_sequence<std::size_t, Indices...>> { 475 using value_type = std::tuple< Data<Indices>... >; 476 std::tuple<Iter<Indices>...> iterators; 477 478 base_iterator( Iter<Indices>... is ) : iterators( is... ) {} 479 base_iterator operator++() { 480 return base_iterator( ++std::get<Indices>( iterators )... ); 481 } 482 bool operator!=( const base_iterator& other ) const { 483 return iterators != other.iterators; 484 } 485 value_type operator*() const { 486 return std::tie( *std::get<Indices>( iterators )... ); 487 } 488 489 static base_iterator make_begin( Iterables & data ) { 490 return base_iterator( std::get<Indices>( data ).begin()... ); 491 } 492 static base_iterator make_end( Iterables & data ) { 493 return base_iterator( std::get<Indices>( data ).end()... ); 494 } 495 }; 496 463 497 public: 464 group_iterate_t( bool skipBoundsCheck, const T1 & v1, const T2 & v2 ) : args(v1, v2) { 465 assertf(skipBoundsCheck || v1.size() == v2.size(), "group iteration requires containers of the same size: <%zd, %zd>.", v1.size(), v2.size()); 466 }; 467 468 typedef std::tuple<decltype(*std::get<0>(args).begin()), decltype(*std::get<1>(args).begin())> value_type; 469 typedef decltype(std::get<0>(args).begin()) T1Iter; 470 typedef decltype(std::get<1>(args).begin()) T2Iter; 471 472 struct iterator { 473 typedef std::tuple<T1Iter, T2Iter> IterTuple; 474 IterTuple it; 475 iterator( T1Iter i1, T2Iter i2 ) : it( i1, i2 ) {} 476 iterator operator++() { 477 return iterator( ++std::get<0>(it), ++std::get<1>(it) ); 478 } 479 bool operator!=( const iterator &other ) const { return it != other.it; } 480 value_type operator*() const { return std::tie( *std::get<0>(it), *std::get<1>(it) ); } 481 }; 482 483 iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); } 484 iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); } 485 }; 486 487 /// performs bounds check to ensure that all arguments are of the same length. 498 group_iterate_t( const Args &... args ) : iterables( args... ) {} 499 500 using iterator = base_iterator<decltype( 501 std::make_integer_sequence<std::size_t, sizeof...(Args)>())>; 502 503 iterator begin() { return iterator::make_begin( iterables ); } 504 iterator end() { return iterator::make_end( iterables ); } 505 }; 506 507 // Helpers for the bounds checks (the non-varatic part of group_iterate): 508 static inline void runGroupBoundsCheck(size_t size0, size_t size1) { 509 assertf( size0 == size1, 510 "group iteration requires containers of the same size: <%zd, %zd>.", 511 size0, size1 ); 512 } 513 514 static inline void runGroupBoundsCheck(size_t size0, size_t size1, size_t size2) { 515 assertf( size0 == size1 && size1 == size2, 516 "group iteration requires containers of the same size: <%zd, %zd, %zd>.", 517 size0, size1, size2 ); 518 } 519 520 /// Performs bounds check to ensure that all arguments are of the same length. 488 521 template< typename... Args > 489 522 group_iterate_t<Args...> group_iterate( Args &&... args ) { 490 return group_iterate_t<Args...>(false, std::forward<Args>( args )...); 491 } 492 493 /// does not perform a bounds check - requires user to ensure that iteration terminates when appropriate. 523 runGroupBoundsCheck( args.size()... ); 524 return group_iterate_t<Args...>( std::forward<Args>( args )... ); 525 } 526 527 /// Does not perform a bounds check - requires user to ensure that iteration terminates when appropriate. 494 528 template< typename... Args > 495 529 group_iterate_t<Args...> unsafe_group_iterate( Args &&... args ) { 496 return group_iterate_t<Args...>( true, std::forward<Args>( args )...);530 return group_iterate_t<Args...>( std::forward<Args>( args )... ); 497 531 } 498 532 -
src/GenPoly/Box.cc
rb77f0e1 r63be3387 58 58 namespace GenPoly { 59 59 namespace { 60 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );60 FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars ); 61 61 62 62 class BoxPass { … … 68 68 /// Adds layout-generation functions to polymorphic types. 69 69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting { 70 // Current level of nested functions:71 unsigned int functionNesting = 0;72 70 public: 73 void previsit( FunctionDecl *functionDecl );74 71 void previsit( StructDecl *structDecl ); 75 72 void previsit( UnionDecl *unionDecl ); … … 100 97 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 101 98 /// passes extra type parameters into a polymorphic function application 102 void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 99 /// Returns an iterator to the first argument after the added 100 /// arguments, which are added at the beginning. 101 std::list< Expression *>::iterator passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ); 103 102 /// wraps a function application with a new temporary for the out-parameter return value 104 Expression *addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg ); 105 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment 106 void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ); 107 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete). 108 /// If `doClone` is set to false, will not clone interior types 109 Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true ); 103 /// The new out-parameter is the new first parameter. 104 Expression *addRetParam( ApplicationExpr *appExpr, Type *retType ); 110 105 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 111 Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg ); 112 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 113 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 114 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 115 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 106 Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType ); 107 /// Converts a function call into a call of the adapter with the 108 /// original function as the first argument (all other arguments 109 /// are pushed back). May adjust return value. 110 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function ); 111 /// Modifies the `arg`, replacing it with a boxed expression 112 /// that matches `formal` under the current TyVarMap. 113 void boxParam( Expression *&arg, Type *formal, const TyVarMap &exprTyVars ); 114 /// Box an argument of `appExpr` for each parameter in `function` 115 /// starting at `arg`. 116 /// `exprTyVars` is the function's type variables. 117 void boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ); 118 /// Boxes each assertion and inserts them into `appExpr` at 119 /// `arg`. `exprTyVars` is the function's type variables. 120 void addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ); 116 121 /// Stores assignment operators from assertion list in local map of assignment operations 117 122 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 118 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 123 /// Creates an adapter definition from `adaptee` to `realType`, using 124 /// `mangleName` as the base name for the adapter. `tyVars` is the map of 125 /// type variables for the function type of the adapted expression. 126 FunctionDecl *makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 119 127 /// Replaces intrinsic operator functions with their arithmetic desugaring 120 128 Expression *handleIntrinsics( ApplicationExpr *appExpr ); … … 182 190 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 ); 183 191 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns 184 bool findGeneric( Type *ty );192 bool findGeneric( Type const *ty ); 185 193 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 186 194 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); … … 221 229 } // anonymous namespace 222 230 223 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging224 template< typename MutatorType >225 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {226 bool seenIntrinsic = false;227 SemanticErrorException errors;228 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {229 try {230 if ( *i ) {231 if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {232 seenIntrinsic = true;233 } else if ( seenIntrinsic ) {234 seenIntrinsic = false; // break on this line when debugging for end of prelude235 }236 237 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );238 assert( *i );239 } // if240 } catch( SemanticErrorException &e ) {241 errors.append( e );242 } // try243 } // for244 if ( ! errors.isEmpty() ) {245 throw errors;246 } // if247 }248 249 231 void box( std::list< Declaration *>& translationUnit ) { 250 232 PassVisitor<LayoutFunctionBuilder> layoutBuilder; … … 263 245 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 264 246 265 void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {266 visit_children = false;267 maybeAccept( functionDecl->get_functionType(), *visitor );268 ++functionNesting;269 maybeAccept( functionDecl->get_statements(), *visitor );270 --functionNesting;271 }272 273 247 /// Get a list of type declarations that will affect a layout function 274 248 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { 275 249 std::list< TypeDecl * > otypeDecls; 276 250 277 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl) {278 if ( (*decl)->isComplete() ) {279 otypeDecls.push_back( *decl );251 for ( TypeDecl * const decl : decls ) { 252 if ( decl->isComplete() ) { 253 otypeDecls.push_back( decl ); 280 254 } 281 255 } … … 288 262 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 289 263 290 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param) {291 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );264 for ( TypeDecl * const param : otypeParams ) { 265 TypeInstType paramType( Type::Qualifiers(), param->get_name(), param ); 292 266 std::string paramName = mangleType( ¶mType ); 293 267 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); … … 297 271 298 272 /// Builds a layout function declaration 299 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {273 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) { 300 274 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 301 275 // because each unit generates copies of the default routines for each aggregate. 302 276 FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ), 303 functionNesting > 0? Type::StorageClasses() : Type::StorageClasses( Type::Static ),277 isInFunction ? Type::StorageClasses() : Type::StorageClasses( Type::Static ), 304 278 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(), 305 279 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) ); 306 280 layoutDecl->fixUniqueId(); 307 281 return layoutDecl; 308 }309 310 /// Makes a unary operation311 Expression *makeOp( const std::string &name, Expression *arg ) {312 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );313 expr->args.push_back( arg );314 return expr;315 282 } 316 283 … … 380 347 381 348 // build function decl 382 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );349 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType ); 383 350 384 351 // calculate struct layout in function body … … 387 354 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) ); 388 355 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 389 unsigned long n_members = 0; 390 bool firstMember = true; 391 for ( Declaration* member : structDecl->get_members() ) { 392 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 356 for ( auto index_member : enumerate( structDecl->members ) ) { 357 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val ); 393 358 assert( dwt ); 394 359 Type *memberType = dwt->get_type(); 395 360 396 if ( firstMember ) { 397 firstMember = false; 398 } else { 361 if ( 0 < index_member.idx ) { 399 362 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment 400 363 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); … … 402 365 403 366 // place current size in the current offset index 404 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members) ) ),367 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx ) ) ), 405 368 derefVar( sizeParam ) ) ); 406 ++n_members;407 369 408 370 // add member size to current size … … 439 401 440 402 // build function decl 441 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );403 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType ); 442 404 443 405 // calculate union layout in function body 444 406 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 445 407 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 446 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member) {447 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );408 for ( Declaration * const member : unionDecl->members ) { 409 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 448 410 assert( dwt ); 449 411 Type *memberType = dwt->get_type(); … … 464 426 465 427 namespace { 466 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {428 std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) { 467 429 std::stringstream name; 468 430 … … 473 435 // to take those polymorphic types as pointers. Therefore, there can be two different functions 474 436 // with the same mangled name, so we need to further mangle the names. 475 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval) {476 if ( isPolyType( (*retval)->get_type(), tyVars ) ) {437 for ( DeclarationWithType const * const ret : function->returnVals ) { 438 if ( isPolyType( ret->get_type(), tyVars ) ) { 477 439 name << "P"; 478 440 } else { … … 481 443 } 482 444 name << "_"; 483 std::list< DeclarationWithType *> ¶mList = function->get_parameters(); 484 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 485 if ( isPolyType( (*arg)->get_type(), tyVars ) ) { 445 for ( DeclarationWithType const * const arg : function->parameters ) { 446 if ( isPolyType( arg->get_type(), tyVars ) ) { 486 447 name << "P"; 487 448 } else { … … 492 453 } 493 454 494 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {455 std::string mangleAdapterName( FunctionType const * function, const TyVarMap &tyVars ) { 495 456 return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars ); 496 457 } … … 499 460 return "_adapter" + mangleName; 500 461 } 462 463 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete). 464 /// If `doClone` is set to false, will not clone interior types 465 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true ); 501 466 502 467 Pass1::Pass1() : tempNamer( "_temp" ) {} … … 524 489 525 490 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 526 std::list< FunctionType *> functions;527 for ( Type ::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar) {528 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert) {529 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );491 std::list< FunctionType const *> functions; 492 for ( TypeDecl * const tyVar : functionType->forall ) { 493 for ( DeclarationWithType * const assert : tyVar->assertions ) { 494 findFunction( assert->get_type(), functions, scopeTyVars, needsAdapter ); 530 495 } // for 531 496 } // for 532 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg) {533 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );497 for ( DeclarationWithType * const arg : paramList ) { 498 findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter ); 534 499 } // for 535 500 536 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType) {537 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );501 for ( FunctionType const * const funType : functions ) { 502 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 538 503 if ( adapters.find( mangleName ) == adapters.end() ) { 539 504 std::string adapterName = makeAdapterName( mangleName ); 540 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), nullptr ) ) );505 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) ); 541 506 } // if 542 507 } // for … … 593 558 } 594 559 595 void Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 560 std::list< Expression *>::iterator Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) { 561 assert( env ); 562 std::list< Expression *>::iterator arg = appExpr->args.begin(); 596 563 // pass size/align for type variables 597 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm) {564 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 598 565 ResolvExpr::EqvClass eqvClass; 599 assert( env ); 600 if ( tyParm->second.isComplete ) { 601 Type *concrete = env->lookup( tyParm->first ); 602 if ( concrete ) { 603 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 604 arg++; 605 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 606 arg++; 607 } else { 608 // xxx - should this be an assertion? 609 SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ) ); 610 } // if 566 if ( tyParam.second.isComplete ) { 567 Type *concrete = env->lookup( tyParam.first ); 568 // If there is an unbound type variable, it should have detected already. 569 assertf( concrete, "Unbound type variable: %s in: %s", 570 toCString( tyParam.first ), toCString( *env ) ); 571 572 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 573 arg++; 574 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 575 arg++; 611 576 } // if 612 577 } // for 613 578 614 579 // add size/align for generic types to parameter list 615 if ( ! appExpr->get_function()->result ) return ;580 if ( ! appExpr->get_function()->result ) return arg; 616 581 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 617 582 assert( funcType ); 618 583 584 // These iterators don't advance in unison. 619 585 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 620 586 std::list< Expression* >::const_iterator fnArg = arg; … … 623 589 // a polymorphic return type may need to be added to the argument list 624 590 if ( polyRetType ) { 625 Type *concRetType = replaceWithConcrete( appExpr, polyRetType);591 Type *concRetType = replaceWithConcrete( polyRetType, env ); 626 592 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 627 593 ++fnArg; // skip the return parameter in the argument list … … 634 600 passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 635 601 } 602 return arg; 636 603 } 637 604 … … 642 609 } 643 610 644 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType , std::list< Expression *>::iterator &arg) {611 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) { 645 612 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 646 613 // using a comma expression. … … 662 629 paramExpr = new AddressExpr( paramExpr ); 663 630 } // if 664 arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call665 a rg++;631 // Add argument to function call. 632 appExpr->args.push_front( paramExpr ); 666 633 // Build a comma expression to call the function and emulate a normal return. 667 634 CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr ); … … 671 638 } 672 639 673 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) { 674 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 675 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 640 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment 641 void replaceParametersWithConcrete( std::list< Expression* >& params, TypeSubstitution const * env ) { 642 for ( Expression * const param : params ) { 643 TypeExpr *paramType = dynamic_cast< TypeExpr* >( param ); 676 644 assertf(paramType, "Aggregate parameters should be type expressions"); 677 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 678 } 679 } 680 681 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) { 645 paramType->set_type( replaceWithConcrete( paramType->get_type(), env, false ) ); 646 } 647 } 648 649 // See forward definition. 650 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone ) { 651 assert( env ); 682 652 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 683 653 Type *concrete = env->lookup( typeInst->get_name() ); … … 690 660 structType = structType->clone(); 691 661 } 692 replaceParametersWithConcrete( appExpr, structType->get_parameters());662 replaceParametersWithConcrete( structType->get_parameters(), env ); 693 663 return structType; 694 664 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { … … 696 666 unionType = unionType->clone(); 697 667 } 698 replaceParametersWithConcrete( appExpr, unionType->get_parameters());668 replaceParametersWithConcrete( unionType->get_parameters(), env ); 699 669 return unionType; 700 670 } … … 702 672 } 703 673 704 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) { 705 assert( env ); 706 Type *concrete = replaceWithConcrete( appExpr, dynType ); 674 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) { 675 Type *concrete = replaceWithConcrete( dynType, env ); 707 676 // add out-parameter for return value 708 return addRetParam( appExpr, concrete , arg);709 } 710 711 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function , std::list< Expression *>::iterator &arg, const TyVarMap &tyVars) {677 return addRetParam( appExpr, concrete ); 678 } 679 680 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 712 681 Expression *ret = appExpr; 713 682 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 714 if ( isDynRet( function, tyVars ) ) {715 ret = addRetParam( appExpr, function->returnVals.front()->get_type() , arg);683 if ( isDynRet( function, scopeTyVars ) ) { 684 ret = addRetParam( appExpr, function->returnVals.front()->get_type() ); 716 685 } // if 717 std::string mangleName = mangleAdapterName( function, tyVars );686 std::string mangleName = mangleAdapterName( function, scopeTyVars ); 718 687 std::string adapterName = makeAdapterName( mangleName ); 719 688 … … 724 693 725 694 return ret; 726 }727 728 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {729 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );730 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;731 732 if ( arg->get_lvalue() ) {733 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.734 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {735 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){736 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0]737 // return;738 // }739 // }740 arg = generalizedLvalue( new AddressExpr( arg ) );741 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {742 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.743 arg = new CastExpr( arg, param->clone() );744 }745 } else {746 // use type computed in unification to declare boxed variables747 Type * newType = param->clone();748 if ( env ) env->apply( newType );749 ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );750 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???751 stmtsToAddBefore.push_back( new DeclStmt( newObj ) );752 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?753 assign->get_args().push_back( new VariableExpr( newObj ) );754 assign->get_args().push_back( arg );755 stmtsToAddBefore.push_back( new ExprStmt( assign ) );756 arg = new AddressExpr( new VariableExpr( newObj ) );757 } // if758 695 } 759 696 … … 791 728 } 792 729 793 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 794 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg ) { 795 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 796 addCast( *arg, (*param)->get_type(), exprTyVars ); 797 boxParam( (*param)->get_type(), *arg, exprTyVars ); 730 void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) { 731 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 732 addCast( arg, param, exprTyVars ); 733 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 734 735 if ( arg->get_lvalue() ) { 736 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 737 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 738 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 739 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 740 // return; 741 // } 742 // } 743 arg = generalizedLvalue( new AddressExpr( arg ) ); 744 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 745 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 746 arg = new CastExpr( arg, param->clone() ); 747 } 748 } else { 749 // use type computed in unification to declare boxed variables 750 Type * newType = param->clone(); 751 if ( env ) env->apply( newType ); 752 ObjectDecl *newObj = makeTemporary( newType ); 753 // TODO: is this right??? (Why wouldn't it be?) 754 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); 755 // TODO: why doesn't this just use initialization syntax? 756 // (Possibly to ensure code is run at the right time.) 757 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 758 assign->get_args().push_back( new VariableExpr( newObj ) ); 759 assign->get_args().push_back( arg ); 760 stmtsToAddBefore.push_back( new ExprStmt( assign ) ); 761 arg = new AddressExpr( new VariableExpr( newObj ) ); 762 } // if 763 } 764 765 void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) { 766 for ( DeclarationWithType * param : function->parameters ) { 767 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 768 boxParam( *arg, param->get_type(), exprTyVars ); 769 ++arg; 798 770 } // for 799 771 } 800 772 801 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {773 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 802 774 std::list< Expression *>::iterator cur = arg; 803 for ( Type ::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar) {804 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert) {805 InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() );806 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );775 for ( TypeDecl * const tyVar : functionType->forall ) { 776 for ( DeclarationWithType * const assert : tyVar->assertions ) { 777 InferredParams::const_iterator inferParam = appExpr->inferParams.find( assert->get_uniqueId() ); 778 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() ); 807 779 Expression *newExpr = inferParam->second.expr->clone(); 808 addCast( newExpr, (*assert)->get_type(), tyVars ); 809 boxParam( (*assert)->get_type(), newExpr, tyVars ); 780 boxParam( newExpr, assert->get_type(), tyVars ); 810 781 appExpr->get_args().insert( cur, newExpr ); 811 782 } // for … … 824 795 } 825 796 826 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {797 FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars ) { 827 798 // actually make the adapter type 828 799 FunctionType *adapter = adaptee->clone(); … … 834 805 } 835 806 836 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) { 807 Expression *makeAdapterArg( 808 DeclarationWithType *param, 809 DeclarationWithType const *arg, 810 DeclarationWithType const *realParam, 811 const TyVarMap &tyVars ) { 837 812 assert( param ); 838 813 assert( arg ); 839 if ( isPolyType( realParam->get_type(), tyVars ) ) { 840 if ( ! isPolyType( arg->get_type() ) ) { 841 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 842 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 843 deref->result = arg->get_type()->clone(); 844 return deref; 845 } // if 814 if ( isPolyType( realParam->get_type(), tyVars ) 815 && ! isPolyType( arg->get_type() ) ) { 816 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 817 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 818 deref->result = arg->get_type()->clone(); 819 return deref; 846 820 } // if 847 821 return new VariableExpr( param ); 848 822 } 849 823 850 void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) { 824 void addAdapterParams( 825 ApplicationExpr *adapteeApp, 826 std::list< DeclarationWithType *>::const_iterator arg, 827 std::list< DeclarationWithType *>::const_iterator param, 828 std::list< DeclarationWithType *>::const_iterator paramEnd, 829 std::list< DeclarationWithType *>::const_iterator realParam, 830 const TyVarMap &tyVars ) { 851 831 UniqueName paramNamer( "_p" ); 852 832 for ( ; param != paramEnd; ++param, ++arg, ++realParam ) { … … 859 839 } 860 840 861 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {841 FunctionDecl *Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 862 842 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 863 843 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); … … 876 856 Statement *bodyStmt; 877 857 878 Type::ForallList::iterator tyArg = realType->get_forall().begin(); 879 Type::ForallList::iterator tyParam = adapterType->get_forall().begin(); 880 Type::ForallList::iterator realTyParam = adaptee->get_forall().begin(); 881 for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) { 882 assert( tyArg != realType->get_forall().end() ); 883 std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin(); 884 std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin(); 885 std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin(); 886 for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) { 887 assert( assertArg != (*tyArg)->get_assertions().end() ); 888 adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) ); 858 for ( auto tys : group_iterate( realType->forall, adapterType->forall, adaptee->forall ) ) { 859 TypeDecl * tyArg = std::get<0>( tys ); 860 TypeDecl * tyParam = std::get<1>( tys ); 861 TypeDecl * realTyParam = std::get<2>( tys ); 862 for ( auto asserts : group_iterate( tyArg->assertions, tyParam->assertions, realTyParam->assertions ) ) { 863 DeclarationWithType * assertArg = std::get<0>( asserts ); 864 DeclarationWithType * assertParam = std::get<1>( asserts ); 865 DeclarationWithType * realAssertParam = std::get<2>( asserts ); 866 adapteeApp->args.push_back( makeAdapterArg( assertParam, assertArg, realAssertParam, tyVars ) ); 889 867 } // for 890 868 } // for 891 869 892 std::list< DeclarationWithType *>:: iterator arg = realType->get_parameters().begin();893 std::list< DeclarationWithType *>:: iterator param = adapterType->get_parameters().begin();894 std::list< DeclarationWithType *>:: iterator realParam = adaptee->get_parameters().begin();870 std::list< DeclarationWithType *>::const_iterator arg = realType->parameters.begin(); 871 std::list< DeclarationWithType *>::const_iterator param = adapterType->parameters.begin(); 872 std::list< DeclarationWithType *>::const_iterator realParam = adaptee->parameters.begin(); 895 873 param++; // skip adaptee parameter in the adapter type 896 874 if ( realType->get_returnVals().empty() ) { … … 898 876 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 899 877 bodyStmt = new ExprStmt( adapteeApp ); 900 } else if ( isDynType( adaptee-> get_returnVals().front()->get_type(), tyVars ) ) {878 } else if ( isDynType( adaptee->returnVals.front()->get_type(), tyVars ) ) { 901 879 // return type T 902 880 if ( (*param)->get_name() == "" ) { … … 923 901 void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) { 924 902 // collect a list of function types passed as parameters or implicit parameters (assertions) 925 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 926 std::list< FunctionType *> functions; 927 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 928 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 929 findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter ); 903 std::list<FunctionType const *> functions; 904 for ( TypeDecl * const tyVar : functionType->get_forall() ) { 905 for ( DeclarationWithType * const assert : tyVar->get_assertions() ) { 906 findFunction( assert->get_type(), functions, exprTyVars, needsAdapter ); 930 907 } // for 931 908 } // for 932 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg) {933 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );909 for ( DeclarationWithType * const arg : functionType->get_parameters() ) { 910 findFunction( arg->get_type(), functions, exprTyVars, needsAdapter ); 934 911 } // for 935 912 … … 938 915 std::set< std::string > adaptersDone; 939 916 940 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType) {941 FunctionType *originalFunction = (*funType)->clone();942 FunctionType *realFunction = (*funType)->clone();917 for ( FunctionType const * const funType : functions ) { 918 FunctionType *originalFunction = funType->clone(); 919 FunctionType *realFunction = funType->clone(); 943 920 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 944 921 … … 958 935 if ( adapter == adapters.end() ) { 959 936 // adapter has not been created yet in the current scope, so define it 960 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );937 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars ); 961 938 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 962 939 adapter = answer.first; … … 972 949 973 950 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 974 NameExpr *opExpr; 975 if ( isIncr ) { 976 opExpr = new NameExpr( "?+=?" ); 977 } else { 978 opExpr = new NameExpr( "?-=?" ); 979 } // if 951 NameExpr *opExpr = new NameExpr( ( isIncr ) ? "?+=?" : "?-=?" ); 980 952 UntypedExpr *addAssign = new UntypedExpr( opExpr ); 981 953 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { … … 1120 1092 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) { 1121 1093 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1122 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i) {1123 // std::cerr << i->first << " ";1094 // for ( auto tyVar : scopeTyVars ) { 1095 // std::cerr << tyVar.first << " "; 1124 1096 // } 1125 1097 // std::cerr << "\n"; … … 1134 1106 1135 1107 Expression *ret = appExpr; 1136 1137 std::list< Expression *>::iterator arg = appExpr->get_args().begin();1138 1108 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1139 1109 … … 1156 1126 // std::cerr << "dynRetType: " << dynRetType << std::endl; 1157 1127 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1158 ret = addDynRetParam( appExpr, concRetType , arg); // xxx - used to use dynRetType instead of concRetType1128 ret = addDynRetParam( appExpr, concRetType ); // xxx - used to use dynRetType instead of concRetType 1159 1129 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? 1160 1130 // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed. … … 1164 1134 // std::cerr << *env << std::endl; 1165 1135 // change the application so it calls the adapter rather than the passed function 1166 ret = applyAdapter( appExpr, function , arg, scopeTyVars);1136 ret = applyAdapter( appExpr, function ); 1167 1137 } // if 1168 arg = appExpr->get_args().begin(); 1169 1170 Type *concRetType = replaceWithConcrete( appExpr, dynRetType );1171 passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)1172 addInferredParams( appExpr, function, arg, exprTyVars );1173 1174 arg = paramBegin;1175 1176 boxParams( appExpr, function, arg, exprTyVars ); 1138 1139 Type *concRetType = replaceWithConcrete( dynRetType, env ); 1140 std::list< Expression *>::iterator arg = 1141 passTypeVars( appExpr, concRetType, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's) 1142 addInferredParams( appExpr, arg, function, exprTyVars ); 1143 1144 // This needs to point at the original first argument. 1145 boxParams( appExpr, paramBegin, function, exprTyVars ); 1146 1177 1147 passAdapters( appExpr, function, exprTyVars ); 1178 1148 … … 1180 1150 } 1181 1151 1182 Expression * Pass1::postmutate( UntypedExpr *expr) {1152 bool isPolyDeref( UntypedExpr const * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) { 1183 1153 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1184 if ( NameExpr *name = dynamic_cast< NameExpr*>( expr->function ) ) {1154 if ( auto name = dynamic_cast<NameExpr const *>( expr->function ) ) { 1185 1155 if ( name->name == "*?" ) { 1186 Expression *ret = expr->args.front(); 1187 expr->args.clear(); 1188 delete expr; 1189 return ret; 1156 return true; 1190 1157 } // if 1191 1158 } // if 1192 1159 } // if 1160 return false; 1161 } 1162 1163 Expression * Pass1::postmutate( UntypedExpr *expr ) { 1164 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1165 Expression *ret = expr->args.front(); 1166 expr->args.clear(); 1167 delete expr; 1168 return ret; 1169 } 1193 1170 return expr; 1194 1171 } … … 1200 1177 bool needs = false; 1201 1178 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) { 1202 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1203 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1204 if ( name->name == "*?" ) { 1205 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1206 assert( appExpr->function->result ); 1207 FunctionType *function = getFunctionType( appExpr->function->result ); 1208 assert( function ); 1209 needs = needsAdapter( function, scopeTyVars ); 1210 } // if 1211 } // if 1179 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1180 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1181 assert( appExpr->function->result ); 1182 FunctionType *function = getFunctionType( appExpr->function->result ); 1183 assert( function ); 1184 needs = needsAdapter( function, scopeTyVars ); 1212 1185 } // if 1213 1186 } // if … … 1260 1233 void Pass2::addAdapters( FunctionType *functionType ) { 1261 1234 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 1262 std::list< FunctionType *> functions;1263 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg) {1264 Type *orig = (*arg)->get_type();1235 std::list< FunctionType const *> functions; 1236 for ( DeclarationWithType * const arg : functionType->parameters ) { 1237 Type *orig = arg->get_type(); 1265 1238 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter ); 1266 (*arg)->set_type( orig );1239 arg->set_type( orig ); 1267 1240 } 1268 1241 std::set< std::string > adaptersDone; 1269 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType) {1270 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );1242 for ( FunctionType const * const funType : functions ) { 1243 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 1271 1244 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 1272 1245 std::string adapterName = makeAdapterName( mangleName ); 1273 1246 // adapter may not be used in body, pass along with unused attribute. 1274 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );1247 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1275 1248 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1276 1249 } … … 1349 1322 ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0, 1350 1323 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1351 for ( Type ::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm) {1324 for ( TypeDecl * const tyParam : funcType->get_forall() ) { 1352 1325 ObjectDecl *sizeParm, *alignParm; 1353 1326 // add all size and alignment parameters to parameter list 1354 if ( (*tyParm)->isComplete() ) {1355 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );1327 if ( tyParam->isComplete() ) { 1328 TypeInstType parmType( Type::Qualifiers(), tyParam->get_name(), tyParam ); 1356 1329 std::string parmName = mangleType( &parmType ); 1357 1330 … … 1367 1340 } 1368 1341 // move all assertions into parameter list 1369 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert) {1342 for ( DeclarationWithType * const assert : tyParam->get_assertions() ) { 1370 1343 // assertion parameters may not be used in body, pass along with unused attribute. 1371 (*assert)->get_attributes().push_back( new Attribute( "unused" ) );1372 inferredParams.push_back( *assert );1373 } 1374 (*tyParm)->get_assertions().clear();1344 assert->get_attributes().push_back( new Attribute( "unused" ) ); 1345 inferredParams.push_back( assert ); 1346 } 1347 tyParam->get_assertions().clear(); 1375 1348 } 1376 1349 1377 1350 // add size/align for generic parameter types to parameter list 1378 1351 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1379 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm) {1380 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );1352 for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) { 1353 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars ); 1381 1354 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1382 1355 std::string typeName = mangleType( polyType ); … … 1482 1455 1483 1456 if(!expect_func_type) { 1484 GuardAction( [this]() {1485 knownLayouts.endScope();1486 knownOffsets.endScope();1487 });1488 1457 // If this is the first function type we see 1489 1458 // Then it's the type of the declaration and we care about it 1490 knownLayouts.beginScope(); 1491 knownOffsets.beginScope(); 1459 GuardScope( *this ); 1492 1460 } 1493 1461 … … 1497 1465 1498 1466 // make sure that any type information passed into the function is accounted for 1499 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm) {1467 for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) { 1500 1468 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1501 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );1469 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars ); 1502 1470 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1503 1471 knownLayouts.insert( mangleType( polyType ) ); … … 1507 1475 1508 1476 /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T] 1509 Type * polyToMonoType( Type * declType ) {1477 Type * polyToMonoType( Type const * declType ) { 1510 1478 Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char); 1511 1479 Expression * size = new NameExpr( sizeofName( mangleType(declType) ) ); … … 1572 1540 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present 1573 1541 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) { 1574 long i = 0; 1575 for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) { 1576 if ( memberDecl->get_name() != (*decl)->get_name() ) 1542 for ( auto pair : enumerate( baseDecls ) ) { 1543 Declaration * decl = pair.val; 1544 size_t i = pair.idx; 1545 if ( memberDecl->get_name() != decl->get_name() ) 1577 1546 continue; 1578 1547 1579 1548 if ( memberDecl->get_name().empty() ) { 1580 1549 // plan-9 field: match on unique_id 1581 if ( memberDecl->get_uniqueId() == (*decl)->get_uniqueId() )1550 if ( memberDecl->get_uniqueId() == decl->get_uniqueId() ) 1582 1551 return i; 1583 1552 else … … 1585 1554 } 1586 1555 1587 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( *decl );1556 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( decl ); 1588 1557 1589 1558 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() ) { … … 1603 1572 1604 1573 /// Returns an index expression into the offset array for a type 1605 Expression *makeOffsetIndex( Type *objectType, long i ) {1574 Expression *makeOffsetIndex( Type const *objectType, long i ) { 1606 1575 ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) ); 1607 1576 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); … … 1696 1665 1697 1666 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 1698 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param) {1699 if ( findGeneric( *param ) ) {1667 for ( Type * const param : otypeParams ) { 1668 if ( findGeneric( param ) ) { 1700 1669 // push size/align vars for a generic parameter back 1701 std::string paramName = mangleType( *param );1670 std::string paramName = mangleType( param ); 1702 1671 layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) ); 1703 1672 layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) ); 1704 1673 } else { 1705 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );1706 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );1674 layoutCall->get_args().push_back( new SizeofExpr( param->clone() ) ); 1675 layoutCall->get_args().push_back( new AlignofExpr( param->clone() ) ); 1707 1676 } 1708 1677 } … … 1710 1679 1711 1680 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 1712 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* >&typeParams, std::list< Type* > &out ) {1681 bool findGenericParams( std::list< TypeDecl* > const &baseParams, std::list< Expression* > const &typeParams, std::list< Type* > &out ) { 1713 1682 bool hasDynamicLayout = false; 1714 1683 1715 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();1716 std::list< Expression* >::const_iterator typeParam = typeParams.begin();1717 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) {1684 for ( auto paramPair : group_iterate( baseParams, typeParams ) ) { 1685 TypeDecl * baseParam = std::get<0>( paramPair ); 1686 Expression * typeParam = std::get<1>( paramPair ); 1718 1687 // skip non-otype parameters 1719 if ( ! (*baseParam)->isComplete() ) continue;1720 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );1688 if ( ! baseParam->isComplete() ) continue; 1689 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( typeParam ); 1721 1690 assert( typeExpr && "all otype parameters should be type expressions" ); 1722 1691 … … 1725 1694 if ( isPolyType( type ) ) hasDynamicLayout = true; 1726 1695 } 1727 assert( baseParam == baseParams.end() && typeParam == typeParams.end() );1728 1696 1729 1697 return hasDynamicLayout; 1730 1698 } 1731 1699 1732 bool PolyGenericCalculator::findGeneric( Type *ty ) {1700 bool PolyGenericCalculator::findGeneric( Type const *ty ) { 1733 1701 ty = replaceTypeInst( ty, env ); 1734 1702 1735 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {1703 if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) { 1736 1704 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 1737 1705 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set … … 1739 1707 } 1740 1708 return false; 1741 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {1709 } else if ( auto structTy = dynamic_cast< StructInstType const * >( ty ) ) { 1742 1710 // check if this type already has a layout generated for it 1743 1711 std::string typeName = mangleType( ty ); … … 1746 1714 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1747 1715 std::list< Type* > otypeParams; 1748 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy-> get_parameters(), otypeParams ) ) return false;1716 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->parameters, otypeParams ) ) return false; 1749 1717 1750 1718 // insert local variables for layout and generate call to layout function … … 1776 1744 1777 1745 return true; 1778 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {1746 } else if ( auto unionTy = dynamic_cast< UnionInstType const * >( ty ) ) { 1779 1747 // check if this type already has a layout generated for it 1780 1748 std::string typeName = mangleType( ty ); … … 1783 1751 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1784 1752 std::list< Type* > otypeParams; 1785 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy-> get_parameters(), otypeParams ) ) return false;1753 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->parameters, otypeParams ) ) return false; 1786 1754 1787 1755 // insert local variables for layout and generate call to layout function … … 1881 1849 // build initializer list for offset array 1882 1850 std::list< Initializer* > inits; 1883 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 1884 if ( DeclarationWithType *memberDecl = dynamic_cast< DeclarationWithType* >( *member ) ) { 1885 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 1886 } else { 1887 assertf( false, "Requesting offset of Non-DWT member: %s", toString( *member ).c_str() ); 1888 } 1851 for ( Declaration * const member : baseMembers ) { 1852 DeclarationWithType *memberDecl = dynamic_cast< DeclarationWithType* >( member ); 1853 assertf( memberDecl, "Requesting offset of Non-DWT member: %s", toString( member ).c_str() ); 1854 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 1889 1855 } 1890 1856 … … 1965 1931 // compile-command: "make install" // 1966 1932 // End: // 1933 -
src/GenPoly/FindFunction.cc
rb77f0e1 r63be3387 29 29 class FindFunction : public WithGuards, public WithVisitorRef<FindFunction>, public WithShortCircuiting { 30 30 public: 31 FindFunction( std::list< FunctionType * > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate );31 FindFunction( std::list< FunctionType const* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ); 32 32 33 33 void premutate( FunctionType * functionType ); … … 37 37 void handleForall( const Type::ForallList &forall ); 38 38 39 std::list< FunctionType * > &functions;39 std::list< FunctionType const * > & functions; 40 40 TyVarMap tyVars; 41 41 bool replaceMode; … … 43 43 }; 44 44 45 void findFunction( Type *type, std::list< FunctionType * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {45 void findFunction( Type *type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 46 46 PassVisitor<FindFunction> finder( functions, tyVars, false, predicate ); 47 47 type->acceptMutator( finder ); 48 48 } 49 49 50 void findAndReplaceFunction( Type *&type, std::list< FunctionType * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {50 void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 51 51 PassVisitor<FindFunction> finder( functions, tyVars, true, predicate ); 52 52 type = type->acceptMutator( finder ); 53 53 } 54 54 55 FindFunction::FindFunction( std::list< FunctionType * > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate )55 FindFunction::FindFunction( std::list< FunctionType const * > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ) 56 56 : functions( functions ), tyVars( tyVars ), replaceMode( replaceMode ), predicate( predicate ) { 57 57 } -
src/GenPoly/FindFunction.h
rb77f0e1 r63be3387 27 27 28 28 /// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions` 29 void findFunction( Type *type, std::list< FunctionType * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );29 void findFunction( Type *type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 30 30 /// like `findFunction`, but also replaces the function type with void ()(void) 31 void findAndReplaceFunction( Type *&type, std::list< FunctionType * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );31 void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 32 32 } // namespace GenPoly 33 33 -
src/GenPoly/GenPoly.cc
rb77f0e1 r63be3387 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 15:25:00 202213 // Update Count : 1 612 // Last Modified On : Mon Oct 24 15:19:00 2022 13 // Update Count : 17 14 14 // 15 15 … … 118 118 } 119 119 120 const Type* replaceTypeInst( const Type* type, const TypeSubstitution* env ) { 121 if ( ! env ) return type; 122 if ( auto typeInst = dynamic_cast< const TypeInstType* >( type ) ) { 123 Type *newType = env->lookup( typeInst->get_name() ); 124 if ( newType ) return newType; 125 } 126 return type; 127 } 128 120 129 const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) { 121 130 if (!env) return type; 122 if ( auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {131 if ( auto typeInst = dynamic_cast<const ast::TypeInstType*>(type) ) { 123 132 auto newType = env->lookup(typeInst); 124 133 if (newType) return newType; … … 194 203 195 204 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 196 if ( typeVars.find( inst->typeString()) != typeVars.end() ) return type;205 if ( typeVars.find( *inst ) != typeVars.end() ) return type; 197 206 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 198 207 return isPolyType( array->base, subst ); … … 227 236 228 237 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) { 229 auto var = typeVars.find( inst->name);238 auto var = typeVars.find( *inst ); 230 239 if ( var != typeVars.end() && var->second.isComplete ) { 231 240 return inst; 232 241 } 233 242 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) { … … 784 793 785 794 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 786 typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) );795 typeVars.insert( *type, ast::TypeDecl::Data( type->base ) ); 787 796 } 788 797 … … 816 825 } 817 826 818 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ) {819 for ( auto const & pair : typeVars ) {820 os << pair.first << " (" << pair.second << ") ";821 } // for822 os << std::endl;823 }824 825 827 } // namespace GenPoly 826 828 -
src/GenPoly/GenPoly.h
rb77f0e1 r63be3387 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 15:06:00 202213 // Update Count : 912 // Last Modified On : Mon Oct 24 15:18:00 2022 13 // Update Count : 11 14 14 // 15 15 … … 22 22 #include "AST/Decl.hpp" // for TypeDecl::Data 23 23 #include "AST/Fwd.hpp" // for ApplicationExpr, BaseInstType, Func... 24 #include "AST/Type.hpp" // for TypeInstType::TypeEnvKey 24 25 #include "SymTab/Mangler.h" // for Mangler 25 26 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... … … 28 29 namespace GenPoly { 29 30 30 // TODO Via some tricks this works for ast::TypeDecl::Data as well.31 31 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 32 using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >;32 using TypeVarMap = ErasableScopedMap< ast::TypeInstType::TypeEnvKey, ast::TypeDecl::Data >; 33 33 34 34 /// Replaces a TypeInstType by its referrent in the environment, if applicable 35 35 Type* replaceTypeInst( Type* type, const TypeSubstitution* env ); 36 const Type* replaceTypeInst( const Type* type, const TypeSubstitution* env ); 37 const ast::Type * replaceTypeInst( const ast::Type *, const ast::TypeSubstitution * ); 36 38 37 39 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided … … 53 55 /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters 54 56 ReferenceToType *isDynRet( FunctionType *function ); 57 const ast::BaseInstType *isDynRet( const ast::FunctionType * func ); 55 58 56 59 /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type … … 112 115 /// Prints type variable map 113 116 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 114 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars );115 117 116 118 /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType(). 117 inline std::string mangleType( Type *ty ) { return SymTab::Mangler::mangleType( ty ); }119 inline std::string mangleType( const Type *ty ) { return SymTab::Mangler::mangleType( ty ); } 118 120 119 121 /// Gets the name of the sizeof parameter for the type, given its mangled name … … 128 130 /// Gets the name of the layout function for a given aggregate type, given its declaration 129 131 inline std::string layoutofName( AggregateDecl *decl ) { return std::string( "_layoutof_" ) + decl->get_name(); } 132 inline std::string layoutofName( ast::AggregateDecl const * decl ) { 133 return std::string( "_layoutof_" ) + decl->name; 134 } 130 135 131 136 } // namespace GenPoly -
src/GenPoly/InstantiateGenericNew.cpp
rb77f0e1 r63be3387 10 10 // Created On : Tue Aug 16 10:51:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Sep 13 16:03:00 202213 // Update Count : 012 // Last Modified On : Mon Oct 31 16:48:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 378 378 // Ptr(int) p; 379 379 // int i; 380 // The original expression: 380 381 // p.x = &i; 381 // becomes 382 // int *& _dtype_static_member_0 = (int **)&p.x; 383 // _dtype_static_member_0 = &i; 382 // Becomes the expression/declaration: 383 // int *& _dtype_static_member_0; 384 // (_dtype_static_member_0 = (int**)&p.x, 385 // _dtype_static_member_0) = &i; 386 387 // The declaration is simple: 384 388 static UniqueName tmpNamer( "_dtype_static_member_" ); 385 ast::Expr * init = new ast::CastExpr( location,386 new ast::AddressExpr( location, memberExpr ),387 new ast::PointerType( ast::deepCopy( concType ) ),388 ast::ExplicitCast389 );390 389 ast::ObjectDecl * tmp = new ast::ObjectDecl( location, 391 390 tmpNamer.newName(), 392 391 new ast::ReferenceType( concType ), 393 n ew ast::SingleInit( location, init ),392 nullptr, 394 393 ast::Storage::Classes(), 395 394 ast::Linkage::C 396 395 ); 397 396 stmtsToAddBefore.push_back( new ast::DeclStmt( location, tmp ) ); 398 return new ast::VariableExpr( location, tmp ); 397 398 // The expression is more complex, uses references and reference / 399 // pointer parity. But breaking it up risks reordering. 400 return new ast::CommaExpr( location, 401 ast::UntypedExpr::createAssign( location, 402 new ast::VariableExpr( location, tmp ), 403 new ast::CastExpr( location, 404 new ast::AddressExpr( location, memberExpr ), 405 new ast::PointerType( ast::deepCopy( concType ) ), 406 ast::ExplicitCast 407 ) 408 ), 409 new ast::VariableExpr( location, tmp ) 410 ); 399 411 } else { 400 412 // Here, it can simply add a cast to actual types. … … 476 488 }; 477 489 478 // I think this and the UnionInstType can be made into a template function.479 490 ast::Type const * GenericInstantiator::postvisit( 480 491 ast::StructInstType const * inst ) { -
src/GenPoly/ScrubTyVars.cc
rb77f0e1 r63be3387 20 20 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 21 21 #include "ScrubTyVars.h" 22 #include "SymTab/Mangler.h" // for mangle , typeMode22 #include "SymTab/Mangler.h" // for mangleType 23 23 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Typ... 24 24 #include "SynTree/Expression.h" // for Expression (ptr only), NameExpr … … 195 195 } 196 196 197 auto typeVar = typeVars->find( type->name );197 auto typeVar = typeVars->find( *type ); 198 198 if ( typeVar == typeVars->end() ) { 199 199 return type; … … 227 227 if ( dynType ) { 228 228 return new ast::NameExpr( expr->location, 229 sizeofName( Mangle::mangle ( dynType, Mangle::typeMode()) ) );229 sizeofName( Mangle::mangleType( dynType ) ) ); 230 230 } else { 231 231 return expr; … … 237 237 if ( dynType ) { 238 238 return new ast::NameExpr( expr->location, 239 alignofName( Mangle::mangle ( dynType, Mangle::typeMode()) ) );239 alignofName( Mangle::mangleType( dynType ) ) ); 240 240 } else { 241 241 return expr; -
src/Parser/DeclarationNode.cc
rb77f0e1 r63be3387 27 27 #include "SynTree/LinkageSpec.h" // for Spec, linkageName, Cforall 28 28 #include "SynTree/Attribute.h" // for Attribute 29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, Declaration29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration 30 30 #include "SynTree/Expression.h" // for Expression, ConstantExpr 31 31 #include "SynTree/Statement.h" // for AsmStmt … … 1165 1165 SemanticError( this, "invalid function specifier for " ); 1166 1166 } // if 1167 if ( enumInLine ) { 1168 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1169 } // if 1167 1170 assertf( name, "ObjectDecl must a have name\n" ); 1168 1171 return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension ); -
src/Parser/ExpressionNode.cc
rb77f0e1 r63be3387 519 519 } 520 520 } 521 auto ret = new QualifiedNameExpr( newDecl, name->name ); 522 if ( auto e = dynamic_cast<EnumDecl*>(newDecl) ) { 523 auto enumInst = new EnumInstType( Type::Qualifiers(), e ); 524 auto obj = new ObjectDecl( name->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, enumInst, nullptr ); 525 } 526 return ret; 521 return new QualifiedNameExpr( newDecl, name->name ); 527 522 } 528 523 -
src/Parser/ParseNode.h
rb77f0e1 r63be3387 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Oct 18 16:22:15202213 // Update Count : 93 712 // Last Modified On : Wed Nov 2 21:27:07 2022 13 // Update Count : 939 14 14 // 15 15 … … 168 168 Ctor, Dtor, 169 169 }; // OperKinds 170 171 enum class EnumHiding { Visible, Hide }; 170 172 171 173 struct LabelNode { -
src/Parser/TypeData.cc
rb77f0e1 r63be3387 925 925 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 926 926 if ( cur->enumInLine ) { 927 // Tell the compiler this is a inline value placeholder 928 ObjectDecl * member = dynamic_cast< ObjectDecl* >(* members); 929 member->enumInLine = true; 930 } 931 if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) { 927 // Do Nothing 928 } else if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) { 932 929 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); 933 930 } else if ( cur->has_enumeratorValue() ) { -
src/Parser/parser.yy
rb77f0e1 r63be3387 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Oct 14 14:04:43202213 // Update Count : 5 75112 // Last Modified On : Wed Nov 2 21:31:21 2022 13 // Update Count : 5810 14 14 // 15 15 … … 278 278 279 279 // Types declaration for productions 280 280 281 %union { 281 282 Token tok; … … 290 291 CondCtl * ifctl; 291 292 ForCtrl * fctl; 292 enumOperKinds compop;293 OperKinds compop; 293 294 LabelNode * label; 294 295 InitializerNode * in; … … 296 297 std::string * str; 297 298 bool flag; 299 EnumHiding hide; 298 300 CatchStmt::Kind catch_kind; 299 301 GenericExpr * genexpr; … … 364 366 %type<constant> string_literal 365 367 %type<str> string_literal_list 368 369 %type<hide> hide_opt visible_hide_opt 366 370 367 371 // expressions … … 2553 2557 | ENUM attribute_list_opt identifier 2554 2558 { typedefTable.makeTypedef( *$3 ); } 2555 '{' enumerator_list comma_opt '}'2556 { $$ = DeclarationNode::newEnum( $3, $6, true, false )->addQualifiers( $2 ); }2559 hide_opt '{' enumerator_list comma_opt '}' 2560 { $$ = DeclarationNode::newEnum( $3, $7, true, false )->addQualifiers( $2 ); } 2557 2561 | ENUM attribute_list_opt typedef_name // unqualified type name 2558 '{' enumerator_list comma_opt '}'2559 { $$ = DeclarationNode::newEnum( $3->name, $ 5, true, false )->addQualifiers( $2 ); }2562 hide_opt '{' enumerator_list comma_opt '}' 2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false )->addQualifiers( $2 ); } 2560 2564 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2561 2565 { … … 2574 2578 typedefTable.makeTypedef( *$6 ); 2575 2579 } 2576 '{' enumerator_list comma_opt '}'2577 { 2578 $$ = DeclarationNode::newEnum( $6, $1 0, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );2580 hide_opt '{' enumerator_list comma_opt '}' 2581 { 2582 $$ = DeclarationNode::newEnum( $6, $11, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2579 2583 } 2580 2584 | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt 2581 '{' enumerator_list comma_opt '}' 2582 { 2583 $$ = DeclarationNode::newEnum( $5, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 ); 2584 } 2585 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}' 2586 { 2587 $$ = DeclarationNode::newEnum( $6->name, $9, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2588 } 2589 | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}' 2590 { 2591 $$ = DeclarationNode::newEnum( $5->name, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 ); 2585 hide_opt '{' enumerator_list comma_opt '}' 2586 { 2587 $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 ); 2588 } 2589 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt 2590 hide_opt '{' enumerator_list comma_opt '}' 2591 { 2592 $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2593 } 2594 | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt 2595 hide_opt '{' enumerator_list comma_opt '}' 2596 { 2597 $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 ); 2592 2598 } 2593 2599 | enum_type_nobody 2600 ; 2601 2602 hide_opt: 2603 // empty 2604 { $$ = EnumHiding::Visible; } 2605 | '!' 2606 { $$ = EnumHiding::Hide; } 2594 2607 ; 2595 2608 … … 2602 2615 2603 2616 enumerator_list: 2604 identifier_or_type_name enumerator_value_opt2605 { $$ = DeclarationNode::newEnumValueGeneric( $ 1, $2); }2617 visible_hide_opt identifier_or_type_name enumerator_value_opt 2618 { $$ = DeclarationNode::newEnumValueGeneric( $2, $3 ); } 2606 2619 | INLINE type_name 2607 2620 { $$ = DeclarationNode::newEnumInLine( *$2->type->symbolic.name ); } 2608 | enumerator_list ',' identifier_or_type_name enumerator_value_opt2609 { $$ = $1->appendList( DeclarationNode::newEnumValueGeneric( $ 3, $4) ); }2621 | enumerator_list ',' visible_hide_opt identifier_or_type_name enumerator_value_opt 2622 { $$ = $1->appendList( DeclarationNode::newEnumValueGeneric( $4, $5 ) ); } 2610 2623 | enumerator_list ',' INLINE type_name enumerator_value_opt 2611 2624 { $$ = $1->appendList( DeclarationNode::newEnumValueGeneric( new string("inline"), nullptr ) ); } 2625 ; 2626 2627 visible_hide_opt: 2628 hide_opt 2629 | '^' 2630 { $$ = EnumHiding::Visible; } 2612 2631 ; 2613 2632 -
src/ResolvExpr/CommonType.cc
rb77f0e1 r63be3387 991 991 add_qualifiers( result, type2->qualifiers ); 992 992 } else { 993 // xxx - does unifying a ref with typed enumInst makes sense?994 993 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 995 994 result = commonType( type2, ref, tenv, need, have, open, widen, symtab ); … … 1010 1009 1011 1010 void postvisit( const ast::EnumInstType * enumInst ) { 1012 // reuse BasicType/EnumInstType common type by swapping1013 // xxx - is this already handled by unify?1014 1011 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 1015 1012 result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab); -
src/ResolvExpr/ConversionCost.cc
rb77f0e1 r63be3387 720 720 costCalc( baseType, dst, srcIsLvalue, symtab, env ); 721 721 } else { 722 (void)enumInstType;723 722 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 724 723 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); -
src/ResolvExpr/SatisfyAssertions.cpp
rb77f0e1 r63be3387 268 268 ast::ptr< ast::Type > resType = cand.expr->result; 269 269 cand.env.apply( resType ); 270 return Mangle::mangle ( resType, Mangle::typeMode());270 return Mangle::mangleType( resType ); 271 271 } 272 272 -
src/SymTab/Mangler.cc
rb77f0e1 r63be3387 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:40:29 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jan 11 21:56:06 202113 // Update Count : 7 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 21 16:18:00 2022 13 // Update Count : 75 14 14 // 15 15 #include "Mangler.h" … … 418 418 void postvisit( const ast::QualifiedType * qualType ); 419 419 420 std::string get_mangleName() { return mangleName; } 420 /// The result is the current constructed mangled name. 421 std::string result() const { return mangleName; } 421 422 private: 422 423 std::string mangleName; ///< Mangled name being constructed … … 444 445 } // namespace 445 446 446 447 447 std::string mangle( const ast::Node * decl, Mangle::Mode mode ) { 448 ast::Pass<Mangler_new> mangler( mode ); 449 maybeAccept( decl, mangler ); 450 return mangler.core.get_mangleName(); 448 return ast::Pass<Mangler_new>::read( decl, mode ); 451 449 } 452 450 … … 689 687 } // for 690 688 for ( auto & assert : ptype->assertions ) { 691 ast::Pass<Mangler_new> sub_mangler( 692 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 693 assert->var->accept( sub_mangler ); 694 assertionNames.push_back( sub_mangler.core.get_mangleName() ); 689 assertionNames.push_back( ast::Pass<Mangler_new>::read( 690 assert->var.get(), 691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); 695 692 acount++; 696 693 } // for -
src/SymTab/Mangler.h
rb77f0e1 r63be3387 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:44:03 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:45:30 201713 // Update Count : 1 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Oct 27 11:58:00 2022 13 // Update Count : 16 14 14 // 15 15 … … 22 22 23 23 #include "AST/Bitfield.hpp" 24 #include "AST/Fwd.hpp"25 24 #include "SynTree/SynTree.h" // for Types 26 25 #include "SynTree/Visitor.h" // for Visitor, maybeAccept … … 33 32 // * Currently name compression is not implemented. 34 33 34 namespace ast { 35 class Node; 36 } 35 37 namespace ResolvExpr { 36 38 class TypeEnvironment; … … 101 103 using Mode = bitfield<mangle_flags>; 102 104 103 static inline Mode typeMode() { return NoOverrideable | Type; } 105 /// Mangle declaration name. 106 std::string mangle( const ast::Node * decl, Mode mode = {} ); 104 107 105 /// Mangle declaration name 106 std::string mangle( const ast::Node * decl, Mode mode = {} ); 108 /// Most common mangle configuration for types. 109 static inline std::string mangleType( const ast::Node * type ) { 110 return mangle( type, { NoOverrideable | Type } ); 111 } 107 112 108 113 namespace Encoding { -
src/SymTab/Validate.cc
rb77f0e1 r63be3387 47 47 #include <utility> // for pair 48 48 49 #include "AST/Chain.hpp"50 #include "AST/Decl.hpp"51 #include "AST/Node.hpp"52 #include "AST/Pass.hpp"53 #include "AST/SymbolTable.hpp"54 #include "AST/Type.hpp"55 #include "AST/TypeSubstitution.hpp"56 49 #include "CodeGen/CodeGenerator.h" // for genName 57 50 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign … … 1326 1319 } 1327 1320 1328 namespace {1329 /// Replaces enum types by int, and function/array types in function parameter and return1330 /// lists by appropriate pointers1331 /*1332 struct EnumAndPointerDecay_new {1333 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {1334 // set the type of each member of the enumeration to be EnumConstant1335 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {1336 // build new version of object with EnumConstant1337 ast::ptr< ast::ObjectDecl > obj =1338 enumDecl->members[i].strict_as< ast::ObjectDecl >();1339 obj.get_and_mutate()->type =1340 new ast::EnumInstType{ enumDecl->name, ast::CV::Const };1341 1342 // set into decl1343 ast::EnumDecl * mut = mutate( enumDecl );1344 mut->members[i] = obj.get();1345 enumDecl = mut;1346 }1347 return enumDecl;1348 }1349 1350 static const ast::FunctionType * fixFunctionList(1351 const ast::FunctionType * func,1352 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,1353 ast::ArgumentFlag isVarArgs = ast::FixedArgs1354 ) {1355 const auto & dwts = func->* field;1356 unsigned nvals = dwts.size();1357 bool hasVoid = false;1358 for ( unsigned i = 0; i < nvals; ++i ) {1359 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );1360 }1361 1362 // the only case in which "void" is valid is where it is the only one in the list1363 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {1364 SemanticError(1365 dwts.front()->location, func, "invalid type void in function type" );1366 }1367 1368 // one void is the only thing in the list, remove it1369 if ( hasVoid ) {1370 func = ast::mutate_field(1371 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );1372 }1373 1374 return func;1375 }1376 1377 const ast::FunctionType * previsit( const ast::FunctionType * func ) {1378 func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs );1379 return fixFunctionList( func, &ast::FunctionType::returns );1380 }1381 };1382 1383 /// expand assertions from a trait instance, performing appropriate type variable substitutions1384 void expandAssertions(1385 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out1386 ) {1387 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) );1388 1389 // build list of trait members, substituting trait decl parameters for instance parameters1390 ast::TypeSubstitution sub{1391 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() };1392 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base1393 for ( ast::ptr< ast::Decl > decl : inst->base->members ) {1394 auto member = decl.strict_as< ast::DeclWithType >();1395 sub.apply( member );1396 out.emplace_back( member );1397 }1398 }1399 1400 /// Associates forward declarations of aggregates with their definitions1401 class LinkReferenceToTypes_new final1402 : public ast::WithSymbolTable, public ast::WithGuards, public1403 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {1404 1405 // these maps of uses of forward declarations of types need to have the actual type1406 // declaration switched in * after * they have been traversed. To enable this in the1407 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it1408 // before it is placed in the map, properly updating its parents in the usual traversal,1409 // then can have the actual mutation applied later1410 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >;1411 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >;1412 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >;1413 1414 const CodeLocation & location;1415 const ast::SymbolTable * localSymtab;1416 1417 ForwardEnumsType forwardEnums;1418 ForwardStructsType forwardStructs;1419 ForwardUnionsType forwardUnions;1420 1421 /// true if currently in a generic type body, so that type parameter instances can be1422 /// renamed appropriately1423 bool inGeneric = false;1424 1425 public:1426 /// contstruct using running symbol table1427 LinkReferenceToTypes_new( const CodeLocation & loc )1428 : location( loc ), localSymtab( &symtab ) {}1429 1430 /// construct using provided symbol table1431 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms )1432 : location( loc ), localSymtab( &syms ) {}1433 1434 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {1435 // ensure generic parameter instances are renamed like the base type1436 if ( inGeneric && typeInst->base ) {1437 typeInst = ast::mutate_field(1438 typeInst, &ast::TypeInstType::name, typeInst->base->name );1439 }1440 1441 if (1442 auto typeDecl = dynamic_cast< const ast::TypeDecl * >(1443 localSymtab->lookupType( typeInst->name ) )1444 ) {1445 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind );1446 }1447 1448 return typeInst;1449 }1450 1451 const ast::Type * postvisit( const ast::EnumInstType * inst ) {1452 const ast::EnumDecl * decl = localSymtab->lookupEnum( inst->name );1453 // not a semantic error if the enum is not found, just an implicit forward declaration1454 if ( decl ) {1455 inst = ast::mutate_field( inst, &ast::EnumInstType::base, decl );1456 }1457 if ( ! decl || ! decl->body ) {1458 // forward declaration1459 auto mut = mutate( inst );1460 forwardEnums.emplace( inst->name, mut );1461 inst = mut;1462 }1463 return inst;1464 }1465 1466 void checkGenericParameters( const ast::BaseInstType * inst ) {1467 for ( const ast::Expr * param : inst->params ) {1468 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) {1469 SemanticError(1470 location, inst, "Expression parameters for generic types are currently "1471 "unsupported: " );1472 }1473 }1474 }1475 1476 const ast::StructInstType * postvisit( const ast::StructInstType * inst ) {1477 const ast::StructDecl * decl = localSymtab->lookupStruct( inst->name );1478 // not a semantic error if the struct is not found, just an implicit forward declaration1479 if ( decl ) {1480 inst = ast::mutate_field( inst, &ast::StructInstType::base, decl );1481 }1482 if ( ! decl || ! decl->body ) {1483 // forward declaration1484 auto mut = mutate( inst );1485 forwardStructs.emplace( inst->name, mut );1486 inst = mut;1487 }1488 checkGenericParameters( inst );1489 return inst;1490 }1491 1492 const ast::UnionInstType * postvisit( const ast::UnionInstType * inst ) {1493 const ast::UnionDecl * decl = localSymtab->lookupUnion( inst->name );1494 // not a semantic error if the struct is not found, just an implicit forward declaration1495 if ( decl ) {1496 inst = ast::mutate_field( inst, &ast::UnionInstType::base, decl );1497 }1498 if ( ! decl || ! decl->body ) {1499 // forward declaration1500 auto mut = mutate( inst );1501 forwardUnions.emplace( inst->name, mut );1502 inst = mut;1503 }1504 checkGenericParameters( inst );1505 return inst;1506 }1507 1508 const ast::Type * postvisit( const ast::TraitInstType * traitInst ) {1509 // handle other traits1510 const ast::TraitDecl * traitDecl = localSymtab->lookupTrait( traitInst->name );1511 if ( ! traitDecl ) {1512 SemanticError( location, "use of undeclared trait " + traitInst->name );1513 }1514 if ( traitDecl->params.size() != traitInst->params.size() ) {1515 SemanticError( location, traitInst, "incorrect number of trait parameters: " );1516 }1517 traitInst = ast::mutate_field( traitInst, &ast::TraitInstType::base, traitDecl );1518 1519 // need to carry over the "sized" status of each decl in the instance1520 for ( unsigned i = 0; i < traitDecl->params.size(); ++i ) {1521 auto expr = traitInst->params[i].as< ast::TypeExpr >();1522 if ( ! expr ) {1523 SemanticError(1524 traitInst->params[i].get(), "Expression parameters for trait instances "1525 "are currently unsupported: " );1526 }1527 1528 if ( auto inst = expr->type.as< ast::TypeInstType >() ) {1529 if ( traitDecl->params[i]->sized && ! inst->base->sized ) {1530 // traitInst = ast::mutate_field_index(1531 // traitInst, &ast::TraitInstType::params, i,1532 // ...1533 // );1534 ast::TraitInstType * mut = ast::mutate( traitInst );1535 ast::chain_mutate( mut->params[i] )1536 ( &ast::TypeExpr::type )1537 ( &ast::TypeInstType::base )->sized = true;1538 traitInst = mut;1539 }1540 }1541 }1542 1543 return traitInst;1544 }1545 1546 void previsit( const ast::QualifiedType * ) { visit_children = false; }1547 1548 const ast::Type * postvisit( const ast::QualifiedType * qualType ) {1549 // linking only makes sense for the "oldest ancestor" of the qualified type1550 return ast::mutate_field(1551 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );1552 }1553 1554 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) {1555 // visit enum members first so that the types of self-referencing members are updated1556 // properly1557 if ( ! enumDecl->body ) return enumDecl;1558 1559 // update forward declarations to point here1560 auto fwds = forwardEnums.equal_range( enumDecl->name );1561 if ( fwds.first != fwds.second ) {1562 auto inst = fwds.first;1563 do {1564 // forward decl is stored * mutably * in map, can thus be updated1565 inst->second->base = enumDecl;1566 } while ( ++inst != fwds.second );1567 forwardEnums.erase( fwds.first, fwds.second );1568 }1569 1570 // ensure that enumerator initializers are properly set1571 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {1572 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >();1573 if ( field->init ) {1574 // need to resolve enumerator initializers early so that other passes that1575 // determine if an expression is constexpr have appropriate information1576 auto init = field->init.strict_as< ast::SingleInit >();1577 1578 enumDecl = ast::mutate_field_index(1579 enumDecl, &ast::EnumDecl::members, i,1580 ast::mutate_field( field, &ast::ObjectDecl::init,1581 ast::mutate_field( init, &ast::SingleInit::value,1582 ResolvExpr::findSingleExpression(1583 init->value, new ast::BasicType{ ast::BasicType::SignedInt },1584 symtab ) ) ) );1585 }1586 }1587 1588 return enumDecl;1589 }1590 1591 /// rename generic type parameters uniquely so that they do not conflict with user defined1592 /// function forall parameters, e.g. the T in Box and the T in f, below1593 /// forall(otype T)1594 /// struct Box {1595 /// T x;1596 /// };1597 /// forall(otype T)1598 /// void f(Box(T) b) {1599 /// ...1600 /// }1601 template< typename AggrDecl >1602 const AggrDecl * renameGenericParams( const AggrDecl * aggr ) {1603 GuardValue( inGeneric );1604 inGeneric = ! aggr->params.empty();1605 1606 for ( unsigned i = 0; i < aggr->params.size(); ++i ) {1607 const ast::TypeDecl * td = aggr->params[i];1608 1609 aggr = ast::mutate_field_index(1610 aggr, &AggrDecl::params, i,1611 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) );1612 }1613 return aggr;1614 }1615 1616 const ast::StructDecl * previsit( const ast::StructDecl * structDecl ) {1617 return renameGenericParams( structDecl );1618 }1619 1620 void postvisit( const ast::StructDecl * structDecl ) {1621 // visit struct members first so that the types of self-referencing members are1622 // updated properly1623 if ( ! structDecl->body ) return;1624 1625 // update forward declarations to point here1626 auto fwds = forwardStructs.equal_range( structDecl->name );1627 if ( fwds.first != fwds.second ) {1628 auto inst = fwds.first;1629 do {1630 // forward decl is stored * mutably * in map, can thus be updated1631 inst->second->base = structDecl;1632 } while ( ++inst != fwds.second );1633 forwardStructs.erase( fwds.first, fwds.second );1634 }1635 }1636 1637 const ast::UnionDecl * previsit( const ast::UnionDecl * unionDecl ) {1638 return renameGenericParams( unionDecl );1639 }1640 1641 void postvisit( const ast::UnionDecl * unionDecl ) {1642 // visit union members first so that the types of self-referencing members are updated1643 // properly1644 if ( ! unionDecl->body ) return;1645 1646 // update forward declarations to point here1647 auto fwds = forwardUnions.equal_range( unionDecl->name );1648 if ( fwds.first != fwds.second ) {1649 auto inst = fwds.first;1650 do {1651 // forward decl is stored * mutably * in map, can thus be updated1652 inst->second->base = unionDecl;1653 } while ( ++inst != fwds.second );1654 forwardUnions.erase( fwds.first, fwds.second );1655 }1656 }1657 1658 const ast::Decl * postvisit( const ast::TraitDecl * traitDecl ) {1659 // set the "sized" status for the special "sized" trait1660 if ( traitDecl->name == "sized" ) {1661 assertf( traitDecl->params.size() == 1, "Built-in trait 'sized' has incorrect "1662 "number of parameters: %zd", traitDecl->params.size() );1663 1664 traitDecl = ast::mutate_field_index(1665 traitDecl, &ast::TraitDecl::params, 0,1666 ast::mutate_field(1667 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) );1668 }1669 1670 // move assertions from type parameters into the body of the trait1671 std::vector< ast::ptr< ast::DeclWithType > > added;1672 for ( const ast::TypeDecl * td : traitDecl->params ) {1673 for ( const ast::DeclWithType * assn : td->assertions ) {1674 auto inst = dynamic_cast< const ast::TraitInstType * >( assn->get_type() );1675 if ( inst ) {1676 expandAssertions( inst, added );1677 } else {1678 added.emplace_back( assn );1679 }1680 }1681 }1682 if ( ! added.empty() ) {1683 auto mut = mutate( traitDecl );1684 for ( const ast::DeclWithType * decl : added ) {1685 mut->members.emplace_back( decl );1686 }1687 traitDecl = mut;1688 }1689 1690 return traitDecl;1691 }1692 };1693 1694 /// Replaces array and function types in forall lists by appropriate pointer type and assigns1695 /// each object and function declaration a unique ID1696 class ForallPointerDecay_new {1697 const CodeLocation & location;1698 public:1699 ForallPointerDecay_new( const CodeLocation & loc ) : location( loc ) {}1700 1701 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) {1702 // ensure that operator names only apply to functions or function pointers1703 if (1704 CodeGen::isOperator( obj->name )1705 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() )1706 ) {1707 SemanticError( obj->location, toCString( "operator ", obj->name.c_str(), " is not "1708 "a function or function pointer." ) );1709 }1710 1711 // ensure object has unique ID1712 if ( obj->uniqueId ) return obj;1713 auto mut = mutate( obj );1714 mut->fixUniqueId();1715 return mut;1716 }1717 1718 const ast::FunctionDecl * previsit( const ast::FunctionDecl * func ) {1719 // ensure function has unique ID1720 if ( func->uniqueId ) return func;1721 auto mut = mutate( func );1722 mut->fixUniqueId();1723 return mut;1724 }1725 1726 /// Fix up assertions -- flattens assertion lists, removing all trait instances1727 template< typename node_t, typename parent_t >1728 static const node_t * forallFixer(1729 const CodeLocation & loc, const node_t * node,1730 ast::FunctionType::ForallList parent_t::* forallField1731 ) {1732 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {1733 const ast::TypeDecl * type = (node->* forallField)[i];1734 if ( type->assertions.empty() ) continue;1735 1736 std::vector< ast::ptr< ast::DeclWithType > > asserts;1737 asserts.reserve( type->assertions.size() );1738 1739 // expand trait instances into their members1740 for ( const ast::DeclWithType * assn : type->assertions ) {1741 auto traitInst =1742 dynamic_cast< const ast::TraitInstType * >( assn->get_type() );1743 if ( traitInst ) {1744 // expand trait instance to all its members1745 expandAssertions( traitInst, asserts );1746 } else {1747 // pass other assertions through1748 asserts.emplace_back( assn );1749 }1750 }1751 1752 // apply FixFunction to every assertion to check for invalid void type1753 for ( ast::ptr< ast::DeclWithType > & assn : asserts ) {1754 bool isVoid = false;1755 assn = fixFunction( assn, isVoid );1756 if ( isVoid ) {1757 SemanticError( loc, node, "invalid type void in assertion of function " );1758 }1759 }1760 1761 // place mutated assertion list in node1762 auto mut = mutate( type );1763 mut->assertions = move( asserts );1764 node = ast::mutate_field_index( node, forallField, i, mut );1765 }1766 return node;1767 }1768 1769 const ast::FunctionType * previsit( const ast::FunctionType * ftype ) {1770 return forallFixer( location, ftype, &ast::FunctionType::forall );1771 }1772 1773 const ast::StructDecl * previsit( const ast::StructDecl * aggrDecl ) {1774 return forallFixer( aggrDecl->location, aggrDecl, &ast::StructDecl::params );1775 }1776 1777 const ast::UnionDecl * previsit( const ast::UnionDecl * aggrDecl ) {1778 return forallFixer( aggrDecl->location, aggrDecl, &ast::UnionDecl::params );1779 }1780 };1781 */1782 } // anonymous namespace1783 1784 /*1785 const ast::Type * validateType(1786 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {1787 // ast::Pass< EnumAndPointerDecay_new > epc;1788 ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };1789 ast::Pass< ForallPointerDecay_new > fpd{ loc };1790 1791 return type->accept( lrt )->accept( fpd );1792 }1793 */1794 1795 1321 } // namespace SymTab 1796 1322 -
src/SynTree/Declaration.h
rb77f0e1 r63be3387 449 449 }; 450 450 451 452 class InlineMemberDecl : public DeclarationWithType { 453 typedef DeclarationWithType Parent; 454 public: 455 Type * type; 456 457 InlineMemberDecl( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, Type * type, 458 const std::list< Attribute * > attributes = std::list< Attribute * >(), Type::FuncSpecifiers fs = Type::FuncSpecifiers() ); 459 InlineMemberDecl( const InlineMemberDecl & other ); 460 virtual ~InlineMemberDecl(); 461 462 virtual Type * get_type() const override { return type; } 463 virtual void set_type(Type * newType) override { type = newType; } 464 465 static InlineMemberDecl * newInlineMemberDecl( const std::string & name, Type * type ); 466 467 virtual InlineMemberDecl * clone() const override { return new InlineMemberDecl( *this ); } 468 virtual void accept( Visitor & v ) override { v.visit( this ); } 469 virtual void accept( Visitor & v ) const override { v.visit( this ); } 470 virtual DeclarationWithType * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 471 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 472 virtual void printShort( std::ostream & os, Indenter indent = {} ) const override; 473 474 }; 475 451 476 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ); 452 477 -
src/SynTree/Mutator.h
rb77f0e1 r63be3387 36 36 virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) = 0; 37 37 virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0; 38 virtual DeclarationWithType * mutate( InlineMemberDecl * InlineMemberDecl ) = 0; 38 39 39 40 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) = 0; -
src/SynTree/SynTree.h
rb77f0e1 r63be3387 38 38 class DirectiveDecl; 39 39 class StaticAssertDecl; 40 class InlineMemberDecl; 40 41 41 42 class Statement; -
src/SynTree/Visitor.h
rb77f0e1 r63be3387 49 49 virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); } 50 50 virtual void visit( const StaticAssertDecl * assertDecl ) = 0; 51 virtual void visit( InlineMemberDecl * node ) { visit( const_cast<const InlineMemberDecl *>(node) ); } 52 virtual void visit( const InlineMemberDecl * valueDecl ) = 0; 51 53 52 54 virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); } -
src/SynTree/module.mk
rb77f0e1 r63be3387 42 42 SynTree/Initializer.cc \ 43 43 SynTree/Initializer.h \ 44 SynTree/InlineMemberDecl.cc \ 44 45 SynTree/Label.h \ 45 46 SynTree/LinkageSpec.cc \ -
src/Validate/EnumAndPointerDecay.cpp
rb77f0e1 r63be3387 21 21 #include "AST/Type.hpp" 22 22 #include "SymTab/FixFunction.h" 23 #include "Validate/NoIdSymbolTable.hpp" 23 24 24 25 namespace Validate { … … 26 27 namespace { 27 28 28 struct EnumAndPointerDecayCore final : public ast::WithCodeLocation {29 struct EnumAndPointerDecayCore final : public WithNoIdSymbolTable, public ast::WithCodeLocation { 29 30 ast::EnumDecl const * previsit( ast::EnumDecl const * decl ); 30 31 ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl ); … … 39 40 // Set the type of each member of the enumeration to be EnumContant. 40 41 auto mut = ast::mutate( decl ); 41 for ( ast::ptr<ast::Decl> & member : mut->members ) { 42 ast::ObjectDecl const * object = member.strict_as<ast::ObjectDecl>(); 43 member = ast::mutate_field( object, &ast::ObjectDecl::type, 44 new ast::EnumInstType( decl, ast::CV::Const ) ); 42 std::vector<ast::ptr<ast::Decl>> buffer; 43 for ( auto member : decl->members ) { 44 if ( ast::ObjectDecl const * object = member.as<ast::ObjectDecl>() ) { 45 buffer.push_back( ast::mutate_field( object, 46 &ast::ObjectDecl::type, 47 new ast::EnumInstType( decl, ast::CV::Const ) ) ); 48 } else if ( auto value = member.as<ast::InlineMemberDecl>() ) { 49 if ( auto targetEnum = symtab.lookupEnum( value->name ) ) { 50 for ( auto enumMember : targetEnum->members ) { 51 auto enumObject = enumMember.strict_as<ast::ObjectDecl>(); 52 buffer.push_back( new ast::ObjectDecl( 53 // Get the location from the "inline" declaration. 54 value->location, 55 enumObject->name, 56 // Construct a new EnumInstType as the type. 57 new ast::EnumInstType( decl, ast::CV::Const ), 58 enumObject->init, 59 enumObject->storage, 60 enumObject->linkage, 61 enumObject->bitfieldWidth, 62 {}, 63 enumObject->funcSpec 64 ) ); 65 } 66 } 67 } 45 68 } 69 mut->members = buffer; 46 70 return mut; 47 71 } -
src/Validate/LinkReferenceToTypes.cpp
rb77f0e1 r63be3387 185 185 decl = mut; 186 186 } 187 // visit the base 187 188 } else if ( auto ptr = decl->base.as<ast::PointerType>() ) { 188 189 if ( auto base = ptr->base.as<ast::TypeInstType>() ) { … … 203 204 204 205 // The following section 205 auto mut = ast::mutate( decl );206 std::vector<ast::ptr<ast::Decl>> buffer;207 for ( auto it = decl->members.begin(); it != decl->members.end(); ++it) {208 auto member = (*it).as<ast::ObjectDecl>();209 if ( member->enumInLine ) {210 auto targetEnum = symtab.lookupEnum( member->name );211 if ( targetEnum ) {212 for ( auto singleMamber : targetEnum->members ) {213 auto tm = singleMamber.as<ast::ObjectDecl>();214 auto t = new ast::ObjectDecl(215 member->location, // use the "inline" location216 tm->name,217 new ast::EnumInstType( decl, ast::CV::Const ),218 // Construct a new EnumInstType as the type219 tm->init,220 tm->storage,221 tm->linkage,222 tm->bitfieldWidth,223 {}, // enum member doesn't have attribute224 tm->funcSpec225 );226 t->importValue = true;227 buffer.push_back(t);228 }229 }230 } else {231 auto search_it = std::find_if( buffer.begin(), buffer.end(), [member](ast::ptr<ast::Decl> cur) {232 auto curAsObjDecl = cur.as<ast::ObjectDecl>();233 return (curAsObjDecl->importValue) && (curAsObjDecl->name == member->name);234 });235 if ( search_it != buffer.end() ) {236 buffer.erase( search_it ); // Found an import enum value that has the same name237 // override the imported value238 }239 buffer.push_back( *it );240 }241 }242 mut->members = buffer;243 decl = mut;244 206 245 207 ForwardEnumsType::iterator fwds = forwardEnums.find( decl->name ); -
src/Virtual/ExpandCasts.cc
rb77f0e1 r63be3387 295 295 // returns the previous declaration for error messages. 296 296 ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) { 297 std::string const & mangledName = 298 Mangle::mangle( typeIdDecl->type, Mangle::typeMode() ); 297 std::string mangledName = Mangle::mangleType( typeIdDecl->type ); 299 298 ast::ObjectDecl const *& value = instances[ mangledName ]; 300 299 if ( value ) { … … 310 309 311 310 ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) { 312 std::string const & mangledName = 313 Mangle::mangle( typeIdType, Mangle::typeMode() ); 311 std::string mangledName = Mangle::mangleType( typeIdType ); 314 312 auto const it = instances.find( mangledName ); 315 313 return ( instances.end() == it ) ? nullptr : it->second;
Note:
See TracChangeset
for help on using the changeset viewer.