- Timestamp:
- Sep 21, 2022, 11:02:15 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 95dab9e
- Parents:
- 428adbc (diff), 0bd46fd (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:
-
- 3 added
- 83 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r428adbc r7f6a7c9 310 310 node->name, 311 311 get<Attribute>().acceptL( node->attributes ), 312 false, // Temporary 312 313 LinkageSpec::Spec( node->linkage.val ), 313 314 get<Type>().accept1(node->base) … … 731 732 } 732 733 734 const ast::Expr * visit( const ast::QualifiedNameExpr * node ) override final { 735 auto temp = new QualifiedNameExpr( 736 get<Declaration>().accept1(node->type_decl), 737 node->name 738 ); 739 temp->var = get<DeclarationWithType>().accept1(node->var); 740 auto expr = visitBaseExpr( node, 741 temp 742 ); 743 this->node = expr; 744 return nullptr; 745 } 746 733 747 const ast::Expr * visit( const ast::AddressExpr * node ) override final { 734 748 auto expr = visitBaseExpr( node, … … 1740 1754 old->location, 1741 1755 old->name, 1756 old->isTyped, 1742 1757 GET_ACCEPT_V(attributes, Attribute), 1743 1758 { old->linkage.val }, … … 2266 2281 } 2267 2282 2283 /// xxx - type_decl should be DeclWithType in the final design 2284 /// type_decl is set to EnumDecl as a temporary fix 2285 virtual void visit( const QualifiedNameExpr * old ) override final { 2286 this->node = visitBaseExpr( old, 2287 new ast::QualifiedNameExpr ( 2288 old->location, 2289 GET_ACCEPT_1(type_decl, Decl), 2290 GET_ACCEPT_1(var, DeclWithType), 2291 old->name 2292 ) 2293 ); 2294 } 2295 2268 2296 virtual void visit( const CastExpr * old ) override final { 2269 2297 this->node = visitBaseExpr( old, -
src/AST/Decl.hpp
r428adbc r7f6a7c9 217 217 218 218 /// convenience accessor to match Type::isComplete() 219 bool isComplete() { return sized; }219 bool isComplete() const { return sized; } 220 220 221 221 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } … … 312 312 class EnumDecl final : public AggregateDecl { 313 313 public: 314 bool isTyped; 314 315 ptr<Type> base; 315 316 316 EnumDecl( const CodeLocation& loc, const std::string& name, 317 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, Type const * base = nullptr, 317 EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 318 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, 319 Type const * base = nullptr, 318 320 std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() ) 319 : AggregateDecl( loc, name, std::move(attrs), linkage ), base(base), enumValues(enumValues) {}321 : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), enumValues(enumValues) {} 320 322 321 323 /// gets the integer value for this enumerator, returning true iff value found … … 327 329 const char * typeString() const override { return aggrString( Enum ); } 328 330 329 bool isTyped() {return base && base.get();}330 331 331 332 private: -
src/AST/DeclReplacer.cpp
r428adbc r7f6a7c9 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 8 13:00:00 2019 11 // Last Modified By : A aron B. Moss12 // Last Modified On : Wed May 8 13:00:00 201913 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Sep 15 11:55:00 2022 13 // Update Count : 2 14 14 // 15 15 16 16 #include "DeclReplacer.hpp" 17 17 18 #include "Expr.hpp" 19 #include "Pass.hpp" 18 20 #include "Type.hpp" 19 20 #include "Pass.hpp"21 21 22 22 namespace ast { 23 23 24 24 namespace DeclReplacer { 25 namespace {26 struct DeclReplacer {27 private:28 const DeclMap & declMap;29 const TypeMap & typeMap;30 bool debug;31 25 32 public: 33 DeclReplacer(const DeclMap & declMap, const TypeMap & typeMap, bool debug) 34 : declMap( declMap ), typeMap( typeMap ), debug( debug ) 35 {} 26 namespace { 27 struct DeclReplacer { 28 private: 29 const DeclMap & declMap; 30 const TypeMap & typeMap; 31 bool debug; 36 32 37 const ast::VariableExpr * previsit( const ast::VariableExpr * ); 38 const ast::TypeInstType * previsit( const ast::TypeInstType * ); 39 }; 33 public: 34 DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) 35 : declMap( declMap ), typeMap( typeMap ), debug( debug ) 36 {} 40 37 41 struct VarExprReplacer { 42 private: 43 const ExprMap & exprMap; 44 45 public: 46 VarExprReplacer(const ExprMap & exprMap): exprMap (exprMap) {} 38 const ast::VariableExpr * previsit( const ast::VariableExpr * ); 39 const ast::TypeInstType * previsit( const ast::TypeInstType * ); 40 }; 47 41 48 const Expr * postvisit (const VariableExpr *); 49 }; 42 struct VarExprReplacer { 43 private: 44 const ExprMap & exprMap; 45 46 public: 47 VarExprReplacer( const ExprMap & exprMap ) : exprMap( exprMap ) {} 48 49 const Expr * postvisit( const VariableExpr * ); 50 }; 51 } // namespace 52 53 const ast::Node * replace( const ast::Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) { 54 if(!node) return nullptr; 55 Pass<DeclReplacer> replacer = { declMap, typeMap, debug }; 56 return node->accept( replacer ); 57 } 58 59 const ast::Node * replace( const ast::Node * node, const DeclMap & declMap, bool debug ) { 60 TypeMap typeMap; 61 return replace( node, declMap, typeMap, debug ); 62 } 63 64 const ast::Node * replace( const ast::Node * node, const TypeMap & typeMap, bool debug ) { 65 DeclMap declMap; 66 return replace( node, declMap, typeMap, debug ); 67 } 68 69 const ast::Node * replace( const ast::Node * node, const ExprMap & exprMap ) { 70 Pass<VarExprReplacer> replacer = {exprMap}; 71 return node->accept( replacer ); 72 } 73 74 namespace { 75 // replace variable with new node from decl map 76 const ast::VariableExpr * DeclReplacer::previsit( const VariableExpr * varExpr ) { 77 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 78 if ( !declMap.count( varExpr->var ) ) return varExpr; 79 80 auto replacement = declMap.at( varExpr->var ); 81 if ( debug ) { 82 std::cerr << "replacing variable reference: " 83 << (void*)varExpr->var.get() << " " << varExpr->var 84 << " with " << (void*)replacement << " " << replacement 85 << std::endl; 86 } 87 auto nexpr = mutate(varExpr); 88 nexpr->var = replacement; 89 return nexpr; 50 90 } 51 91 52 const ast::Node * replace( const ast::Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) { 53 if(!node) return nullptr; 54 Pass<DeclReplacer> replacer = { declMap, typeMap, debug }; 55 return node->accept( replacer ); 92 const TypeInstType * DeclReplacer::previsit( const TypeInstType * inst ) { 93 if ( !typeMap.count( inst->base ) ) return inst; 94 95 auto replacement = typeMap.at( inst->base ); 96 if ( debug ) { 97 std::cerr << "replacing type reference: " 98 << (void*)inst->base.get() << " " << inst->base 99 << " with " << (void*)replacement << " " << replacement 100 << std::endl; 101 } 102 auto ninst = mutate(inst); 103 ninst->base = replacement; 104 return ninst; 56 105 } 57 106 58 const ast::Node * replace( const ast::Node * node, const DeclMap & declMap, bool debug) {59 TypeMap typeMap;60 return replace( node, declMap, typeMap, debug);107 const Expr * VarExprReplacer::postvisit( const VariableExpr * expr ) { 108 if ( !exprMap.count( expr->var ) ) return expr; 109 return exprMap.at( expr->var ); 61 110 } 111 } // namespace 62 112 63 const ast::Node * replace( const ast::Node * node, const TypeMap & typeMap, bool debug ) { 64 DeclMap declMap; 65 return replace( node, declMap, typeMap, debug ); 66 } 113 } // namespace DeclReplacer 67 114 68 const ast::Node * replace( const ast::Node * node, const ExprMap & exprMap) { 69 Pass<VarExprReplacer> replacer = {exprMap}; 70 return node->accept( replacer ); 71 } 72 73 namespace { 74 // replace variable with new node from decl map 75 const ast::VariableExpr * DeclReplacer::previsit( const VariableExpr * varExpr ) { 76 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 77 if ( !declMap.count( varExpr->var ) ) return varExpr; 78 79 auto replacement = declMap.at( varExpr->var ); 80 if ( debug ) { 81 std::cerr << "replacing variable reference: " 82 << (void*)varExpr->var.get() << " " << varExpr->var 83 << " with " << (void*)replacement << " " << replacement 84 << std::endl; 85 } 86 auto nexpr = mutate(varExpr); 87 nexpr->var = replacement; 88 return nexpr; 89 } 90 91 const TypeInstType * DeclReplacer::previsit( const TypeInstType * inst ) { 92 if ( !typeMap.count( inst->base ) ) return inst; 93 94 auto replacement = typeMap.at( inst->base ); 95 if ( debug ) { 96 std::cerr << "replacing type reference: " 97 << (void*)inst->base.get() << " " << inst->base 98 << " with " << (void*)replacement << " " << replacement 99 << std::endl; 100 } 101 auto ninst = mutate(inst); 102 ninst->base = replacement; 103 return ninst; 104 } 105 106 const Expr * VarExprReplacer::postvisit( const VariableExpr * expr ) { 107 if (!exprMap.count(expr->var)) return expr; 108 109 return exprMap.at(expr->var); 110 } 111 112 } 113 } 114 115 } 115 } // namespace ast 116 116 117 117 // Local Variables: // -
src/AST/Expr.hpp
r428adbc r7f6a7c9 254 254 }; 255 255 256 class QualifiedNameExpr final : public Expr { 257 public: 258 ptr<Decl> type_decl; 259 ptr<DeclWithType> var; 260 std::string name; 261 262 QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const DeclWithType * r, const std::string & n ) 263 : Expr( loc ), type_decl( d ), var(r), name( n ) {} 264 265 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } 266 private: 267 QualifiedNameExpr * clone() const override { return new QualifiedNameExpr{ *this }; } 268 MUTATE_FRIEND 269 }; 270 256 271 /// A reference to a named variable. 257 272 class VariableExpr final : public Expr { -
src/AST/Fwd.hpp
r428adbc r7f6a7c9 67 67 class UntypedExpr; 68 68 class NameExpr; 69 class QualifiedNameExpr; 69 70 class AddressExpr; 70 71 class LabelAddressExpr; -
src/AST/Pass.hpp
r428adbc r7f6a7c9 167 167 const ast::Expr * visit( const ast::UntypedExpr * ) override final; 168 168 const ast::Expr * visit( const ast::NameExpr * ) override final; 169 const ast::Expr * visit( const ast::QualifiedNameExpr * ) override final; 169 170 const ast::Expr * visit( const ast::AddressExpr * ) override final; 170 171 const ast::Expr * visit( const ast::LabelAddressExpr * ) override final; … … 327 328 struct PureVisitor {}; 328 329 330 /// Keep track of the nearest parent node's location field. 331 struct WithCodeLocation { 332 const CodeLocation * location = nullptr; 333 }; 334 329 335 /// Keep track of the polymorphic const TypeSubstitution * typeSubs for the current expression. 330 336 struct WithConstTypeSubstitution { -
src/AST/Pass.impl.hpp
r428adbc r7f6a7c9 25 25 #define VISIT_START( node ) \ 26 26 using namespace ast; \ 27 /* back-up the last known code location */ \ 28 __attribute__((unused)) auto loc_guard = ast::__pass::make_location_guard( core, node, 0 ); \ 27 29 /* back-up the visit children */ \ 28 30 __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(core, 0) ); \ … … 1197 1199 1198 1200 //-------------------------------------------------------------------------- 1201 // QualifiedNameExpr 1202 template< typename core_t > 1203 const ast::Expr * ast::Pass< core_t >::visit( const ast::QualifiedNameExpr * node ) { 1204 VISIT_START( node ); 1205 if ( __visit_children() ) { 1206 guard_symtab guard { *this }; 1207 maybe_accept( node, &QualifiedNameExpr::var ); 1208 maybe_accept( node, &QualifiedNameExpr::type_decl ); 1209 } 1210 VISIT_END( Expr, node ); 1211 } 1212 1213 //-------------------------------------------------------------------------- 1199 1214 // CastExpr 1200 1215 template< typename core_t > -
src/AST/Pass.proto.hpp
r428adbc r7f6a7c9 326 326 } 327 327 328 template< typename core_t, typename node_t > 329 static auto make_location_guard( core_t & core, node_t * node, int ) 330 -> decltype( node->location, ValueGuardPtr<const CodeLocation *>( &core.location ) ) { 331 ValueGuardPtr<const CodeLocation *> guard( &core.location ); 332 core.location = &node->location; 333 return guard; 334 } 335 336 template< typename core_t, typename node_t > 337 static auto make_location_guard( core_t &, node_t *, long ) -> int { 338 return 0; 339 } 340 328 341 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 329 342 // All passes which have such functions are assumed desire this behaviour -
src/AST/Print.cpp
r428adbc r7f6a7c9 33 33 { 34 34 return array<C,sizeof...(T)>{ 35 forward<T>(values)...35 std::forward<T>(values)... 36 36 }; 37 37 } … … 86 86 87 87 static constexpr auto StorageClasses = make_array<const char*>( 88 "extern", "static", "auto", "register", "_ Thread_local"88 "extern", "static", "auto", "register", "__thread", "_Thread_local" 89 89 ); 90 90 91 91 static constexpr auto Qualifiers = make_array<const char*>( 92 "const", "restrict", "volatile", " lvalue", "mutex", "_Atomic"92 "const", "restrict", "volatile", "mutex", "_Atomic" 93 93 ); 94 94 }; … … 215 215 ++indent; 216 216 ptrToEnum->base->accept( *this ); 217 --indent; 217 --indent; 218 218 } 219 219 … … 899 899 postprint( node ); 900 900 901 return node; 902 } 903 904 virtual const ast::Expr * visit( const ast::QualifiedNameExpr * node ) override final { 905 os << "QualifiedNameExpr: " << std::endl; 906 os << ++indent << "Type: "; 907 safe_print( node->type_decl ); 908 os << std::endl; 909 os << indent << "Name: " << node->name << std::endl; 910 --indent; 911 postprint( node ); 901 912 return node; 902 913 } … … 1623 1634 // if the wrong size is specified 1624 1635 constexpr array<const char*, 3> Printer::Names::FuncSpecifiers; 1625 constexpr array<const char*, 5> Printer::Names::StorageClasses;1626 constexpr array<const char*, 6> Printer::Names::Qualifiers;1636 constexpr array<const char*, 6> Printer::Names::StorageClasses; 1637 constexpr array<const char*, 5> Printer::Names::Qualifiers; 1627 1638 } -
src/AST/StorageClasses.hpp
r428adbc r7f6a7c9 24 24 /// Bitflags for storage classes 25 25 enum { 26 Extern = 1 << 0, 27 Static = 1 << 1, 28 Auto = 1 << 2, 29 Register = 1 << 3, 30 ThreadLocal = 1 << 4, 31 NumClasses = 5 26 Extern = 1 << 0, 27 Static = 1 << 1, 28 Auto = 1 << 2, 29 Register = 1 << 3, 30 ThreadLocalGcc = 1 << 4, 31 ThreadLocalC11 = 1 << 5, 32 NumClasses = 6 32 33 }; 33 34 … … 37 38 unsigned int val; 38 39 struct { 39 bool is_extern : 1; 40 bool is_static : 1; 41 bool is_auto : 1; 42 bool is_register : 1; 43 bool is_threadlocal : 1; 40 bool is_extern : 1; 41 bool is_static : 1; 42 bool is_auto : 1; 43 bool is_register : 1; 44 bool is_threadlocalGcc : 1; 45 bool is_threadlocalC11 : 1; 44 46 }; 45 47 … … 48 50 49 51 constexpr class_flags( unsigned int val = 0 ) : val(val) {} 52 53 bool is_threadlocal_any() { return this->is_threadlocalC11 || this->is_threadlocalGcc; } 50 54 }; 51 55 -
src/AST/Type.cpp
r428adbc r7f6a7c9 143 143 TraitInstType::TraitInstType( 144 144 const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 145 : BaseInstType( b->name, q, move(as) ), base( b ) {}145 : BaseInstType( b->name, q, std::move(as) ), base( b ) {} 146 146 147 147 // --- TypeInstType … … 149 149 TypeInstType::TypeInstType( const TypeDecl * b, 150 150 CV::Qualifiers q, std::vector<ptr<Attribute>> && as ) 151 : BaseInstType( b->name, q, move(as) ), base( b ), kind( b->kind ) {}151 : BaseInstType( b->name, q, std::move(as) ), base( b ), kind( b->kind ) {} 152 152 153 153 void TypeInstType::set_base( const TypeDecl * b ) { … … 161 161 162 162 TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q ) 163 : Type( q ), types( move(ts) ), members() {163 : Type( q ), types( std::move(ts) ), members() { 164 164 // This constructor is awkward. `TupleType` needs to contain objects so that members can be 165 165 // named, but members without initializer nodes end up getting constructors, which breaks -
src/AST/Type.hpp
r428adbc r7f6a7c9 83 83 template< enum Node::ref_type ref_t > 84 84 void reset_qualifiers( ptr_base< Type, ref_t > & p, CV::Qualifiers q = {} ) { 85 if ( p->qualifiers .val != q.val) p.get_and_mutate()->qualifiers = q;85 if ( p->qualifiers != q ) p.get_and_mutate()->qualifiers = q; 86 86 } 87 87 … … 89 89 template< enum Node::ref_type ref_t > 90 90 void add_qualifiers( ptr_base< Type, ref_t > & p, CV::Qualifiers q ) { 91 if ( ( p->qualifiers .val & q.val ) != q.val) p.get_and_mutate()->qualifiers |= q;91 if ( ( p->qualifiers & q ) != q ) p.get_and_mutate()->qualifiers |= q; 92 92 } 93 93 … … 95 95 template< enum Node::ref_type ref_t > 96 96 void remove_qualifiers( ptr_base< Type, ref_t > & p, CV::Qualifiers q ) { 97 if ( ( p->qualifiers .val & q.val) != 0 ) p.get_and_mutate()->qualifiers -= q;97 if ( ( p->qualifiers & q ) != 0 ) p.get_and_mutate()->qualifiers -= q; 98 98 } 99 99 … … 412 412 std::string typeString() const { return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + base->name; } 413 413 bool operator==(const TypeEnvKey & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; } 414 415 414 }; 416 415 -
src/AST/TypeEnvironment.hpp
r428adbc r7f6a7c9 56 56 struct AssertCompare { 57 57 bool operator()( const VariableExpr * d1, const VariableExpr * d2 ) const { 58 auto kind1 = ast::SymbolTable::getSpecialFunctionKind(d1->var->name); 59 auto kind2 = ast::SymbolTable::getSpecialFunctionKind(d2->var->name); 60 // heuristics optimization: force special functions to go last 61 if (kind1 > kind2) return true; 62 else if (kind1 < kind2) return false; 63 58 64 int cmp = d1->var->name.compare( d2->var->name ); 59 65 return cmp < 0 || ( cmp == 0 && d1->result < d2->result ); -
src/AST/Visitor.hpp
r428adbc r7f6a7c9 59 59 virtual const ast::Expr * visit( const ast::UntypedExpr * ) = 0; 60 60 virtual const ast::Expr * visit( const ast::NameExpr * ) = 0; 61 virtual const ast::Expr * visit( const ast::QualifiedNameExpr * ) = 0; 61 62 virtual const ast::Expr * visit( const ast::AddressExpr * ) = 0; 62 63 virtual const ast::Expr * visit( const ast::LabelAddressExpr * ) = 0; -
src/AST/module.mk
r428adbc r7f6a7c9 24 24 AST/Copy.cpp \ 25 25 AST/Copy.hpp \ 26 AST/Create.cpp \ 27 AST/Create.hpp \ 26 28 AST/CVQualifiers.hpp \ 27 29 AST/Decl.cpp \ -
src/CodeGen/CodeGenerator.cc
r428adbc r7f6a7c9 277 277 std::list< Declaration* > &memb = enumDecl->get_members(); 278 278 if (enumDecl->base && ! memb.empty()) { 279 unsigned long long last_val = -1; 279 unsigned long long last_val = -1; // if the first enum value has no explicit initializer, 280 // as other 280 281 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 281 282 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); 282 283 assert( obj ); 283 output << "static const";284 output << genType(enumDecl->base, "", options) << " ";284 output << "static "; 285 output << genType(enumDecl->base, "", options) << " const "; 285 286 output << mangleName( obj ) << " "; 286 287 output << " = "; … … 493 494 assert( false ); 494 495 } // switch 496 } else if( varExpr->get_var()->get_linkage() == LinkageSpec::BuiltinCFA && varExpr->get_var()->get_name() == "intptr" ) { 497 // THIS is a hack to make it a constant until a proper constexpr solution is created 498 output << "((void*)"; 499 std::list< Expression* >::iterator arg = applicationExpr->get_args().begin(); 500 (*arg++)->accept( *visitor ); 501 output << ")"; 495 502 } else { 496 503 varExpr->accept( *visitor ); … … 689 696 output << opInfo->symbol; 690 697 } else { 691 // if (dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())692 // && dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())->baseEnum->base) {693 // output << '(' <<genType(dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())->baseEnum->base, "", options) << ')';694 // }695 698 output << mangleName( variableExpr->get_var() ); 696 699 } // if … … 911 914 } 912 915 916 // QualifiedNameExpr should not reach to CodeGen. 917 // FixQualifiedName Convert QualifiedNameExpr to VariableExpr 918 void CodeGenerator::postvisit( QualifiedNameExpr * expr ) { 919 output << "/* label */" << mangleName(expr->var); 920 } 913 921 914 922 // *** Statements -
src/CodeGen/CodeGenerator.h
r428adbc r7f6a7c9 103 103 void postvisit( DefaultArgExpr * ); 104 104 void postvisit( GenericExpr * ); 105 void postvisit( QualifiedNameExpr *); 105 106 106 107 //*** Statements -
src/Common/CodeLocationTools.cpp
r428adbc r7f6a7c9 137 137 macro(UntypedExpr, Expr) \ 138 138 macro(NameExpr, Expr) \ 139 macro(QualifiedNameExpr, Expr) \ 139 140 macro(AddressExpr, Expr) \ 140 141 macro(LabelAddressExpr, Expr) \ -
src/Common/Eval.cc
r428adbc r7f6a7c9 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 1 08:41:03202213 // Update Count : 11 712 // Last Modified On : Sat Aug 6 12:11:59 2022 13 // Update Count : 119 14 14 // 15 15 … … 217 217 value = arg1.first * arg2.first; 218 218 } else if (fname == "?/?") { 219 value = arg1.first / arg2.first;219 if ( arg2.first ) value = arg1.first / arg2.first; 220 220 } else if (fname == "?%?") { 221 value = arg1.first % arg2.first;221 if ( arg2.first ) value = arg1.first % arg2.first; 222 222 } else if (fname == "?<<?") { 223 223 value = arg1.first << arg2.first; -
src/Common/PassVisitor.h
r428adbc r7f6a7c9 133 133 virtual void visit( NameExpr * nameExpr ) override final; 134 134 virtual void visit( const NameExpr * nameExpr ) override final; 135 virtual void visit ( QualifiedNameExpr * qualifiedNameExpr ) override final; 136 virtual void visit ( const QualifiedNameExpr * qualifiedNameExpr ) override final; 135 137 virtual void visit( CastExpr * castExpr ) override final; 136 138 virtual void visit( const CastExpr * castExpr ) override final; … … 325 327 virtual Expression * mutate( TupleExpr * tupleExpr ) override final; 326 328 virtual Expression * mutate( TupleIndexExpr * tupleExpr ) override final; 327 virtual Expression * mutate( TupleAssignExpr * assignExpr ) override final; 329 virtual Expression * mutate( TupleAssignExpr * assignExpr ) override final; 328 330 virtual Expression * mutate( StmtExpr * stmtExpr ) override final; 329 331 virtual Expression * mutate( UniqueExpr * uniqueExpr ) override final; … … 333 335 virtual Expression * mutate( DefaultArgExpr * argExpr ) override final; 334 336 virtual Expression * mutate( GenericExpr * genExpr ) override final; 337 virtual Expression * mutate( QualifiedNameExpr * qualifiedNameExpr ) override final; 335 338 336 339 virtual Type * mutate( VoidType * basicType ) override final; -
src/Common/PassVisitor.impl.h
r428adbc r7f6a7c9 1927 1927 1928 1928 //-------------------------------------------------------------------------- 1929 // QualifiedNameExpr 1930 template< typename pass_type > 1931 void PassVisitor< pass_type >::visit( QualifiedNameExpr * node ) { 1932 VISIT_START( node ); 1933 1934 indexerScopedAccept( node->result, *this ); 1935 maybeAccept_impl( node->type_decl, *this ); 1936 maybeAccept_impl( node->var, *this ); 1937 1938 VISIT_END( node ); 1939 } 1940 1941 template< typename pass_type > 1942 void PassVisitor< pass_type >::visit( const QualifiedNameExpr * node ) { 1943 VISIT_START( node ); 1944 1945 indexerScopedAccept( node->result, *this ); 1946 maybeAccept_impl( node->type_decl, *this ); 1947 maybeAccept_impl( node->var, *this ); 1948 1949 VISIT_END( node ); 1950 } 1951 1952 template< typename pass_type > 1953 Expression * PassVisitor< pass_type >::mutate( QualifiedNameExpr * node ) { 1954 MUTATE_START( node ); 1955 1956 indexerScopedMutate( node->env , *this ); 1957 indexerScopedMutate( node->result, *this ); 1958 maybeMutate_impl( node->type_decl, *this ); 1959 maybeAccept_impl( node->var, *this ); 1960 1961 MUTATE_END( Expression, node ); 1962 } 1963 1964 //-------------------------------------------------------------------------- 1929 1965 // CastExpr 1930 1966 template< typename pass_type > -
src/Common/ScopedMap.h
r428adbc r7f6a7c9 10 10 // Created On : Wed Dec 2 11:37:00 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 21 15:22:40 201813 // Update Count : 312 // Last Modified On : Tue Feb 15 08:41:28 2022 13 // Update Count : 5 14 14 // 15 15 … … 36 36 37 37 template<typename N> 38 Scope(N && n) : map(), note(std::forward<N>(n)) {}38 Scope(N && n) : map(), note(std::forward<N>(n)) {} 39 39 40 40 Scope() = default; 41 Scope(const Scope &) = default;42 Scope(Scope &&) = default;43 Scope & operator= (const Scope&) = default;44 Scope & operator= (Scope&&) = default;41 Scope(const Scope &) = default; 42 Scope(Scope &&) = default; 43 Scope & operator= (const Scope &) = default; 44 Scope & operator= (Scope &&) = default; 45 45 }; 46 46 typedef std::vector< Scope > ScopeList; … … 58 58 typedef typename MapType::const_pointer const_pointer; 59 59 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, 61 value_type > { 60 class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > { 62 61 friend class ScopedMap; 63 62 friend class const_iterator; … … 72 71 73 72 /// Increments on invalid 74 iterator & next_valid() {73 iterator & next_valid() { 75 74 if ( ! is_valid() ) { ++(*this); } 76 75 return *this; … … 78 77 79 78 /// Decrements on invalid 80 iterator & prev_valid() {79 iterator & prev_valid() { 81 80 if ( ! is_valid() ) { --(*this); } 82 81 return *this; 83 82 } 84 83 85 iterator(scope_list & _scopes, const wrapped_iterator &_it, size_type inLevel)84 iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel) 86 85 : scopes(&_scopes), it(_it), level(inLevel) {} 87 86 public: 88 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}89 iterator & operator= (const iterator &that) {87 iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 88 iterator & operator= (const iterator & that) { 90 89 scopes = that.scopes; level = that.level; it = that.it; 91 90 return *this; … … 95 94 pointer operator-> () const { return it.operator->(); } 96 95 97 iterator & operator++ () {96 iterator & operator++ () { 98 97 if ( it == (*scopes)[level].map.end() ) { 99 98 if ( level == 0 ) return *this; … … 107 106 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 108 107 109 iterator & operator-- () {108 iterator & operator-- () { 110 109 // may fail if this is the begin iterator; allowed by STL spec 111 110 if ( it == (*scopes)[level].map.begin() ) { … … 118 117 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 119 118 120 bool operator== (const iterator & that) const {119 bool operator== (const iterator & that) const { 121 120 return scopes == that.scopes && level == that.level && it == that.it; 122 121 } 123 bool operator!= (const iterator & that) const { return !( *this == that ); }122 bool operator!= (const iterator & that) const { return !( *this == that ); } 124 123 125 124 size_type get_level() const { return level; } 126 125 127 Note & get_note() { return (*scopes)[level].note; }128 const Note & get_note() const { return (*scopes)[level].note; }126 Note & get_note() { return (*scopes)[level].note; } 127 const Note & get_note() const { return (*scopes)[level].note; } 129 128 130 129 private: … … 148 147 149 148 /// Increments on invalid 150 const_iterator & next_valid() {149 const_iterator & next_valid() { 151 150 if ( ! is_valid() ) { ++(*this); } 152 151 return *this; … … 154 153 155 154 /// Decrements on invalid 156 const_iterator & prev_valid() {155 const_iterator & prev_valid() { 157 156 if ( ! is_valid() ) { --(*this); } 158 157 return *this; 159 158 } 160 159 161 const_iterator(scope_list const & _scopes, const wrapped_const_iterator &_it, size_type inLevel)160 const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel) 162 161 : scopes(&_scopes), it(_it), level(inLevel) {} 163 162 public: 164 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}165 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}166 const_iterator & operator= (const iterator &that) {163 const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 164 const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {} 165 const_iterator & operator= (const iterator & that) { 167 166 scopes = that.scopes; level = that.level; it = that.it; 168 167 return *this; 169 168 } 170 const_iterator & operator= (const const_iterator &that) {169 const_iterator & operator= (const const_iterator & that) { 171 170 scopes = that.scopes; level = that.level; it = that.it; 172 171 return *this; … … 176 175 const_pointer operator-> () { return it.operator->(); } 177 176 178 const_iterator & operator++ () {177 const_iterator & operator++ () { 179 178 if ( it == (*scopes)[level].map.end() ) { 180 179 if ( level == 0 ) return *this; … … 188 187 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 189 188 190 const_iterator & operator-- () {189 const_iterator & operator-- () { 191 190 // may fail if this is the begin iterator; allowed by STL spec 192 191 if ( it == (*scopes)[level].map.begin() ) { … … 199 198 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 200 199 201 bool operator== (const const_iterator & that) const {200 bool operator== (const const_iterator & that) const { 202 201 return scopes == that.scopes && level == that.level && it == that.it; 203 202 } 204 bool operator!= (const const_iterator & that) const { return !( *this == that ); }203 bool operator!= (const const_iterator & that) const { return !( *this == that ); } 205 204 206 205 size_type get_level() const { return level; } 207 206 208 const Note & get_note() const { return (*scopes)[level].note; }207 const Note & get_note() const { return (*scopes)[level].note; } 209 208 210 209 private: … … 221 220 // Starts a new scope with the given note 222 221 template<typename N> 223 void beginScope( N && n ) {222 void beginScope( N && n ) { 224 223 scopes.emplace_back( std::forward<N>(n) ); 225 224 } … … 236 235 /// Constructs with a given note on the outermost scope 237 236 template<typename N> 238 ScopedMap( N && n ) : scopes() { beginScope(std::forward<N>(n)); }237 ScopedMap( N && n ) : scopes() { beginScope(std::forward<N>(n)); } 239 238 240 239 iterator begin() { return iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); } … … 249 248 250 249 /// Gets the note at the given scope 251 Note & getNote() { return scopes.back().note; }252 const Note & getNote() const { return scopes.back().note; }253 Note & getNote( size_type i ) { return scopes[i].note; }254 const Note & getNote( size_type i ) const { return scopes[i].note; }250 Note & getNote() { return scopes.back().note; } 251 const Note & getNote() const { return scopes.back().note; } 252 Note & getNote( size_type i ) { return scopes[i].note; } 253 const Note & getNote( size_type i ) const { return scopes[i].note; } 255 254 256 255 /// Finds the given key in the outermost scope it occurs; returns end() for none such 257 iterator find( const Key & key ) {256 iterator find( const Key & key ) { 258 257 for ( size_type i = scopes.size() - 1; ; --i ) { 259 258 typename MapType::iterator val = scopes[i].map.find( key ); … … 263 262 return end(); 264 263 } 265 const_iterator find( const Key & key ) const {264 const_iterator find( const Key & key ) const { 266 265 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->find( key ) ); 267 266 } 268 267 269 268 /// Finds the given key in the provided scope; returns end() for none such 270 iterator findAt( size_type scope, const Key & key ) {269 iterator findAt( size_type scope, const Key & key ) { 271 270 typename MapType::iterator val = scopes[scope].map.find( key ); 272 271 if ( val != scopes[scope].map.end() ) return iterator( scopes, val, scope ); 273 272 return end(); 274 273 } 275 const_iterator findAt( size_type scope, const Key & key ) const {274 const_iterator findAt( size_type scope, const Key & key ) const { 276 275 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findAt( scope, key ) ); 277 276 } 278 277 279 278 /// Finds the given key in the outermost scope inside the given scope where it occurs 280 iterator findNext( const_iterator & it, const Key &key ) {279 iterator findNext( const_iterator & it, const Key & key ) { 281 280 if ( it.level == 0 ) return end(); 282 281 for ( size_type i = it.level - 1; ; --i ) { … … 287 286 return end(); 288 287 } 289 const_iterator findNext( const_iterator & it, const Key &key ) const {288 const_iterator findNext( const_iterator & it, const Key & key ) const { 290 289 return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findNext( it, key ) ); 291 290 } … … 293 292 /// Inserts the given key-value pair into the outermost scope 294 293 template< typename value_type_t > 295 std::pair< iterator, bool > insert( value_type_t && value ) {294 std::pair< iterator, bool > insert( value_type_t && value ) { 296 295 std::pair< typename MapType::iterator, bool > res = scopes.back().map.insert( std::forward<value_type_t>( value ) ); 297 296 return std::make_pair( iterator(scopes, std::move( res.first ), scopes.size()-1), std::move( res.second ) ); … … 299 298 300 299 template< typename value_type_t > 301 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {302 MapType & scope = (*at.scopes)[ at.level ].map;300 std::pair< iterator, bool > insert( iterator at, value_type_t && value ) { 301 MapType & scope = (*at.scopes)[ at.level ].map; 303 302 std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) ); 304 303 return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) ); … … 306 305 307 306 template< typename value_t > 308 std::pair< iterator, bool > insert( const Key & key, value_t&& value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); }307 std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); } 309 308 310 309 template< typename value_type_t > 311 std::pair< iterator, bool > insertAt( size_type scope, value_type_t && value ) {310 std::pair< iterator, bool > insertAt( size_type scope, value_type_t && value ) { 312 311 std::pair< typename MapType::iterator, bool > res = scopes.at(scope).map.insert( std::forward<value_type_t>( value ) ); 313 312 return std::make_pair( iterator(scopes, std::move( res.first ), scope), std::move( res.second ) ); … … 315 314 316 315 template< typename value_t > 317 std::pair< iterator, bool > insertAt( size_type scope, const Key & key, value_t&& value ) {316 std::pair< iterator, bool > insertAt( size_type scope, const Key & key, value_t && value ) { 318 317 return insertAt( scope, std::make_pair( key, std::forward<value_t>( value ) ) ); 319 318 } 320 319 321 Value & operator[] ( const Key &key ) {320 Value & operator[] ( const Key & key ) { 322 321 iterator slot = find( key ); 323 322 if ( slot != end() ) return slot->second; … … 326 325 327 326 iterator erase( iterator pos ) { 328 MapType & scope = (*pos.scopes)[ pos.level ].map;329 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it );327 MapType & scope = (*pos.scopes)[ pos.level ].map; 328 const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it ); 330 329 iterator it( *pos.scopes, new_it, pos.level ); 331 330 return it.next_valid(); 332 331 } 333 332 334 size_type count( const Key & key ) const {333 size_type count( const Key & key ) const { 335 334 size_type c = 0; 336 335 auto it = find( key ); … … 344 343 return c; 345 344 } 346 347 345 }; 348 346 -
src/Common/utility.h
r428adbc r7f6a7c9 322 322 323 323 ValueGuardPtr(T * inRef) : old( inRef ? *inRef : T() ), ref(inRef) {} 324 ValueGuardPtr(const ValueGuardPtr& other) = delete; 325 ValueGuardPtr(ValueGuardPtr&& other) : old(other.old), ref(other.ref) { other.ref = nullptr; } 324 326 ~ValueGuardPtr() { if( ref ) *ref = old; } 325 327 }; -
src/CompilationState.cc
r428adbc r7f6a7c9 31 31 genproto = false, 32 32 deterministic_output = false, 33 useNewAST = CFA_USE_NEW_AST,33 useNewAST = true, 34 34 nomainp = false, 35 35 parsep = false, -
src/Concurrency/Keywords.cc
r428adbc r7f6a7c9 508 508 ObjectDecl * vtable_object = Virtual::makeVtableForward( 509 509 "_default_vtable_object_declaration", 510 vtable_decl->makeInst( move( poly_args ) ) );510 vtable_decl->makeInst( std::move( poly_args ) ) ); 511 511 declsToAddBefore.push_back( vtable_object ); 512 512 declsToAddBefore.push_back( … … 681 681 void lock (monitor_t & this) { 682 682 lock(get_monitor(this)); 683 } 683 } 684 684 */ 685 685 FunctionDecl * lock_decl = new FunctionDecl( … … 700 700 CompoundStmt * lock_statement = new CompoundStmt(); 701 701 lock_statement->push_back( 702 new ExprStmt( 702 new ExprStmt( 703 703 new UntypedExpr ( 704 704 new NameExpr( "lock" ), … … 716 716 void unlock (monitor_t & this) { 717 717 unlock(get_monitor(this)); 718 } 718 } 719 719 */ 720 720 FunctionDecl * unlock_decl = new FunctionDecl( … … 736 736 737 737 unlock_statement->push_back( 738 new ExprStmt( 738 new ExprStmt( 739 739 new UntypedExpr( 740 740 new NameExpr( "unlock" ), … … 746 746 ); 747 747 unlock_decl->set_statements( unlock_statement ); 748 748 749 749 // pushes routines to declsToAddAfter to add at a later time 750 750 declsToAddAfter.push_back( lock_decl ); … … 1054 1054 assert( !thread_guard_decl ); 1055 1055 thread_guard_decl = decl; 1056 } 1056 } 1057 1057 else if ( decl->name == "__mutex_stmt_lock_guard" && decl->body ) { 1058 1058 assert( !lock_guard_decl ); … … 1206 1206 new NameExpr( "__get_mutexstmt_lock_type" ), 1207 1207 { args.front()->clone() } 1208 ) 1208 ) 1209 1209 ) 1210 1210 ), … … 1225 1225 1226 1226 StructInstType * lock_guard_struct = new StructInstType( noQualifiers, lock_guard_decl ); 1227 TypeExpr * lock_type_expr = new TypeExpr( 1227 TypeExpr * lock_type_expr = new TypeExpr( 1228 1228 new TypeofType( noQualifiers, new UntypedExpr( 1229 1229 new NameExpr( "__get_mutexstmt_lock_type" ), 1230 1230 { args.front()->clone() } 1231 ) 1232 ) 1231 ) 1232 ) 1233 1233 ); 1234 1234 -
src/Concurrency/Waitfor.cc
r428adbc r7f6a7c9 402 402 403 403 clause.target.function = nullptr; 404 clause.target.arguments. empty();404 clause.target.arguments.clear(); 405 405 clause.condition = nullptr; 406 406 } -
src/Concurrency/WaitforNew.cpp
r428adbc r7f6a7c9 101 101 namespace { 102 102 103 class GenerateWaitForCore :103 class GenerateWaitForCore final : 104 104 public ast::WithSymbolTable, public ast::WithConstTranslationUnit { 105 105 const ast::FunctionDecl * decl_waitfor = nullptr; -
src/ControlStruct/ExceptTranslateNew.cpp
r428adbc r7f6a7c9 32 32 } 33 33 34 class TranslateThrowsCore : public ast::WithGuards {34 class TranslateThrowsCore final : public ast::WithGuards { 35 35 const ast::ObjectDecl * terminateHandlerExcept; 36 36 enum Context { NoHandler, TerHandler, ResHandler } currentContext; … … 136 136 137 137 138 class TryMutatorCore {138 class TryMutatorCore final { 139 139 // The built in types used in translation. 140 140 const ast::StructDecl * except_decl; -
src/ControlStruct/LabelFixer.cc
r428adbc r7f6a7c9 119 119 120 120 // Builds a table that maps a label to its defining statement. 121 std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ){121 std::map<Label, Statement * > * LabelFixer::resolveJumps() { 122 122 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 123 123 for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { -
src/ControlStruct/LabelFixer.h
r428adbc r7f6a7c9 33 33 LabelFixer( LabelGenerator *gen = 0 ); 34 34 35 std::map < Label, Statement * > *resolveJumps() throw ( SemanticErrorException );35 std::map < Label, Statement * > *resolveJumps(); 36 36 37 37 // Declarations -
src/ControlStruct/LabelGeneratorNew.cpp
r428adbc r7f6a7c9 14 14 // 15 15 16 using namespace std;17 18 16 #include "LabelGeneratorNew.hpp" 19 17 … … 21 19 #include "AST/Label.hpp" 22 20 #include "AST/Stmt.hpp" 21 22 using namespace std; 23 23 using namespace ast; 24 24 -
src/ControlStruct/MLEMutator.cc
r428adbc r7f6a7c9 141 141 142 142 143 Statement *MultiLevelExitMutator::postmutate( BranchStmt *branchStmt ) 144 throw ( SemanticErrorException ) { 143 Statement *MultiLevelExitMutator::postmutate( BranchStmt *branchStmt ) { 145 144 std::string originalTarget = branchStmt->originalTarget; 146 145 -
src/ControlStruct/MLEMutator.h
r428adbc r7f6a7c9 41 41 42 42 void premutate( CompoundStmt *cmpndStmt ); 43 Statement * postmutate( BranchStmt *branchStmt ) throw ( SemanticErrorException );43 Statement * postmutate( BranchStmt *branchStmt ); 44 44 void premutate( WhileDoStmt *whileDoStmt ); 45 45 Statement * postmutate( WhileDoStmt *whileDoStmt ); -
src/ControlStruct/MultiLevelExit.cpp
r428adbc r7f6a7c9 356 356 vec.emplace_back( nullptr ); 357 357 for ( size_t i = vec.size() - 1 ; 0 < i ; --i ) { 358 vec[ i ] = move( vec[ i - 1 ] );358 vec[ i ] = std::move( vec[ i - 1 ] ); 359 359 } 360 360 vec[ 0 ] = element; … … 511 511 512 512 void MultiLevelExitCore::previsit( const FinallyClause * ) { 513 GuardAction([this, old = move( enclosing_control_structures)](){ enclosing_control_structures =move(old); });513 GuardAction([this, old = std::move( enclosing_control_structures)](){ enclosing_control_structures = std::move(old); }); 514 514 enclosing_control_structures = vector<Entry>(); 515 515 GuardValue( inFinally ) = true; -
src/GenPoly/GenPoly.cc
r428adbc r7f6a7c9 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jun 29 21:45:53 201613 // Update Count : 1 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 14 9:24:00 2022 13 // Update Count : 15 14 14 // 15 15 … … 83 83 } 84 84 85 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) { 86 for ( ast::ptr<ast::Expr> const & param : params ) { 87 auto paramType = param.as<ast::TypeExpr>(); 88 assertf( paramType, "Aggregate parameters should be type expressions." ); 89 if ( isDynType( paramType->type, tyVars, typeSubs ) ) { 90 return true; 91 } 92 } 93 return false; 94 } 95 85 96 /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present 86 97 bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) { … … 198 209 } 199 210 return 0; 211 } 212 213 const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) { 214 type = replaceTypeInst( type, typeSubs ); 215 216 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) { 217 auto var = tyVars.find( inst->name ); 218 if ( var != tyVars.end() && var->second.isComplete ) { 219 return inst; 220 } 221 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) { 222 if ( hasDynParams( inst->params, tyVars, typeSubs ) ) { 223 return inst; 224 } 225 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) { 226 if ( hasDynParams( inst->params, tyVars, typeSubs ) ) { 227 return inst; 228 } 229 } 230 return nullptr; 200 231 } 201 232 … … 378 409 inline D* as( B* p ) { return reinterpret_cast<D*>(p); } 379 410 411 template<typename D, typename B> 412 inline D const * as( B const * p ) { 413 return reinterpret_cast<D const *>( p ); 414 } 415 380 416 /// Flattens a declaration list 381 417 template<typename Output> … … 391 427 for ( Type* ty : src ) { 392 428 ResolvExpr::flatten( ty, out ); 429 } 430 } 431 432 void flattenList( vector<ast::ptr<ast::Type>> const & src, 433 vector<ast::ptr<ast::Type>> & out ) { 434 for ( auto const & type : src ) { 435 ResolvExpr::flatten( type, out ); 393 436 } 394 437 } … … 409 452 // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue; 410 453 if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false; 454 } 455 456 return true; 457 } 458 459 bool paramListsPolyCompatible( 460 std::vector<ast::ptr<ast::Expr>> const & lparams, 461 std::vector<ast::ptr<ast::Expr>> const & rparams ) { 462 if ( lparams.size() != rparams.size() ) { 463 return false; 464 } 465 466 for ( auto lparam = lparams.begin(), rparam = rparams.begin() ; 467 lparam != lparams.end() ; ++lparam, ++rparam ) { 468 ast::TypeExpr const * lexpr = lparam->as<ast::TypeExpr>(); 469 assertf( lexpr, "Aggregate parameters should be type expressions" ); 470 ast::TypeExpr const * rexpr = rparam->as<ast::TypeExpr>(); 471 assertf( rexpr, "Aggregate parameters should be type expressions" ); 472 473 // xxx - might need to let VoidType be a wildcard here too; could have some voids 474 // stuffed in for dtype-statics. 475 // if ( is<VoidType>( lexpr->type() ) || is<VoidType>( bparam->get_type() ) ) continue; 476 if ( !typesPolyCompatible( lexpr->type, rexpr->type ) ) { 477 return false; 478 } 411 479 } 412 480 … … 505 573 } 506 574 575 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) { 576 type_index const lid = typeid(*lhs); 577 578 // Polymorphic types always match: 579 if ( type_index(typeid(ast::TypeInstType)) == lid ) return true; 580 581 type_index const rid = typeid(*rhs); 582 if ( type_index(typeid(ast::TypeInstType)) == rid ) return true; 583 584 // All other types only match if they are the same type: 585 if ( lid != rid ) return false; 586 587 // So remaining types can be examined case by case. 588 // Recurse through type structure (conditions borrowed from Unify.cc). 589 590 if ( type_index(typeid(ast::BasicType)) == lid ) { 591 return as<ast::BasicType>(lhs)->kind == as<ast::BasicType>(rhs)->kind; 592 } else if ( type_index(typeid(ast::PointerType)) == lid ) { 593 ast::PointerType const * l = as<ast::PointerType>(lhs); 594 ast::PointerType const * r = as<ast::PointerType>(rhs); 595 596 // void pointers should match any other pointer type. 597 return is<ast::VoidType>( l->base.get() ) 598 || is<ast::VoidType>( r->base.get() ) 599 || typesPolyCompatible( l->base.get(), r->base.get() ); 600 } else if ( type_index(typeid(ast::ReferenceType)) == lid ) { 601 ast::ReferenceType const * l = as<ast::ReferenceType>(lhs); 602 ast::ReferenceType const * r = as<ast::ReferenceType>(rhs); 603 604 // void references should match any other reference type. 605 return is<ast::VoidType>( l->base.get() ) 606 || is<ast::VoidType>( r->base.get() ) 607 || typesPolyCompatible( l->base.get(), r->base.get() ); 608 } else if ( type_index(typeid(ast::ArrayType)) == lid ) { 609 ast::ArrayType const * l = as<ast::ArrayType>(lhs); 610 ast::ArrayType const * r = as<ast::ArrayType>(rhs); 611 612 if ( l->isVarLen ) { 613 if ( !r->isVarLen ) return false; 614 } else { 615 if ( r->isVarLen ) return false; 616 617 auto lc = l->dimension.as<ast::ConstantExpr>(); 618 auto rc = r->dimension.as<ast::ConstantExpr>(); 619 if ( lc && rc && lc->intValue() != rc->intValue() ) { 620 return false; 621 } 622 } 623 624 return typesPolyCompatible( l->base.get(), r->base.get() ); 625 } else if ( type_index(typeid(ast::FunctionType)) == lid ) { 626 ast::FunctionType const * l = as<ast::FunctionType>(lhs); 627 ast::FunctionType const * r = as<ast::FunctionType>(rhs); 628 629 std::vector<ast::ptr<ast::Type>> lparams, rparams; 630 flattenList( l->params, lparams ); 631 flattenList( r->params, rparams ); 632 if ( lparams.size() != rparams.size() ) return false; 633 for ( unsigned i = 0; i < lparams.size(); ++i ) { 634 if ( !typesPolyCompatible( lparams[i], rparams[i] ) ) return false; 635 } 636 637 std::vector<ast::ptr<ast::Type>> lrets, rrets; 638 flattenList( l->returns, lrets ); 639 flattenList( r->returns, rrets ); 640 if ( lrets.size() != rrets.size() ) return false; 641 for ( unsigned i = 0; i < lrets.size(); ++i ) { 642 if ( !typesPolyCompatible( lrets[i], rrets[i] ) ) return false; 643 } 644 return true; 645 } else if ( type_index(typeid(ast::StructInstType)) == lid ) { 646 ast::StructInstType const * l = as<ast::StructInstType>(lhs); 647 ast::StructInstType const * r = as<ast::StructInstType>(rhs); 648 649 if ( l->name != r->name ) return false; 650 return paramListsPolyCompatible( l->params, r->params ); 651 } else if ( type_index(typeid(ast::UnionInstType)) == lid ) { 652 ast::UnionInstType const * l = as<ast::UnionInstType>(lhs); 653 ast::UnionInstType const * r = as<ast::UnionInstType>(rhs); 654 655 if ( l->name != r->name ) return false; 656 return paramListsPolyCompatible( l->params, r->params ); 657 } else if ( type_index(typeid(ast::EnumInstType)) == lid ) { 658 ast::EnumInstType const * l = as<ast::EnumInstType>(lhs); 659 ast::EnumInstType const * r = as<ast::EnumInstType>(rhs); 660 661 return l->name == r->name; 662 } else if ( type_index(typeid(ast::TraitInstType)) == lid ) { 663 ast::TraitInstType const * l = as<ast::TraitInstType>(lhs); 664 ast::TraitInstType const * r = as<ast::TraitInstType>(rhs); 665 666 return l->name == r->name; 667 } else if ( type_index(typeid(ast::TupleType)) == lid ) { 668 ast::TupleType const * l = as<ast::TupleType>(lhs); 669 ast::TupleType const * r = as<ast::TupleType>(rhs); 670 671 std::vector<ast::ptr<ast::Type>> ltypes, rtypes; 672 flattenList( l->types, ( ltypes ) ); 673 flattenList( r->types, ( rtypes ) ); 674 if ( ltypes.size() != rtypes.size() ) return false; 675 676 for ( unsigned i = 0 ; i < ltypes.size() ; ++i ) { 677 if ( !typesPolyCompatible( ltypes[i], rtypes[i] ) ) return false; 678 } 679 return true; 680 // The remaining types (VoidType, VarArgsType, ZeroType & OneType) 681 // have no variation so will always be equal. 682 } else { 683 return true; 684 } 685 } 686 507 687 namespace { 508 688 // temporary hack to avoid re-implementing anything related to TyVarMap -
src/GenPoly/GenPoly.h
r428adbc r7f6a7c9 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:22:57 201713 // Update Count : 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:03:00 2022 13 // Update Count : 8 14 14 // 15 15 … … 27 27 namespace GenPoly { 28 28 29 // TODO Via some tricks this works for ast::TypeDecl::Data as well. 29 30 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 31 30 32 /// Replaces a TypeInstType by its referrent in the environment, if applicable 31 33 Type* replaceTypeInst( Type* type, const TypeSubstitution* env ); … … 41 43 /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided 42 44 ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 45 const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs = 0 ); 43 46 44 47 /// true iff function has dynamic-layout return type under the given type variable map … … 83 86 /// true iff types are structurally identical, where TypeInstType's match any type. 84 87 bool typesPolyCompatible( Type *aty, Type *bty ); 88 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ); 85 89 86 90 /// true if arg requires boxing given exprTyVars -
src/GenPoly/InstantiateGeneric.h
r428adbc r7f6a7c9 19 19 20 20 class Declaration; 21 namespace ast { 22 class TranslationUnit; 23 } 21 24 22 25 namespace GenPoly { 23 /// Replaces all generic types that have static layout with concrete instantiations. 24 /// Types with concrete values for otype parameters will be template-expanded, while 25 /// dtype and ftype parameters will be replaced by the appropriate void type. 26 void instantiateGeneric( std::list< Declaration* > &translationUnit ); 26 /// Replaces all generic types that have static layout with concrete 27 /// instantiations. Types with concrete values for otype parameters will be 28 /// template-expanded, while dtype and ftype parameters will be replaced by 29 /// the appropriate void type. 30 void instantiateGeneric( std::list< Declaration* > &translationUnit ); 31 void instantiateGeneric( ast::TranslationUnit & translationUnit ); 27 32 } // namespace GenPoly 28 33 -
src/GenPoly/Lvalue2.cc
r428adbc r7f6a7c9 23 23 } 24 24 25 26 25 } -
src/GenPoly/ScrubTyVars.cc
r428adbc r7f6a7c9 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 16 15:44:27 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:10:00 2022 13 // Update Count : 4 14 14 // 15 15 16 16 #include <utility> // for pair 17 17 18 #include "AST/Pass.hpp" 18 19 #include "GenPoly.h" // for mangleType, TyVarMap, alignof... 19 20 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 20 21 #include "ScrubTyVars.h" 22 #include "SymTab/Mangler.h" // for mangle, typeMode 21 23 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Typ... 22 24 #include "SynTree/Expression.h" // for Expression (ptr only), NameExpr … … 112 114 return pointer; 113 115 } 116 117 namespace { 118 119 enum class ScrubMode { 120 FromMap, 121 DynamicFromMap, 122 All, 123 }; 124 125 struct ScrubTypeVars : 126 public ast::WithGuards, 127 public ast::WithShortCircuiting, 128 public ast::WithVisitorRef<ScrubTypeVars> { 129 130 ScrubTypeVars( ScrubMode m, TyVarMap const * tv ) : 131 mode ( m ), typeVars( tv ) {} 132 133 void previsit( ast::TypeInstType const * ) { visit_children = false; } 134 void previsit( ast::StructInstType const * ) { visit_children = false; } 135 void previsit( ast::UnionInstType const * ) { visit_children = false; } 136 void previsit( ast::SizeofExpr const * expr ) { primeBaseScrub( expr->type ); } 137 void previsit( ast::AlignofExpr const * expr ) { primeBaseScrub( expr->type ); } 138 void previsit( ast::PointerType const * type ) { primeBaseScrub( type->base ); } 139 140 ast::Type const * postvisit( ast::TypeInstType const * type ); 141 ast::Type const * postvisit( ast::StructInstType const * type ); 142 ast::Type const * postvisit( ast::UnionInstType const * type ); 143 ast::Expr const * postvisit( ast::SizeofExpr const * expr ); 144 ast::Expr const * postvisit( ast::AlignofExpr const * expr ); 145 ast::Type const * postvisit( ast::PointerType const * type ); 146 147 private: 148 ScrubMode const mode; 149 /// Type varriables to scrub. 150 TyVarMap const * const typeVars; 151 /// Value cached by primeBaseScrub. 152 ast::Type const * dynType = nullptr; 153 154 /// Returns the type if it should be scrubbed, nullptr otherwise. 155 ast::Type const * shouldScrub( ast::Type const * type ) { 156 switch ( mode ) { 157 case ScrubMode::FromMap: 158 return isPolyType( type, *typeVars ); 159 case ScrubMode::DynamicFromMap: 160 return isDynType( type, *typeVars ); 161 case ScrubMode::All: 162 return isPolyType( type ); 163 default: 164 assertf( false, "Invalid ScrubMode in shouldScrub." ); 165 throw; 166 } 167 } 168 169 void primeBaseScrub( ast::Type const * type ) { 170 // Need to determine whether type needs to be scrubbed to 171 // determine whether automatic recursion is necessary. 172 if ( ast::Type const * t = shouldScrub( type ) ) { 173 visit_children = false; 174 GuardValue( dynType ) = t; 175 } 176 } 177 178 ast::Type const * postvisitAggregateType( 179 ast::BaseInstType const * type ) { 180 if ( !shouldScrub( type ) ) return type; 181 return new ast::PointerType( new ast::VoidType( type->qualifiers ) ); 182 } 183 }; 184 185 ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) { 186 // This implies that mode == ScrubMode::All. 187 if ( !typeVars ) { 188 if ( ast::TypeDecl::Ftype == type->kind ) { 189 return new ast::PointerType( 190 new ast::FunctionType( ast::FixedArgs ) ); 191 } else { 192 return new ast::PointerType( 193 new ast::VoidType( type->qualifiers ) ); 194 } 195 } 196 197 auto typeVar = typeVars->find( type->name ); 198 if ( typeVar == typeVars->end() ) { 199 return type; 200 } 201 202 switch ( typeVar->second.kind ) { 203 case ::TypeDecl::Dtype: 204 case ::TypeDecl::Ttype: 205 return new ast::PointerType( 206 new ast::VoidType( type->qualifiers ) ); 207 case ::TypeDecl::Ftype: 208 return new ast::PointerType( 209 new ast::FunctionType( ast::VariableArgs ) ); 210 default: 211 assertf( false, 212 "Unhandled type variable kind: %d", typeVar->second.kind ); 213 throw; // Just in case the assert is removed, stop here. 214 } 215 } 216 217 ast::Type const * ScrubTypeVars::postvisit( ast::StructInstType const * type ) { 218 return postvisitAggregateType( type ); 219 } 220 221 ast::Type const * ScrubTypeVars::postvisit( ast::UnionInstType const * type ) { 222 return postvisitAggregateType( type ); 223 } 224 225 ast::Expr const * ScrubTypeVars::postvisit( ast::SizeofExpr const * expr ) { 226 // sizeof( T ) becomes the _sizeof_T parameter. 227 if ( dynType ) { 228 return new ast::NameExpr( expr->location, 229 sizeofName( Mangle::mangle( dynType, Mangle::typeMode() ) ) ); 230 } else { 231 return expr; 232 } 233 } 234 235 ast::Expr const * ScrubTypeVars::postvisit( ast::AlignofExpr const * expr ) { 236 // alignof( T ) becomes the _alignof_T parameter. 237 if ( dynType ) { 238 return new ast::NameExpr( expr->location, 239 alignofName( Mangle::mangle( dynType, Mangle::typeMode() ) ) ); 240 } else { 241 return expr; 242 } 243 } 244 245 ast::Type const * ScrubTypeVars::postvisit( ast::PointerType const * type ) { 246 if ( dynType ) { 247 ast::Type * ret = ast::mutate( dynType->accept( *visitor ) ); 248 ret->qualifiers |= type->qualifiers; 249 return ret; 250 } else { 251 return type; 252 } 253 } 254 255 const ast::Node * scrubTypeVarsBase( 256 const ast::Node * target, 257 ScrubMode mode, const TyVarMap * typeVars ) { 258 if ( ScrubMode::All == mode ) { 259 assert( nullptr == typeVars ); 260 } else { 261 assert( nullptr != typeVars ); 262 } 263 ast::Pass<ScrubTypeVars> visitor( mode, typeVars ); 264 return target->accept( visitor ); 265 } 266 267 } // namespace 268 269 template<> 270 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ) { 271 return scrubTypeVarsBase( target, ScrubMode::All, nullptr ); 272 } 273 114 274 } // namespace GenPoly 115 275 -
src/GenPoly/ScrubTyVars.h
r428adbc r7f6a7c9 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:21:47 201713 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 14:14:00 2022 13 // Update Count : 3 14 14 // 15 15 … … 18 18 #include <cassert> // for assert 19 19 20 #include "AST/Fwd.hpp" // for Node 20 21 #include "Common/PassVisitor.h" 21 22 #include "GenPoly.h" // for TyVarMap, isPolyType, isDynType … … 108 109 } 109 110 111 /// For all polymorphic types, replaces generic types, with the appropriate 112 /// void type, and sizeof/alignof expressions with the proper variable. 113 template<typename node_t> 114 node_t const * scrubAllTypeVars( node_t const * target ) { 115 return strict_dynamic_cast<node_t const *>( scrubAllTypeVars<ast::Node>( target ) ); 116 } 117 118 template<> 119 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ); 120 110 121 } // namespace GenPoly 111 122 -
src/GenPoly/SpecializeNew.cpp
r428adbc r7f6a7c9 240 240 } 241 241 242 namespace { 243 struct TypeInstFixer : public ast::WithShortCircuiting { 244 std::map<const ast::TypeDecl *, std::pair<int, int>> typeMap; 245 246 void previsit(const ast::TypeDecl *) { visit_children = false; } 247 const ast::TypeInstType * postvisit(const ast::TypeInstType * typeInst) { 248 if (typeMap.count(typeInst->base)) { 249 ast::TypeInstType * newInst = mutate(typeInst); 250 auto const & pair = typeMap[typeInst->base]; 251 newInst->expr_id = pair.first; 252 newInst->formal_usage = pair.second; 253 return newInst; 254 } 255 return typeInst; 256 } 257 }; 258 } 242 struct TypeInstFixer final : public ast::WithShortCircuiting { 243 std::map<const ast::TypeDecl *, std::pair<int, int>> typeMap; 244 245 void previsit(const ast::TypeDecl *) { visit_children = false; } 246 const ast::TypeInstType * postvisit(const ast::TypeInstType * typeInst) { 247 if (typeMap.count(typeInst->base)) { 248 ast::TypeInstType * newInst = mutate(typeInst); 249 auto const & pair = typeMap[typeInst->base]; 250 newInst->expr_id = pair.first; 251 newInst->formal_usage = pair.second; 252 return newInst; 253 } 254 return typeInst; 255 } 256 }; 259 257 260 258 const ast::Expr * SpecializeCore::createThunkFunction( -
src/GenPoly/module.mk
r428adbc r7f6a7c9 27 27 GenPoly/FindFunction.cc \ 28 28 GenPoly/FindFunction.h \ 29 GenPoly/InstantiateGenericNew.cpp \ 29 30 GenPoly/InstantiateGeneric.cc \ 30 31 GenPoly/InstantiateGeneric.h \ -
src/InitTweak/InitTweak.cc
r428adbc r7f6a7c9 1241 1241 static const char * const tlsd_section = ".tdata" ASM_COMMENT; 1242 1242 void addDataSectionAttribute( ObjectDecl * objDecl ) { 1243 const bool is_tls = objDecl->get_storageClasses().is_threadlocal ;1243 const bool is_tls = objDecl->get_storageClasses().is_threadlocal_any(); 1244 1244 const char * section = is_tls ? tlsd_section : data_section; 1245 1245 objDecl->attributes.push_back(new Attribute("section", { … … 1249 1249 1250 1250 void addDataSectionAttribute( ast::ObjectDecl * objDecl ) { 1251 const bool is_tls = objDecl->storage.is_threadlocal ;1251 const bool is_tls = objDecl->storage.is_threadlocal_any(); 1252 1252 const char * section = is_tls ? tlsd_section : data_section; 1253 1253 objDecl->attributes.push_back(new ast::Attribute("section", { -
src/Makefile.am
r428adbc r7f6a7c9 71 71 EXTRA_DIST = include/cassert include/optional BasicTypes-gen.cc 72 72 73 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -Werror=return-type -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++1 4$(TCMALLOCFLAG)73 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -Werror=return-type -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++17 $(TCMALLOCFLAG) 74 74 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 75 75 ARFLAGS = cr -
src/Parser/DeclarationNode.cc
r428adbc r7f6a7c9 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 14 17:36:57 202113 // Update Count : 11 5412 // Last Modified On : Mon Aug 8 17:07:00 2022 13 // Update Count : 1185 14 14 // 15 15 … … 128 128 if ( name ) { 129 129 os << *name << ": "; 130 } else {131 os << "unnamed: ";132 130 } // if 133 131 … … 154 152 initializer->printOneLine( os ); 155 153 os << " maybe constructed? " << initializer->get_maybeConstructed(); 156 157 } // if 154 } // if 155 156 for ( Attribute * attr: reverseIterate( attributes ) ) { 157 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str(); 158 } // for 158 159 159 160 os << endl; … … 243 244 newnode->type = new TypeData( TypeData::Aggregate ); 244 245 newnode->type->aggregate.kind = kind; 245 newnode->type->aggregate.name = 246 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 246 247 newnode->type->aggregate.actuals = actuals; 247 248 newnode->type->aggregate.fields = fields; … … 253 254 } // DeclarationNode::newAggregate 254 255 255 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, DeclarationNode * base) {256 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base) { 256 257 DeclarationNode * newnode = new DeclarationNode; 257 258 newnode->type = new TypeData( TypeData::Enum ); … … 260 261 newnode->type->enumeration.body = body; 261 262 newnode->type->enumeration.anon = name == nullptr; 263 newnode->type->enumeration.typed = typed; 262 264 if ( base && base->type) { 263 newnode->type->base = base->type; 264 } // if 265 266 // Check: if base has TypeData 265 newnode->type->base = base->type; 266 } // if 267 267 268 return newnode; 268 269 } // DeclarationNode::newEnum … … 284 285 285 286 DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) { 286 if ( init ) { // list init {} or a singleInit287 if ( init->get_expression() ) { // singleInit287 if ( init ) { 288 if ( init->get_expression() ) { 288 289 return newEnumConstant( name, init->get_expression() ); 289 } else { // TODO: listInit290 } else { 290 291 DeclarationNode * newnode = newName( name ); 291 292 newnode->initializer = init; … … 293 294 } // if 294 295 } else { 295 return newName( name ); // Not explicitly inited enum value;296 return newName( name ); 296 297 } // if 297 298 } // DeclarationNode::newEnumValueGeneric … … 504 505 } // for 505 506 // src is the new item being added and has a single bit 506 } else if ( ! src->storageClasses.is_threadlocal ) { // conflict ?507 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ? 507 508 appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] + 508 509 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] ); … … 518 519 storageClasses |= q->storageClasses; 519 520 520 for ( Attribute * attr: reverseIterate( q->attributes ) ) {521 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 521 522 attributes.push_front( attr->clone() ); 522 523 } // for … … 683 684 } // if 684 685 delete o; 686 685 687 return this; 686 688 } -
src/Parser/ExpressionNode.cc
r428adbc r7f6a7c9 509 509 } // build_varref 510 510 511 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) { 512 Declaration * newDecl = maybeBuild< Declaration >(decl_node); 513 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { 514 const Type * t = newDeclWithType->get_type(); 515 if ( t ) { 516 if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) { 517 newDecl= new EnumDecl( typeInst->name ); 518 } 519 } 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 ret->set_var( obj ); 526 } 527 return ret; 528 } 529 530 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) { 531 EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node ); 532 return new QualifiedNameExpr( newDecl, name->name ); 533 } 534 511 535 DimensionExpr * build_dimensionref( const string * name ) { 512 536 DimensionExpr * expr = new DimensionExpr( *name ); -
src/Parser/ParseNode.h
r428adbc r7f6a7c9 183 183 184 184 NameExpr * build_varref( const std::string * name ); 185 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ); 186 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name ); 185 187 DimensionExpr * build_dimensionref( const std::string * name ); 186 188 … … 235 237 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 236 238 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); 237 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, DeclarationNode * base = nullptr );239 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr ); 238 240 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); 239 241 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init ); -
src/Parser/TypeData.cc
r428adbc r7f6a7c9 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:12:51 2015 11 // Last Modified By : Henry Xue12 // Last Modified On : Tue Jul 20 04:10:50 202113 // Update Count : 67 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 10 22:36:52 2022 13 // Update Count : 677 14 14 // 15 15 … … 283 283 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " "; 284 284 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " "; 285 if ( complextype == DeclarationNode::NoComplexType ) { // basic type 286 assert( basictype != DeclarationNode::NoBasicType ); 287 os << DeclarationNode::basicTypeNames[ basictype ] << " "; 288 } else { // complex type 289 // handle double _Complex 290 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 291 os << DeclarationNode::complexTypeNames[ complextype ] << " "; 292 } // if 285 if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " "; 286 if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " "; 293 287 break; 294 288 case Pointer: … … 437 431 __attribute__((fallthrough)); 438 432 #endif 433 // FALL THROUGH 439 434 case Typeof: 440 435 os << "type-of expression "; … … 442 437 typeexpr->print( os, indent + 2 ); 443 438 } // if 439 break; 440 case Vtable: 441 os << "vtable"; 444 442 break; 445 443 case Builtin: … … 548 546 return buildAggInst( td ); 549 547 case TypeData::EnumConstant: 550 // the name gets filled in later -- by SymTab::Validate551 548 return new EnumInstType( buildQualifiers( td ), "" ); 552 549 case TypeData::SymbolicInst: … … 923 920 assert( td->kind == TypeData::Enum ); 924 921 Type * baseType = td->base ? typebuild(td->base) : nullptr; 925 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage, baseType );922 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType ); 926 923 buildList( td->enumeration.constants, ret->get_members() ); 927 924 list< Declaration * >::iterator members = ret->get_members().begin(); 928 925 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 929 if ( cur->has_enumeratorValue() ) { 926 if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) { 927 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); 928 } else if ( cur->has_enumeratorValue() ) { 930 929 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members); 931 930 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) ); 932 931 } else if ( !cur->initializer ) { 933 932 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) { 934 SemanticError( td->location, " A non whole number enum value declmust be explicitly initialized." );933 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 935 934 } 936 935 } -
src/Parser/TypeData.h
r428adbc r7f6a7c9 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 14 17:44:05 202113 // Update Count : 20 212 // Last Modified On : Tue May 10 22:18:49 2022 13 // Update Count : 203 14 14 // 15 15 … … 27 27 struct TypeData { 28 28 enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 29 SymbolicInst, Tuple, Typeof, Basetypeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };29 SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown }; 30 30 31 31 struct Aggregate_t { … … 59 59 bool body; 60 60 bool anon; 61 bool typed; 61 62 }; 62 63 -
src/Parser/TypedefTable.cc
r428adbc r7f6a7c9 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 19 08:30:14 202113 // Update Count : 2 6212 // Last Modified On : Tue Feb 15 08:27:24 2022 13 // Update Count : 275 14 14 // 15 15 … … 18 18 #include <cassert> // for assert 19 19 #include <iostream> 20 using namespace std; 20 21 21 22 #if 0 … … 28 29 29 30 debugPrint( 30 static const char *kindName( int kind ) {31 switch ( kind ) {32 case IDENTIFIER: return "identifier";33 case TYPEDIMname: return "typedim";34 case TYPEDEFname: return "typedef";35 case TYPEGENname: return "typegen";36 default:37 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;38 abort();39 } // switch40 } // kindName41 ) 31 static const char *kindName( int kind ) { 32 switch ( kind ) { 33 case IDENTIFIER: return "identifier"; 34 case TYPEDIMname: return "typedim"; 35 case TYPEDEFname: return "typedef"; 36 case TYPEGENname: return "typegen"; 37 default: 38 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 39 abort(); 40 } // switch 41 } // kindName 42 ); 42 43 43 44 TypedefTable::~TypedefTable() { … … 80 81 81 82 void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 82 autoscope = kindTable.currentScope();83 KindTable::size_type scope = kindTable.currentScope(); 83 84 debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl ); 84 85 kindTable.insertAt( scope, identifier, kind ); … … 86 87 87 88 void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) { 88 autoscope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;89 // autoscope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;89 KindTable::size_type scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level; 90 // size_type scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level; 90 91 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl ); 91 autoret = kindTable.insertAt( scope, identifier, kind );92 pair< KindTable::iterator, bool > ret = kindTable.insertAt( scope, identifier, kind ); 92 93 if ( ! ret.second ) ret.first->second = kind; // exists => update 93 94 } // TypedefTable::addToEnclosingScope -
src/Parser/lex.ll
r428adbc r7f6a7c9 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Sun Jun 20 18:41:09 202113 * Update Count : 7 5912 * Last Modified On : Tue Sep 20 21:18:55 2022 13 * Update Count : 762 14 14 */ 15 15 … … 24 24 25 25 //**************************** Includes and Defines **************************** 26 27 #ifdef __clang__ 28 #pragma GCC diagnostic ignored "-Wnull-conversion" 29 #endif 26 30 27 31 // trigger before each matching rule's action … … 82 86 // Stop warning due to incorrectly generated flex code. 83 87 #pragma GCC diagnostic ignored "-Wsign-compare" 84 85 // lex uses __null in a boolean context, it's fine.86 #pragma GCC diagnostic ignored "-Wnull-conversion"87 88 %} 88 89 … … 314 315 switch { KEYWORD_RETURN(SWITCH); } 315 316 thread { KEYWORD_RETURN(THREAD); } // C11 316 _Thread_local { KEYWORD_RETURN(THREADLOCAL); } // C11 317 __thread { KEYWORD_RETURN(THREADLOCALGCC); } // GCC 318 _Thread_local { KEYWORD_RETURN(THREADLOCALC11); } // C11 317 319 throw { KEYWORD_RETURN(THROW); } // CFA 318 320 throwResume { KEYWORD_RETURN(THROWRESUME); } // CFA -
src/Parser/parser.yy
r428adbc r7f6a7c9 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 1 15:35:08 202213 // Update Count : 5 40512 // Last Modified On : Sat Aug 27 13:21:28 2022 13 // Update Count : 5661 14 14 // 15 15 … … 58 58 59 59 // lex uses __null in a boolean context, it's fine. 60 #ifdef __clang__ 60 61 #pragma GCC diagnostic ignored "-Wparentheses-equality" 62 #endif 61 63 62 64 extern DeclarationNode * parseTree; … … 197 199 } // fieldDecl 198 200 201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) ) 202 #define NEW_ONE new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) 203 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." 205 #define MISSING_LOW "Missing low value for up-to range so index is uninitialized." 206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized." 207 208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 209 if ( index->initializer ) { 210 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); 211 } // if 212 if ( index->next ) { 213 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." ); 214 } // if 215 return new ForCtrl( index->addInitializer( new InitializerNode( start ) ), 216 // NULL comp/inc => leave blank 217 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr, 218 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 219 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr ); 220 } // forCtrl 221 199 222 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 200 223 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get()); … … 206 229 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 207 230 // NULL comp/inc => leave blank 208 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,231 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr, 209 232 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 210 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0);233 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr ); 211 234 } // forCtrl 212 235 … … 272 295 %token TYPEDEF 273 296 %token EXTERN STATIC AUTO REGISTER 274 %token THREADLOCAL //C11297 %token THREADLOCALGCC THREADLOCALC11 // GCC, C11 275 298 %token INLINE FORTRAN // C99, extension ISO/IEC 9899:1999 Section J.5.9(1) 276 299 %token NORETURN // C11 … … 346 369 %type<ifctl> conditional_declaration 347 370 %type<fctl> for_control_expression for_control_expression_list 348 %type<compop> inclexcl371 %type<compop> updown updowneq downupdowneq 349 372 %type<en> subrange 350 373 %type<decl> asm_name_opt … … 614 637 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); } 615 638 | type_name '.' identifier // CFA, nested type 616 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }639 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); } 617 640 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 618 641 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 1239 1262 iteration_statement: 1240 1263 WHILE '(' ')' statement %prec THEN // CFA => while ( 1 ) 1241 { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) )), maybe_build_compound( $4 ) ) ); }1264 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); } 1242 1265 | WHILE '(' ')' statement ELSE statement // CFA 1243 1266 { 1244 $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) )), maybe_build_compound( $4 ) ) );1267 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1245 1268 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1246 1269 } … … 1250 1273 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1251 1274 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) 1252 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }1275 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); } 1253 1276 | DO statement WHILE '(' ')' ELSE statement // CFA 1254 1277 { 1255 $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );1278 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1256 1279 SemanticWarning( yylloc, Warning::SuperfluousElse, "" ); 1257 1280 } … … 1304 1327 { $$ = new ForCtrl( $1, $2, $4 ); } 1305 1328 1306 | comma_expression // CFA 1307 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1308 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1309 | '=' comma_expression // CFA 1310 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1311 OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1312 | comma_expression inclexcl comma_expression // CFA 1313 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1314 | comma_expression inclexcl comma_expression '~' comma_expression // CFA 1315 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); } 1316 | comma_expression ';' // CFA 1317 { $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); } 1329 | '@' ';' comma_expression // CFA, empty loop-index 1330 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); } 1331 | '@' ';' comma_expression ';' comma_expression // CFA, empty loop-index 1332 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); } 1333 1334 | comma_expression // CFA, anonymous loop-index 1335 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); } 1336 | downupdowneq comma_expression // CFA, anonymous loop-index 1337 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); } 1338 1339 | comma_expression updowneq comma_expression // CFA, anonymous loop-index 1340 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); } 1341 | '@' updowneq comma_expression // CFA, anonymous loop-index 1342 { 1343 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1344 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE ); 1345 } 1346 | comma_expression updowneq '@' // CFA, anonymous loop-index 1347 { 1348 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1349 else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1350 } 1351 | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1352 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); } 1353 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1354 { 1355 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1356 else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 ); 1357 } 1358 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index 1359 { 1360 if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1361 else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1362 } 1363 | comma_expression updowneq comma_expression '~' '@' // CFA, error 1364 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1365 | '@' updowneq '@' // CFA, error 1366 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1367 | '@' updowneq comma_expression '~' '@' // CFA, error 1368 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1369 | comma_expression updowneq '@' '~' '@' // CFA, error 1370 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1371 | '@' updowneq '@' '~' '@' // CFA, error 1372 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1373 1318 1374 | comma_expression ';' comma_expression // CFA 1319 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1320 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1321 | comma_expression ';' '=' comma_expression // CFA 1322 { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1323 OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1324 | comma_expression ';' comma_expression inclexcl comma_expression // CFA 1325 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1326 | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA 1327 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1375 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } 1376 | comma_expression ';' downupdowneq comma_expression // CFA 1377 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); } 1378 1379 | comma_expression ';' comma_expression updowneq comma_expression // CFA 1380 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); } 1381 | comma_expression ';' '@' updowneq comma_expression // CFA 1382 { 1383 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1384 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE ); 1385 } 1386 | comma_expression ';' comma_expression updowneq '@' // CFA 1387 { 1388 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1389 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1390 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE ); 1391 } 1392 | comma_expression ';' '@' updowneq '@' // CFA, error 1393 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; } 1394 1395 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA 1396 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); } 1397 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1398 { 1399 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1400 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 ); 1401 } 1402 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA 1403 { 1404 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1405 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1406 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 ); 1407 } 1408 | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA 1409 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); } 1410 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1411 { 1412 if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1413 else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr ); 1414 } 1415 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA 1416 { 1417 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1418 else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1419 else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr ); 1420 } 1421 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA 1422 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; } 1423 1424 | declaration comma_expression // CFA 1425 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); } 1426 | declaration downupdowneq comma_expression // CFA 1427 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); } 1428 1429 | declaration comma_expression updowneq comma_expression // CFA 1430 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); } 1431 | declaration '@' updowneq comma_expression // CFA 1432 { 1433 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1434 else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE ); 1435 } 1436 | declaration comma_expression updowneq '@' // CFA 1437 { 1438 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1439 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1440 else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE ); 1441 } 1442 1443 | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA 1444 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); } 1445 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1446 { 1447 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1448 else $$ = forCtrl( $1, $4, $3, nullptr, $6 ); 1449 } 1450 | declaration comma_expression updowneq '@' '~' comma_expression // CFA 1451 { 1452 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1453 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1454 else $$ = forCtrl( $1, $2, $3, nullptr, $6 ); 1455 } 1456 | declaration comma_expression updowneq comma_expression '~' '@' // CFA 1457 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); } 1458 | declaration '@' updowneq comma_expression '~' '@' // CFA 1459 { 1460 if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; } 1461 else $$ = forCtrl( $1, $4, $3, nullptr, nullptr ); 1462 } 1463 | declaration comma_expression updowneq '@' '~' '@' // CFA 1464 { 1465 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1466 else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; } 1467 else $$ = forCtrl( $1, $2, $3, nullptr, nullptr ); 1468 } 1469 | declaration '@' updowneq '@' '~' '@' // CFA, error 1470 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; } 1328 1471 1329 1472 | comma_expression ';' TYPEDEFname // CFA, array type 1330 1473 { 1331 SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr; 1332 $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr ); 1333 } 1334 1335 // There is a S/R conflicit if ~ and -~ are factored out. 1336 | comma_expression ';' comma_expression '~' '@' // CFA 1337 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1338 | comma_expression ';' comma_expression ErangeDown '@' // CFA 1339 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1340 | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA 1341 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); } 1342 | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA 1343 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); } 1344 | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA 1345 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); } 1474 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1475 //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr ); 1476 } 1477 | comma_expression ';' downupdowneq TYPEDEFname // CFA, array type 1478 { 1479 if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; } 1480 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1481 } 1346 1482 ; 1347 1483 1348 inclexcl: 1484 downupdowneq: 1485 ErangeDown 1486 { $$ = OperKinds::GThan; } 1487 | ErangeUpEq 1488 { $$ = OperKinds::LEThan; } 1489 | ErangeDownEq 1490 { $$ = OperKinds::GEThan; } 1491 ; 1492 1493 updown: 1349 1494 '~' 1350 1495 { $$ = OperKinds::LThan; } 1496 | ErangeDown 1497 { $$ = OperKinds::GThan; } 1498 ; 1499 1500 updowneq: 1501 updown 1351 1502 | ErangeUpEq 1352 1503 { $$ = OperKinds::LEThan; } 1353 | ErangeDown1354 { $$ = OperKinds::GThan; }1355 1504 | ErangeDownEq 1356 1505 { $$ = OperKinds::GEThan; } … … 1935 2084 | REGISTER 1936 2085 { $$ = DeclarationNode::newStorageClass( Type::Register ); } 1937 | THREADLOCAL // C11 1938 { $$ = DeclarationNode::newStorageClass( Type::Threadlocal ); } 2086 | THREADLOCALGCC // GCC 2087 { $$ = DeclarationNode::newStorageClass( Type::ThreadlocalGcc ); } 2088 | THREADLOCALC11 // C11 2089 { $$ = DeclarationNode::newStorageClass( Type::ThreadlocalC11 ); } 1939 2090 // Put function specifiers here to simplify parsing rules, but separate them semantically. 1940 2091 | INLINE // C99 … … 2387 2538 enum_type: 2388 2539 ENUM attribute_list_opt '{' enumerator_list comma_opt '}' 2389 { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }2540 { $$ = DeclarationNode::newEnum( nullptr, $4, true, false )->addQualifiers( $2 ); } 2390 2541 | ENUM attribute_list_opt identifier 2391 2542 { typedefTable.makeTypedef( *$3 ); } 2392 2543 '{' enumerator_list comma_opt '}' 2393 { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); }2544 { $$ = DeclarationNode::newEnum( $3, $6, true, false )->addQualifiers( $2 ); } 2394 2545 | ENUM attribute_list_opt typedef_name // unqualified type name 2395 2546 '{' enumerator_list comma_opt '}' 2396 { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }2547 { $$ = DeclarationNode::newEnum( $3->name, $5, true, false )->addQualifiers( $2 ); } 2397 2548 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2398 2549 { … … 2400 2551 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2401 2552 2402 $$ = DeclarationNode::newEnum( nullptr, $7, true, $3 )->addQualifiers( $5 ); 2553 $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 ); 2554 } 2555 | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2556 { 2557 $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 ); 2403 2558 } 2404 2559 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt … … 2409 2564 '{' enumerator_list comma_opt '}' 2410 2565 { 2411 $$ = DeclarationNode::newEnum( $6, $10, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2566 $$ = DeclarationNode::newEnum( $6, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2567 } 2568 | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt 2569 '{' enumerator_list comma_opt '}' 2570 { 2571 $$ = DeclarationNode::newEnum( $5, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 ); 2412 2572 } 2413 2573 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}' 2414 2574 { 2415 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2416 typedefTable.makeTypedef( *$6->name ); 2417 $$ = DeclarationNode::newEnum( $6->name, $9, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2575 $$ = DeclarationNode::newEnum( $6->name, $9, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 ); 2576 } 2577 | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}' 2578 { 2579 $$ = DeclarationNode::newEnum( $5->name, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 ); 2418 2580 } 2419 2581 | enum_type_nobody … … 2422 2584 enum_type_nobody: // enum - {...} 2423 2585 ENUM attribute_list_opt identifier 2424 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); }2425 | ENUM attribute_list_opt type_name // qualified type name2426 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); }2586 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); } 2587 | ENUM attribute_list_opt type_name 2588 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); } 2427 2589 ; 2428 2590 -
src/ResolvExpr/AlternativeFinder.cc
r428adbc r7f6a7c9 299 299 SemanticError( expr->location, stream.str() ); 300 300 } 301 alternatives = move(pruned);301 alternatives = std::move(pruned); 302 302 PRINT( 303 303 std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl; … … 573 573 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0, 574 574 unsigned explAlt = 0 ) 575 : parent(parent), expr(expr->clone()), cost(cost), env( move(env)), need(move(need)),576 have( move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),575 : parent(parent), expr(expr->clone()), cost(cost), env(std::move(env)), need(std::move(need)), 576 have(std::move(have)), openVars(std::move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 577 577 nextExpl(nextExpl), explAlt(explAlt) {} 578 578 … … 580 580 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 581 581 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 582 env( move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),582 env(std::move(env)), need(std::move(need)), have(std::move(have)), openVars(std::move(openVars)), 583 583 nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {} 584 584 … … 707 707 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 708 708 newResult.openVars, indexer ) ) { 709 finalResults.push_back( move(newResult) );709 finalResults.push_back( std::move(newResult) ); 710 710 } 711 711 … … 726 726 if ( expl.exprs.empty() ) { 727 727 results.emplace_back( 728 results[i], move(env), copy(results[i].need),729 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );728 results[i], std::move(env), copy(results[i].need), 729 copy(results[i].have), std::move(openVars), nextArg + 1, expl.cost ); 730 730 731 731 continue; … … 734 734 // add new result 735 735 results.emplace_back( 736 i, expl.exprs.front().get(), move(env), copy(results[i].need),737 copy(results[i].have), move(openVars), nextArg + 1,736 i, expl.exprs.front().get(), std::move(env), copy(results[i].need), 737 copy(results[i].have), std::move(openVars), nextArg + 1, 738 738 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 739 739 } … … 747 747 // splice final results onto results 748 748 for ( std::size_t i = 0; i < finalResults.size(); ++i ) { 749 results.push_back( move(finalResults[i]) );749 results.push_back( std::move(finalResults[i]) ); 750 750 } 751 751 return ! finalResults.empty(); … … 783 783 784 784 results.emplace_back( 785 i, expr, move(env), move(need), move(have),move(openVars), nextArg,785 i, expr, std::move(env), std::move(need), std::move(have), std::move(openVars), nextArg, 786 786 nTuples, Cost::zero, nextExpl, results[i].explAlt ); 787 787 } … … 801 801 indexer ) ) { 802 802 results.emplace_back( 803 i, new DefaultArgExpr( cnstExpr ), move(env), move(need),move(have),804 move(openVars), nextArg, nTuples );803 i, new DefaultArgExpr( cnstExpr ), std::move(env), std::move(need), std::move(have), 804 std::move(openVars), nextArg, nTuples ); 805 805 } 806 806 } … … 824 824 if ( expl.exprs.empty() ) { 825 825 results.emplace_back( 826 results[i], move(env), move(need), move(have),move(openVars),826 results[i], std::move(env), std::move(need), std::move(have), std::move(openVars), 827 827 nextArg + 1, expl.cost ); 828 828 … … 846 846 // add new result 847 847 results.emplace_back( 848 i, expr, move(env), move(need), move(have),move(openVars), nextArg + 1,848 i, expr, std::move(env), std::move(need), std::move(have), std::move(openVars), nextArg + 1, 849 849 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 850 850 } … … 962 962 if ( expl.exprs.empty() ) { 963 963 results.emplace_back( 964 results[i], move(env), copy(results[i].need),965 copy(results[i].have), move(openVars), nextArg + 1, expl.cost );964 results[i], std::move(env), copy(results[i].need), 965 copy(results[i].have), std::move(openVars), nextArg + 1, expl.cost ); 966 966 967 967 continue; … … 970 970 // add new result 971 971 results.emplace_back( 972 i, expl.exprs.front().get(), move(env), copy(results[i].need),973 copy(results[i].have), move(openVars), nextArg + 1, 0,972 i, expl.exprs.front().get(), std::move(env), copy(results[i].need), 973 copy(results[i].have), std::move(openVars), nextArg + 1, 0, 974 974 expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 975 975 } … … 1067 1067 funcE.emplace_back( actual, indexer ); 1068 1068 } 1069 argExpansions.insert( argExpansions.begin(), move(funcE) );1069 argExpansions.insert( argExpansions.begin(), std::move(funcE) ); 1070 1070 1071 1071 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); … … 1116 1116 } // for 1117 1117 1118 candidates = move(alternatives);1118 candidates = std::move(alternatives); 1119 1119 1120 1120 // use a new list so that alternatives are not examined by addAnonConversions twice. -
src/ResolvExpr/CandidateFinder.cpp
r428adbc r7f6a7c9 269 269 unsigned nextArg, unsigned tupleStart = 0, Cost cost = Cost::zero, 270 270 unsigned nextExpl = 0, unsigned explAlt = 0 ) 271 : parent(parent), expr( expr ), cost( cost ), env( move( env ) ), need(move( need ) ),272 have( move( have ) ), open(move( open ) ), nextArg( nextArg ), tupleStart( tupleStart ),271 : parent(parent), expr( expr ), cost( cost ), env( std::move( env ) ), need( std::move( need ) ), 272 have( std::move( have ) ), open( std::move( open ) ), nextArg( nextArg ), tupleStart( tupleStart ), 273 273 nextExpl( nextExpl ), explAlt( explAlt ) {} 274 274 … … 276 276 const ArgPack & o, ast::TypeEnvironment && env, ast::AssertionSet && need, 277 277 ast::AssertionSet && have, ast::OpenVarSet && open, unsigned nextArg, Cost added ) 278 : parent( o.parent ), expr( o.expr ), cost( o.cost + added ), env( move( env ) ),279 need( move( need ) ), have( move( have ) ), open(move( open ) ), nextArg( nextArg ),278 : parent( o.parent ), expr( o.expr ), cost( o.cost + added ), env( std::move( env ) ), 279 need( std::move( need ) ), have( std::move( have ) ), open( std::move( open ) ), nextArg( nextArg ), 280 280 tupleStart( o.tupleStart ), nextExpl( 0 ), explAlt( 0 ) {} 281 281 … … 301 301 // reset pack to appropriate tuple 302 302 std::vector< ast::ptr< ast::Expr > > exprv( exprs.begin(), exprs.end() ); 303 expr = new ast::TupleExpr{ expr->location, move( exprv ) };303 expr = new ast::TupleExpr{ expr->location, std::move( exprv ) }; 304 304 tupleStart = pack->tupleStart - 1; 305 305 parent = pack->parent; … … 404 404 newResult.open, symtab ) 405 405 ) { 406 finalResults.emplace_back( move( newResult ) );406 finalResults.emplace_back( std::move( newResult ) ); 407 407 } 408 408 … … 423 423 if ( expl.exprs.empty() ) { 424 424 results.emplace_back( 425 results[i], move( env ), copy( results[i].need ),426 copy( results[i].have ), move( open ), nextArg + 1, expl.cost );425 results[i], std::move( env ), copy( results[i].need ), 426 copy( results[i].have ), std::move( open ), nextArg + 1, expl.cost ); 427 427 428 428 continue; … … 431 431 // add new result 432 432 results.emplace_back( 433 i, expl.exprs.front(), move( env ), copy( results[i].need ),434 copy( results[i].have ), move( open ), nextArg + 1, nTuples,433 i, expl.exprs.front(), std::move( env ), copy( results[i].need ), 434 copy( results[i].have ), std::move( open ), nextArg + 1, nTuples, 435 435 expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 436 436 } … … 444 444 // splice final results onto results 445 445 for ( std::size_t i = 0; i < finalResults.size(); ++i ) { 446 results.emplace_back( move( finalResults[i] ) );446 results.emplace_back( std::move( finalResults[i] ) ); 447 447 } 448 448 return ! finalResults.empty(); … … 478 478 479 479 results.emplace_back( 480 i, expr, move( env ), move( need ), move( have ),move( open ), nextArg,480 i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ), nextArg, 481 481 nTuples, Cost::zero, nextExpl, results[i].explAlt ); 482 482 } … … 494 494 if ( unify( paramType, cnst->result, env, need, have, open, symtab ) ) { 495 495 results.emplace_back( 496 i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ),497 move( need ), move( have ),move( open ), nextArg, nTuples );496 i, new ast::DefaultArgExpr{ cnst->location, cnst }, std::move( env ), 497 std::move( need ), std::move( have ), std::move( open ), nextArg, nTuples ); 498 498 } 499 499 } … … 516 516 if ( expl.exprs.empty() ) { 517 517 results.emplace_back( 518 results[i], move( env ), move( need ), move( have ),move( open ),518 results[i], std::move( env ), std::move( need ), std::move( have ), std::move( open ), 519 519 nextArg + 1, expl.cost ); 520 520 … … 538 538 // add new result 539 539 results.emplace_back( 540 i, expr, move( env ), move( need ), move( have ),move( open ),540 i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ), 541 541 nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 542 542 } … … 576 576 restructureCast( idx, toType->getComponent( i ), isGenerated ) ); 577 577 } 578 return new ast::TupleExpr{ arg->location, move( components ) };578 return new ast::TupleExpr{ arg->location, std::move( components ) }; 579 579 } else { 580 580 // handle normally … … 672 672 } 673 673 std::vector< ast::ptr< ast::Expr > > vargs( args.begin(), args.end() ); 674 appExpr->args = move( vargs );674 appExpr->args = std::move( vargs ); 675 675 // build and validate new candidate 676 676 auto newCand = … … 783 783 if ( expl.exprs.empty() ) { 784 784 results.emplace_back( 785 results[i], move( env ), copy( results[i].need ),786 copy( results[i].have ), move( open ), nextArg + 1,785 results[i], std::move( env ), copy( results[i].need ), 786 copy( results[i].have ), std::move( open ), nextArg + 1, 787 787 expl.cost ); 788 788 … … 792 792 // add new result 793 793 results.emplace_back( 794 i, expl.exprs.front(), move( env ), copy( results[i].need ),795 copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost,794 i, expl.exprs.front(), std::move( env ), copy( results[i].need ), 795 copy( results[i].have ), std::move( open ), nextArg + 1, 0, expl.cost, 796 796 expl.exprs.size() == 1 ? 0 : 1, j ); 797 797 } … … 843 843 // as a member expression 844 844 addAnonConversions( newCand ); 845 candidates.emplace_back( move( newCand ) );845 candidates.emplace_back( std::move( newCand ) ); 846 846 } 847 847 } … … 864 864 } 865 865 866 void postvisit( const ast::QualifiedNameExpr * qualifiedNameExpr ) { 867 auto mangleName = Mangle::mangle(qualifiedNameExpr->var); 868 addCandidate( qualifiedNameExpr, tenv ); 869 } 870 866 871 void postvisit( const ast::UntypedExpr * untypedExpr ) { 867 872 std::vector< CandidateFinder > argCandidates = … … 897 902 } 898 903 899 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer); 900 else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) {901 const ast::EnumDecl * enumDecl = enumInst->base;902 if ( const ast::Type* enumType = enumDecl->base ) {903 // instance of enum (T) is a instance of type (T)904 funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type));905 } else {906 // instance of an untyped enum is techically int907 funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type));908 }909 }904 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer); 905 // else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) { 906 // const ast::EnumDecl * enumDecl = enumInst->base; // Here 907 // if ( const ast::Type* enumType = enumDecl->base ) { 908 // // instance of enum (T) is a instance of type (T) 909 // funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type)); 910 // } else { 911 // // instance of an untyped enum is techically int 912 // funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type)); 913 // } 914 // } 910 915 else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type)); 911 916 } … … 986 991 funcE.emplace_back( *func, symtab ); 987 992 } 988 argExpansions.emplace_front( move( funcE ) );993 argExpansions.emplace_front( std::move( funcE ) ); 989 994 990 995 for ( const CandidateRef & op : opFinder ) { … … 1030 1035 if ( cvtCost != Cost::infinity ) { 1031 1036 withFunc->cvtCost = cvtCost; 1032 candidates.emplace_back( move( withFunc ) );1033 } 1034 } 1035 found = move( candidates );1037 candidates.emplace_back( std::move( withFunc ) ); 1038 } 1039 } 1040 found = std::move( candidates ); 1036 1041 1037 1042 // use a new list so that candidates are not examined by addAnonConversions twice … … 1131 1136 CandidateRef newCand = std::make_shared<Candidate>( 1132 1137 restructureCast( cand->expr, toType, castExpr->isGenerated ), 1133 copy( cand->env ), move( open ),move( need ), cand->cost,1138 copy( cand->env ), std::move( open ), std::move( need ), cand->cost, 1134 1139 cand->cost + thisCost ); 1135 1140 inferParameters( newCand, matches ); … … 1285 1290 // as a name expression 1286 1291 addAnonConversions( newCand ); 1287 candidates.emplace_back( move( newCand ) );1292 candidates.emplace_back( std::move( newCand ) ); 1288 1293 } 1289 1294 } … … 1394 1399 new ast::LogicalExpr{ 1395 1400 logicalExpr->location, r1->expr, r2->expr, logicalExpr->isAnd }, 1396 move( env ), move( open ),move( need ), r1->cost + r2->cost );1401 std::move( env ), std::move( open ), std::move( need ), r1->cost + r2->cost ); 1397 1402 } 1398 1403 } … … 1452 1457 // output candidate 1453 1458 CandidateRef newCand = std::make_shared<Candidate>( 1454 newExpr, move( env ), move( open ),move( need ), cost );1459 newExpr, std::move( env ), std::move( open ), std::move( need ), cost ); 1455 1460 inferParameters( newCand, candidates ); 1456 1461 } … … 1519 1524 // add candidate 1520 1525 CandidateRef newCand = std::make_shared<Candidate>( 1521 newExpr, move( env ), move( open ),move( need ),1526 newExpr, std::move( env ), std::move( open ), std::move( need ), 1522 1527 r1->cost + r2->cost ); 1523 1528 inferParameters( newCand, candidates ); … … 1548 1553 1549 1554 addCandidate( 1550 new ast::TupleExpr{ tupleExpr->location, move( exprs ) },1551 move( env ), move( open ),move( need ), sumCost( subs ) );1555 new ast::TupleExpr{ tupleExpr->location, std::move( exprs ) }, 1556 std::move( env ), std::move( open ), std::move( need ), sumCost( subs ) ); 1552 1557 } 1553 1558 } … … 1635 1640 initExpr->location, restructureCast( cand->expr, toType ), 1636 1641 initAlt.designation }, 1637 move(env), move( open ),move( need ), cand->cost, thisCost );1642 std::move(env), std::move( open ), std::move( need ), cand->cost, thisCost ); 1638 1643 inferParameters( newCand, matches ); 1639 1644 } … … 1768 1773 cand->env.applyFree( newResult ); 1769 1774 cand->expr = ast::mutate_field( 1770 cand->expr.get(), &ast::Expr::result, move( newResult ) );1775 cand->expr.get(), &ast::Expr::result, std::move( newResult ) ); 1771 1776 1772 1777 out.emplace_back( cand ); … … 1854 1859 1855 1860 auto oldsize = candidates.size(); 1856 candidates = move( pruned );1861 candidates = std::move( pruned ); 1857 1862 1858 1863 PRINT( -
src/ResolvExpr/CommonType.cc
r428adbc r7f6a7c9 28 28 #include "Unify.h" // for unifyExact, WidenMode 29 29 #include "typeops.h" // for isFtype 30 #include "Tuples/Tuples.h" 30 31 31 32 // #define DEBUG … … 675 676 ast::TypeEnvironment & tenv; 676 677 const ast::OpenVarSet & open; 678 ast::AssertionSet & need; 679 ast::AssertionSet & have; 677 680 public: 678 681 static size_t traceId; … … 681 684 CommonType_new( 682 685 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 683 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 684 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} 686 ast::TypeEnvironment & env, const ast::OpenVarSet & o, 687 ast::AssertionSet & need, ast::AssertionSet & have ) 688 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), need (need), have (have) ,result() {} 685 689 686 690 void previsit( const ast::Node * ) { visit_children = false; } … … 753 757 bool tryResolveWithTypedEnum( const ast::Type * type1 ) { 754 758 if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) { 755 ast::AssertionSet have, need; // unused756 759 ast::OpenVarSet newOpen{ open }; 757 760 if (enumInst->base->base … … 792 795 reset_qualifiers( t2 ); 793 796 794 ast::AssertionSet have, need;795 797 ast::OpenVarSet newOpen{ open }; 796 798 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { … … 803 805 } 804 806 } 807 else if ( isFtype (t1) && isFtype (t2) ) { 808 auto f1 = t1.as<ast::FunctionType>(); 809 if (!f1) return; 810 auto f2 = t2.strict_as<ast::FunctionType>(); 811 812 assertf(f1->returns.size() <= 1, "Function return should not be a list"); 813 assertf(f2->returns.size() <= 1, "Function return should not be a list"); 814 815 if ( 816 ( f1->params.size() != f2->params.size() || f1->returns.size() != f2->returns.size() ) 817 && ! f1->isTtype() 818 && ! f2->isTtype() 819 ) return; 820 821 auto params1 = flattenList( f1->params, tenv ); 822 auto params2 = flattenList( f2->params, tenv ); 823 824 auto crnt1 = params1.begin(); 825 auto crnt2 = params2.begin(); 826 auto end1 = params1.end(); 827 auto end2 = params2.end(); 828 829 while (crnt1 != end1 && crnt2 != end2 ) { 830 const ast::Type * arg1 = *crnt1; 831 const ast::Type * arg2 = *crnt2; 832 833 bool isTuple1 = Tuples::isTtype( t1 ); 834 bool isTuple2 = Tuples::isTtype( t2 ); 835 836 // assumes here that ttype *must* be last parameter 837 if ( isTuple1 && ! isTuple2 ) { 838 // combine remainder of list2, then unify 839 if (unifyExact( 840 arg1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, 841 noWiden(), symtab )) { 842 break; 843 844 } 845 else return; 846 } else if ( ! isTuple1 && isTuple2 ) { 847 // combine remainder of list1, then unify 848 if (unifyExact( 849 tupleFromTypes( crnt1, end1 ), arg2, tenv, need, have, open, 850 noWiden(), symtab )) { 851 break; 852 853 } 854 else return; 855 } 856 857 // allow qualifiers of pointer and reference base to become more specific 858 if (auto ref1 = dynamic_cast<const ast::ReferenceType *> (arg1)) { 859 if (auto ref2 = dynamic_cast<const ast::ReferenceType *> (arg2)) { 860 ast::ptr<ast::Type> base1 = ref1->base; 861 ast::ptr<ast::Type> base2 = ref2->base; 862 863 // xxx - assume LHS is always the target type 864 865 if ( ! ((widen.second && ref2->qualifiers.is_mutex) 866 || (ref1->qualifiers.is_mutex == ref2->qualifiers.is_mutex ))) return; 867 868 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) { 869 870 reset_qualifiers(base1); 871 reset_qualifiers(base2); 872 873 if ( ! unifyExact( 874 base1, base2, tenv, need, have, open, noWiden(), symtab ) 875 ) return; 876 } 877 } 878 else return; 879 } 880 else if (auto ptr1 = dynamic_cast<const ast::PointerType *> (arg1)) { 881 if (auto ptr2 = dynamic_cast<const ast::PointerType *> (arg2)) { 882 ast::ptr<ast::Type> base1 = ptr1->base; 883 ast::ptr<ast::Type> base2 = ptr2->base; 884 885 // xxx - assume LHS is always the target type 886 // a function accepting const can always be called by non-const arg 887 888 if ( (widen.second && base1->qualifiers <= base2->qualifiers ) || (base2->qualifiers == base1->qualifiers) ) { 889 890 reset_qualifiers(base1); 891 reset_qualifiers(base2); 892 893 if ( ! unifyExact( 894 base1, base2, tenv, need, have, open, noWiden(), symtab ) 895 ) return; 896 } 897 } 898 else return; 899 900 } 901 else if (! unifyExact( 902 arg1, arg2, tenv, need, have, open, noWiden(), symtab )) return; 903 904 ++crnt1; ++crnt2; 905 } 906 if ( crnt1 != end1 ) { 907 // try unifying empty tuple with ttype 908 const ast::Type * t1 = *crnt1; 909 if (! Tuples::isTtype( t1 ) ) return; 910 if (! unifyExact( 911 t1, tupleFromTypes( crnt2, end2 ), tenv, need, have, open, 912 noWiden(), symtab )) return; 913 } else if ( crnt2 != end2 ) { 914 // try unifying empty tuple with ttype 915 const ast::Type * t2 = *crnt2; 916 if (! Tuples::isTtype( t2 ) ) return; 917 if (! unifyExact( 918 tupleFromTypes( crnt1, end1 ), t2, tenv, need, have, open, 919 noWiden(), symtab )) return; 920 } 921 if ((f1->returns.size() == 0 && f2->returns.size() == 0) 922 || (f1->returns.size() == 1 && f2->returns.size() == 1 && unifyExact(f1->returns[0], f2->returns[0], tenv, need, have, open, noWiden(), symtab))) { 923 result = pointer; 924 925 for (auto & assn : f1->assertions) { 926 auto i = need.find(assn); 927 if (i != need.end()) i->second.isUsed = true; 928 auto j = have.find(assn); 929 if (j != have.end()) j->second.isUsed = true; 930 } 931 932 for (auto & assn : f2->assertions) { 933 auto i = need.find(assn); 934 if (i != need.end()) i->second.isUsed = true; 935 auto j = have.find(assn); 936 if (j != have.end()) j->second.isUsed = true; 937 } 938 939 } 940 } // if ftype 941 805 942 } 806 943 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { … … 839 976 reset_qualifiers( t2 ); 840 977 841 ast::AssertionSet have, need;842 978 ast::OpenVarSet newOpen{ open }; 843 979 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { … … 857 993 // xxx - does unifying a ref with typed enumInst makes sense? 858 994 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 859 result = commonType( type2, ref, widen, symtab, tenv, open);995 result = commonType( type2, ref, tenv, need, have, open, widen, symtab ); 860 996 } 861 997 } … … 877 1013 // xxx - is this already handled by unify? 878 1014 if (!dynamic_cast<const ast::EnumInstType *>(type2)) 879 result = commonType( type2, enumInst, widen, symtab, tenv, open);1015 result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab); 880 1016 } 881 1017 … … 895 1031 reset_qualifiers( t2 ); 896 1032 897 ast::AssertionSet have, need;898 1033 ast::OpenVarSet newOpen{ open }; 899 1034 if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) { … … 999 1134 ast::ptr< ast::Type > commonType( 1000 1135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 1001 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,1002 const ast::OpenVarSet & open 1136 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1137 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab 1003 1138 ) { 1004 1139 unsigned depth1 = type1->referenceDepth(); … … 1036 1171 } 1037 1172 // otherwise both are reference types of the same depth and this is handled by the visitor 1038 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };1173 ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open, need, have }; 1039 1174 type1->accept( visitor ); 1040 1175 ast::ptr< ast::Type > result = visitor.core.result; … … 1047 1182 if ( type->base ) { 1048 1183 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1049 ast::AssertionSet have, need;1050 1184 ast::OpenVarSet newOpen{ open }; 1051 1185 -
src/ResolvExpr/ConversionCost.cc
r428adbc r7f6a7c9 22 22 #include "ResolvExpr/Cost.h" // for Cost 23 23 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 24 #include "ResolvExpr/Unify.h" 24 25 #include "SymTab/Indexer.h" // for Indexer 25 26 #include "SynTree/Declaration.h" // for TypeDecl, NamedTypeDecl 26 27 #include "SynTree/Type.h" // for Type, BasicType, TypeInstType 27 28 #include "typeops.h" // for typesCompatibleIgnoreQualifiers 29 28 30 29 31 namespace ResolvExpr { … … 338 340 } else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * >( dest ) ) { 339 341 const EnumDecl * base_enum = enumInst->baseEnum; 340 if ( const Type * base = base_enum->base ) { // if the base enum has a base (if it is typed)342 if ( const Type * base = base_enum->base ) { 341 343 if ( const BasicType * enumBaseAstBasic = dynamic_cast< const BasicType *> (base) ) { 342 344 conversionCostFromBasicToBasic(basicType, enumBaseAstBasic); … … 632 634 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 633 635 const ast::EnumDecl * enumDecl = enumInst->base.get(); 634 if ( const ast::Type * enumType = enumDecl->base.get() ) { 636 if ( enumDecl->isTyped && !enumDecl->base.get() ) { 637 cost = Cost::infinity; 638 } else if ( const ast::Type * enumType = enumDecl->base.get() ) { 635 639 if ( const ast::BasicType * enumTypeAsBasic = dynamic_cast<const ast::BasicType *>(enumType) ) { 636 640 conversionCostFromBasicToBasic( basicType, enumTypeAsBasic ); … … 655 659 cost = Cost::safe; 656 660 } 657 } else { 661 } 662 /* 663 else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) { 664 if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) { 665 if (dstFunc->params.empty() && dstFunc->isVarArgs ) { 666 cost = Cost::unsafe; // assign any function to variadic fptr 667 } 668 } 669 else { 670 ast::AssertionSet need, have; // unused 671 ast::OpenVarSet open; 672 env.extractOpenVars(open); 673 ast::TypeEnvironment tenv = env; 674 if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) { 675 cost = Cost::safe; 676 } 677 } 678 // else infinity 679 } 680 */ 681 else { 658 682 int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env ); 659 683 if ( 0 < assignResult && tq1 <= tq2 ) { … … 694 718 const ast::EnumDecl * baseEnum = enumInstType->base; 695 719 if ( const ast::Type * baseType = baseEnum->base ) { 696 cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );720 costCalc( baseType, dst, srcIsLvalue, symtab, env ); 697 721 } else { 698 722 (void)enumInstType; -
src/ResolvExpr/Resolver.cc
r428adbc r7f6a7c9 1478 1478 // enum type is still incomplete at this point. Use `int` instead. 1479 1479 1480 if (dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() )->base->base) { 1480 if ( auto enumBase = dynamic_cast< const ast::EnumInstType * > 1481 ( objectDecl->get_type() )->base->base ) { 1481 1482 objectDecl = fixObjectType( objectDecl, context ); 1482 const ast::Type * enumBase = (dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() )->base->base.get());1483 1483 currentObject = ast::CurrentObject{ 1484 1484 objectDecl->location, … … 1493 1493 } 1494 1494 else { 1495 if ( !objectDecl->isTypeFixed) {1495 if ( !objectDecl->isTypeFixed ) { 1496 1496 auto newDecl = fixObjectType(objectDecl, context); 1497 1497 auto mutDecl = mutate(newDecl); -
src/ResolvExpr/SatisfyAssertions.cpp
r428adbc r7f6a7c9 36 36 #include "AST/SymbolTable.hpp" 37 37 #include "AST/TypeEnvironment.hpp" 38 #include "FindOpenVars.h" 38 39 #include "Common/FilterCombos.h" 39 40 #include "Common/Indenter.h" … … 161 162 162 163 /// Satisfy a single assertion 163 bool satisfyAssertion( ast::AssertionList::value_type & assn, SatState & sat 164 bool satisfyAssertion( ast::AssertionList::value_type & assn, SatState & sat, bool allowConversion = false, bool skipUnbound = false) { 164 165 // skip unused assertions 165 166 if ( ! assn.second.isUsed ) return true; … … 180 181 if (thisArgType.as<ast::PointerType>()) otypeKey = Mangle::Encoding::pointer; 181 182 else if (!isUnboundType(thisArgType)) otypeKey = Mangle::mangle(thisArgType, Mangle::Type | Mangle::NoGenericParams); 183 else if (skipUnbound) return false; 182 184 183 185 candidates = sat.symtab.specialLookupId(kind, otypeKey); … … 205 207 206 208 // only keep candidates which unify 207 if ( unify( toType, adjType, newEnv, newNeed, have, newOpen, sat.symtab ) ) { 208 // set up binding slot for recursive assertions 209 ast::UniqueId crntResnSlot = 0; 210 if ( ! newNeed.empty() ) { 211 crntResnSlot = ++globalResnSlot; 212 for ( auto & a : newNeed ) { a.second.resnSlot = crntResnSlot; } 213 } 214 215 matches.emplace_back( 216 cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ), 217 std::move( newOpen ), crntResnSlot ); 209 210 ast::OpenVarSet closed; 211 findOpenVars( toType, newOpen, closed, newNeed, have, FirstClosed ); 212 findOpenVars( adjType, newOpen, closed, newNeed, have, FirstOpen ); 213 if ( allowConversion ) { 214 if ( auto c = commonType( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) { 215 // set up binding slot for recursive assertions 216 ast::UniqueId crntResnSlot = 0; 217 if ( ! newNeed.empty() ) { 218 crntResnSlot = ++globalResnSlot; 219 for ( auto & a : newNeed ) { a.second.resnSlot = crntResnSlot; } 220 } 221 222 matches.emplace_back( 223 cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ), 224 std::move( newOpen ), crntResnSlot ); 225 } 226 } 227 else { 228 if ( unifyExact( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) { 229 // set up binding slot for recursive assertions 230 ast::UniqueId crntResnSlot = 0; 231 if ( ! newNeed.empty() ) { 232 crntResnSlot = ++globalResnSlot; 233 for ( auto & a : newNeed ) { a.second.resnSlot = crntResnSlot; } 234 } 235 236 matches.emplace_back( 237 cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ), 238 std::move( newOpen ), crntResnSlot ); 239 } 218 240 } 219 241 } … … 413 435 // for each current mutually-compatible set of assertions 414 436 for ( SatState & sat : sats ) { 437 bool allowConversion = false; 415 438 // stop this branch if a better option is already found 416 439 auto it = thresholds.find( pruneKey( *sat.cand ) ); … … 418 441 419 442 // should a limit be imposed? worst case here is O(n^2) but very unlikely to happen. 443 420 444 for (unsigned resetCount = 0; ; ++resetCount) { 421 445 ast::AssertionList next; … … 424 448 for ( auto & assn : sat.need ) { 425 449 // fail early if any assertion is not satisfiable 426 if ( ! satisfyAssertion( assn, sat ) ) {450 if ( ! satisfyAssertion( assn, sat, allowConversion, !next.empty() ) ) { 427 451 next.emplace_back(assn); 428 452 // goto nextSat; … … 433 457 // fail if nothing resolves 434 458 else if (next.size() == sat.need.size()) { 435 Indenter tabs{ 3 }; 436 std::ostringstream ss; 437 ss << tabs << "Unsatisfiable alternative:\n"; 438 print( ss, *sat.cand, ++tabs ); 439 ss << (tabs-1) << "Could not satisfy assertion:\n"; 440 ast::print( ss, next[0].first, tabs ); 441 442 errors.emplace_back( ss.str() ); 443 goto nextSat; 444 } 459 if (allowConversion) { 460 Indenter tabs{ 3 }; 461 std::ostringstream ss; 462 ss << tabs << "Unsatisfiable alternative:\n"; 463 print( ss, *sat.cand, ++tabs ); 464 ss << (tabs-1) << "Could not satisfy assertion:\n"; 465 ast::print( ss, next[0].first, tabs ); 466 467 errors.emplace_back( ss.str() ); 468 goto nextSat; 469 } 470 471 else { 472 allowConversion = true; 473 continue; 474 } 475 } 476 allowConversion = false; 445 477 sat.need = std::move(next); 446 478 } -
src/ResolvExpr/Unify.cc
r428adbc r7f6a7c9 165 165 ast::Type * newFirst = shallowCopy( first ); 166 166 ast::Type * newSecond = shallowCopy( second ); 167 if ( auto temp = dynamic_cast<const ast::EnumInstType *>(first) ) { 168 if ( !dynamic_cast< const ast::EnumInstType * >( second ) ) { 169 const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get()); 170 if ( auto t = baseEnum->base.get() ) { 171 newFirst = ast::shallowCopy( t ); 172 } 173 } 174 } else if ( auto temp = dynamic_cast<const ast::EnumInstType *>(second) ) { 175 const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get()); 176 if ( auto t = baseEnum->base.get() ) { 177 newSecond = ast::shallowCopy( t ); 178 } 179 } 180 167 181 newFirst ->qualifiers = {}; 168 182 newSecond->qualifiers = {}; … … 693 707 } 694 708 709 namespace { 710 /// Replaces ttype variables with their bound types. 711 /// If this isn't done when satifying ttype assertions, then argument lists can have 712 /// different size and structure when they should be compatible. 713 struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor { 714 ast::TypeEnvironment & tenv; 715 716 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {} 717 718 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 719 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) { 720 // expand ttype parameter into its actual type 721 if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) { 722 return clz->bound; 723 } 724 } 725 return typeInst; 726 } 727 }; 728 } 729 730 std::vector< ast::ptr< ast::Type > > flattenList( 731 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env 732 ) { 733 std::vector< ast::ptr< ast::Type > > dst; 734 dst.reserve( src.size() ); 735 for ( const auto & d : src ) { 736 ast::Pass<TtypeExpander_new> expander{ env }; 737 // TtypeExpander pass is impure (may mutate nodes in place) 738 // need to make nodes shared to prevent accidental mutation 739 ast::ptr<ast::Type> dc = d->accept(expander); 740 auto types = flatten( dc ); 741 for ( ast::ptr< ast::Type > & t : types ) { 742 // outermost const, volatile, _Atomic qualifiers in parameters should not play 743 // a role in the unification of function types, since they do not determine 744 // whether a function is callable. 745 // NOTE: **must** consider at least mutex qualifier, since functions can be 746 // overloaded on outermost mutex and a mutex function has different 747 // requirements than a non-mutex function 748 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 749 dst.emplace_back( t ); 750 } 751 } 752 return dst; 753 } 754 695 755 class Unify_new final : public ast::WithShortCircuiting { 696 756 const ast::Type * type2; … … 764 824 765 825 private: 766 /// Replaces ttype variables with their bound types.767 /// If this isn't done when satifying ttype assertions, then argument lists can have768 /// different size and structure when they should be compatible.769 struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor {770 ast::TypeEnvironment & tenv;771 772 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}773 774 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {775 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) {776 // expand ttype parameter into its actual type777 if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) {778 return clz->bound;779 }780 }781 return typeInst;782 }783 };784 785 /// returns flattened version of `src`786 static std::vector< ast::ptr< ast::Type > > flattenList(787 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env788 ) {789 std::vector< ast::ptr< ast::Type > > dst;790 dst.reserve( src.size() );791 for ( const auto & d : src ) {792 ast::Pass<TtypeExpander_new> expander{ env };793 // TtypeExpander pass is impure (may mutate nodes in place)794 // need to make nodes shared to prevent accidental mutation795 ast::ptr<ast::Type> dc = d->accept(expander);796 auto types = flatten( dc );797 for ( ast::ptr< ast::Type > & t : types ) {798 // outermost const, volatile, _Atomic qualifiers in parameters should not play799 // a role in the unification of function types, since they do not determine800 // whether a function is callable.801 // NOTE: **must** consider at least mutex qualifier, since functions can be802 // overloaded on outermost mutex and a mutex function has different803 // requirements than a non-mutex function804 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );805 dst.emplace_back( t );806 }807 }808 return dst;809 }810 811 /// Creates a tuple type based on a list of DeclWithType812 template< typename Iter >813 static const ast::Type * tupleFromTypes( Iter crnt, Iter end ) {814 std::vector< ast::ptr< ast::Type > > types;815 while ( crnt != end ) {816 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure817 // that this results in a flat tuple818 flatten( *crnt, types );819 820 ++crnt;821 }822 823 return new ast::TupleType{ std::move(types) };824 }825 826 826 827 template< typename Iter > … … 1034 1035 private: 1035 1036 /// Creates a tuple type based on a list of Type 1036 static const ast::Type * tupleFromTypes( 1037 const std::vector< ast::ptr< ast::Type > > & tys 1038 ) { 1039 std::vector< ast::ptr< ast::Type > > out; 1040 for ( const ast::Type * ty : tys ) { 1041 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1042 // that this results in a flat tuple 1043 flatten( ty, out ); 1044 } 1045 1046 return new ast::TupleType{ std::move(out) }; 1047 } 1037 1048 1038 1049 1039 static bool unifyList( … … 1217 1207 } 1218 1208 1219 } else if (( common = commonType( t1, t2, widen, symtab, env, open ))) {1209 } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) { 1220 1210 // no exact unification, but common type 1221 1211 auto c = shallowCopy(common.get()); -
src/ResolvExpr/typeops.h
r428adbc r7f6a7c9 138 138 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars ); 139 139 ast::ptr< ast::Type > commonType( 140 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 141 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 140 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 141 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 142 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab 143 ); 144 // in Unify.cc 145 std::vector< ast::ptr< ast::Type > > flattenList( 146 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env 147 ); 142 148 143 149 // in PolyCost.cc … … 181 187 182 188 /// flatten tuple type into existing list of types 183 staticinline void flatten(189 inline void flatten( 184 190 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 185 191 ) { … … 194 200 195 201 /// flatten tuple type into list of types 196 staticinline std::vector< ast::ptr< ast::Type > > flatten( const ast::Type * type ) {202 inline std::vector< ast::ptr< ast::Type > > flatten( const ast::Type * type ) { 197 203 std::vector< ast::ptr< ast::Type > > out; 198 204 out.reserve( type->size() ); … … 200 206 return out; 201 207 } 208 209 template< typename Iter > 210 const ast::Type * tupleFromTypes( Iter crnt, Iter end ) { 211 std::vector< ast::ptr< ast::Type > > types; 212 while ( crnt != end ) { 213 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 214 // that this results in a flat tuple 215 flatten( *crnt, types ); 216 217 ++crnt; 218 } 219 220 221 return new ast::TupleType{ std::move(types) }; 222 } 223 224 inline const ast::Type * tupleFromTypes( 225 const std::vector< ast::ptr< ast::Type > > & tys 226 ) { 227 return tupleFromTypes( tys.begin(), tys.end() ); 228 } 229 230 202 231 203 232 // in TypeEnvironment.cc -
src/SymTab/Mangler.cc
r428adbc r7f6a7c9 65 65 void postvisit( const QualifiedType * qualType ); 66 66 67 void postvisit( const QualifiedNameExpr * qualNameExpr ); 68 67 69 std::string get_mangleName() { return mangleName; } 68 70 private: … … 305 307 mangleName += Encoding::qualifiedTypeEnd; 306 308 } 309 } 310 311 void Mangler_old::postvisit( const QualifiedNameExpr * qual ) { 312 maybeAccept( qual->var, *visitor ); 307 313 } 308 314 … … 417 423 void postvisit( const ast::OneType * oneType ); 418 424 void postvisit( const ast::QualifiedType * qualType ); 425 void postvisit( const ast::QualifiedNameExpr * qualNameExpr ); 419 426 420 427 std::string get_mangleName() { return mangleName; } … … 645 652 mangleName += Encoding::qualifiedTypeEnd; 646 653 } 654 } 655 void Mangler_new::postvisit( const ast::QualifiedNameExpr * qual ) { 656 maybeAccept( qual->var.get(), *visitor ); 647 657 } 648 658 -
src/SymTab/Validate.cc
r428adbc r7f6a7c9 857 857 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 858 858 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 859 } else if ( EnumInstType * enum Decl= dynamic_cast< EnumInstType * >( designatorType ) ) {859 } else if ( EnumInstType * enumInst = dynamic_cast< EnumInstType * >( designatorType ) ) { 860 860 // declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) ); 861 if (enumDecl->baseEnum) { 862 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) ); 861 if ( enumInst->baseEnum ) { 862 const EnumDecl * enumDecl = enumInst->baseEnum; 863 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, enumDecl->isTyped, tyDecl->linkage, enumDecl->base ) ); 863 864 } else { 864 declsToAddBefore.push_back( new EnumDecl( enum Decl->name, noAttributes, tyDecl->linkage ) );865 declsToAddBefore.push_back( new EnumDecl( enumInst->name, noAttributes, tyDecl->linkage ) ); 865 866 } 866 867 } // if -
src/SymTab/ValidateType.cc
r428adbc r7f6a7c9 82 82 void postvisit( QualifiedType * qualType ); 83 83 84 void postvisit( QualifiedNameExpr * qualExpr ); 85 84 86 void postvisit( EnumDecl * enumDecl ); 85 87 void postvisit( StructDecl * structDecl ); … … 157 159 // linking only makes sense for the 'oldest ancestor' of the qualified type 158 160 qualType->parent->accept( * visitor ); 161 } 162 163 void LinkReferenceToTypes_old::postvisit( QualifiedNameExpr * qualExpr ) { 164 const EnumDecl * st = local_indexer->lookupEnum( qualExpr->type_decl->name ); 165 qualExpr->type_decl = const_cast<EnumDecl *>(st); 159 166 } 160 167 -
src/SynTree/Declaration.h
r428adbc r7f6a7c9 145 145 virtual void printShort( std::ostream & os, Indenter indent = {} ) const override; 146 146 147 // TODO: Move to the right place148 147 void checkAssignedValue() const; 149 148 }; … … 338 337 typedef AggregateDecl Parent; 339 338 public: 339 bool isTyped; 340 Type * base; 341 340 342 EnumDecl( const std::string & name, 341 343 const std::list< Attribute * > & attributes = std::list< class Attribute * >(), 342 LinkageSpec::Spec linkage = LinkageSpec::Cforall, 343 Type * baseType = nullptr ) : Parent( name, attributes, linkage ) , base( baseType ){} 344 EnumDecl( const EnumDecl & other ) : Parent( other ), base( other.base ) {} 345 344 bool isTyped = false, LinkageSpec::Spec linkage = LinkageSpec::Cforall, 345 Type * baseType = nullptr ) 346 : Parent( name, attributes, linkage ),isTyped(isTyped), base( baseType ) {} 347 EnumDecl( const EnumDecl & other ) 348 : Parent( other ), isTyped( other.isTyped), base( other.base ) {} 346 349 bool valueOf( Declaration * enumerator, long long int & value ); 347 348 350 virtual EnumDecl * clone() const override { return new EnumDecl( *this ); } 349 351 virtual void accept( Visitor & v ) override { v.visit( this ); } 350 352 virtual void accept( Visitor & v ) const override { v.visit( this ); } 351 353 virtual Declaration * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 352 Type * base; 353 std::unordered_map< std::string, long long int > enumValues; 354 355 std::unordered_map< std::string, long long int > enumValues; // This attribute is unused 354 356 virtual void print( std::ostream & os, Indenter indent = {} ) const override final; 355 357 private: -
src/SynTree/Expression.h
r428adbc r7f6a7c9 163 163 }; 164 164 165 // [Qualifier].name; Qualifier is the type_name from the parser 166 class QualifiedNameExpr : public Expression { 167 public: 168 Declaration * type_decl; 169 std::string name; 170 DeclarationWithType * var; 171 172 QualifiedNameExpr( Declaration * decl, std::string name): Expression(), type_decl(decl), name(name) {} 173 QualifiedNameExpr( const QualifiedNameExpr & other): Expression(other), type_decl(other.type_decl), name(other.name), var(other.var) {} 174 DeclarationWithType * get_var() const { return var; } 175 void set_var( DeclarationWithType * newValue ) { var = newValue; } 176 177 virtual ~QualifiedNameExpr() { 178 delete var; 179 delete type_decl; 180 } 181 182 virtual QualifiedNameExpr * clone() const override { 183 return new QualifiedNameExpr( * this ); 184 } 185 virtual void accept( Visitor & v ) override { v.visit(this); } 186 virtual void accept( Visitor & v ) const override { v.visit(this); } 187 virtual Expression * acceptMutator( Mutator & m ) override { 188 return m.mutate( this ); 189 } 190 191 virtual void print( std::ostream & os, Indenter indent = {} ) const override { 192 type_decl->print( os, indent ); 193 os << name << std::endl; 194 } 195 }; 196 165 197 /// VariableExpr represents an expression that simply refers to the value of a named variable. 166 198 /// Does not take ownership of var. -
src/SynTree/Mutator.h
r428adbc r7f6a7c9 98 98 virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0; 99 99 virtual Expression * mutate( GenericExpr * genExpr ) = 0; 100 virtual Expression * mutate( QualifiedNameExpr * qualifiedNameExpr ) = 0; 100 101 101 102 virtual Type * mutate( VoidType * basicType ) = 0; -
src/SynTree/Statement.cc
r428adbc r7f6a7c9 105 105 }; 106 106 107 BranchStmt::BranchStmt( Label target, Type type ) throw ( SemanticErrorException ):107 BranchStmt::BranchStmt( Label target, Type type ) : 108 108 Statement(), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) { 109 109 //actually this is a syntactic error signaled by the parser … … 113 113 } 114 114 115 BranchStmt::BranchStmt( Expression * computedTarget, Type type ) throw ( SemanticErrorException ):115 BranchStmt::BranchStmt( Expression * computedTarget, Type type ) : 116 116 Statement(), computedTarget( computedTarget ), type( type ) { 117 117 if ( type != BranchStmt::Goto || computedTarget == nullptr ) { … … 211 211 } 212 212 213 CaseStmt::CaseStmt( Expression * condition, const list<Statement *> & statements, bool deflt ) throw ( SemanticErrorException ):213 CaseStmt::CaseStmt( Expression * condition, const list<Statement *> & statements, bool deflt ) : 214 214 Statement(), condition( condition ), stmts( statements ), _isDefault( deflt ) { 215 215 if ( isDefault() && condition != nullptr ) SemanticError( condition, "default case with condition: " ); … … 575 575 } 576 576 577 MutexStmt::MutexStmt( Statement * stmt, const list<Expression *> mutexObjs ) 577 MutexStmt::MutexStmt( Statement * stmt, const list<Expression *> mutexObjs ) 578 578 : Statement(), stmt( stmt ), mutexObjs( mutexObjs ) { } 579 579 -
src/SynTree/Statement.h
r428adbc r7f6a7c9 200 200 std::list<Statement *> stmts; 201 201 202 CaseStmt( Expression * conditions, const std::list<Statement *> & stmts, bool isdef = false ) throw (SemanticErrorException);202 CaseStmt( Expression * conditions, const std::list<Statement *> & stmts, bool isdef = false ); 203 203 CaseStmt( const CaseStmt & other ); 204 204 virtual ~CaseStmt(); … … 289 289 Type type; 290 290 291 BranchStmt( Label target, Type ) throw (SemanticErrorException);292 BranchStmt( Expression * computedTarget, Type ) throw (SemanticErrorException);291 BranchStmt( Label target, Type ); 292 BranchStmt( Expression * computedTarget, Type ); 293 293 294 294 Label get_originalTarget() { return originalTarget; } -
src/SynTree/SynTree.h
r428adbc r7f6a7c9 103 103 class DefaultArgExpr; 104 104 class GenericExpr; 105 class QualifiedNameExpr; 105 106 106 107 class Type; -
src/SynTree/Type.cc
r428adbc r7f6a7c9 80 80 // These must remain in the same order as the corresponding bit fields. 81 81 const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" }; 82 const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_ Thread_local" };82 const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "__thread", "_Thread_local" }; 83 83 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "mutex", "_Atomic" }; 84 84 -
src/SynTree/Type.h
r428adbc r7f6a7c9 84 84 }; // FuncSpecifiers 85 85 86 enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, Threadlocal = 1 << 4, NumStorageClass = 5};86 enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, ThreadlocalGcc = 1 << 4, ThreadlocalC11 = 1 << 5, NumStorageClass = 6 }; 87 87 static const char * StorageClassesNames[]; 88 88 union StorageClasses { … … 93 93 bool is_auto : 1; 94 94 bool is_register : 1; 95 bool is_threadlocal : 1; 95 bool is_threadlocalGcc : 1; 96 bool is_threadlocalC11 : 1; 96 97 }; 97 98 … … 100 101 // equality (==, !=) works implicitly on first field "val", relational operations are undefined. 101 102 BFCommon( StorageClasses, NumStorageClass ) 103 104 bool is_threadlocal_any() { return this->is_threadlocalC11 || this->is_threadlocalGcc; } 102 105 }; // StorageClasses 103 106 … … 342 345 Type * parent; 343 346 Type * child; 344 345 347 QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child ); 346 348 QualifiedType( const QualifiedType & tq ); -
src/SynTree/Visitor.h
r428adbc r7f6a7c9 101 101 virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); } 102 102 virtual void visit( const NameExpr * nameExpr ) = 0; 103 virtual void visit( QualifiedNameExpr * node ) { visit( const_cast<const QualifiedNameExpr*>(node) );} 104 virtual void visit( const QualifiedNameExpr* qualifiednameExpr ) = 0; 103 105 virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); } 104 106 virtual void visit( const CastExpr * castExpr ) = 0; -
src/Tuples/TupleExpansionNew.cpp
r428adbc r7f6a7c9 10 10 // Created On : Mon Aug 23 15:36:09 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jul 29 14:06:00 202213 // Update Count : 212 // Last Modified On : Tue Sep 20 16:17:00 2022 13 // Update Count : 4 14 14 // 15 15 … … 100 100 } 101 101 102 struct TupleAssignExpander { 102 /// Replaces Tuple Assign & Index Expressions, and Tuple Types. 103 struct TupleMainExpander final : 104 public ast::WithCodeLocation, 105 public ast::WithDeclsToAdd<>, 106 public ast::WithGuards, 107 public ast::WithVisitorRef<TupleMainExpander> { 103 108 ast::Expr const * postvisit( ast::TupleAssignExpr const * expr ) { 104 109 // Just move the env on the new top level expression. … … 106 111 &ast::TupleAssignExpr::env, expr->env.get() ); 107 112 } 108 }; 109 110 struct TupleTypeReplacer : 111 public ast::WithGuards, 112 public ast::WithVisitorRef<TupleTypeReplacer>, 113 public ast::WithDeclsToAdd<> { 114 void previsit( ast::ParseNode const * node ) { 115 GuardValue( location ) = &node->location; 116 } 117 118 void previsit( ast::CompoundStmt const * stmt ) { 119 previsit( (ast::ParseNode const *)stmt ); 113 114 void previsit( ast::CompoundStmt const * ) { 120 115 GuardScope( typeMap ); 121 116 } … … 185 180 return newType; 186 181 } 187 private: 188 ScopedMap< int, ast::StructDecl const * > typeMap; 189 CodeLocation const * location = nullptr; 190 }; 191 192 struct TupleIndexExpander { 182 193 183 ast::Expr const * postvisit( ast::TupleIndexExpr const * expr ) { 194 184 CodeLocation const & location = expr->location; … … 221 211 return memberExpr; 222 212 } 213 private: 214 ScopedMap< int, ast::StructDecl const * > typeMap; 223 215 }; 224 216 … … 257 249 } 258 250 259 struct TupleExprExpander {251 struct TupleExprExpander final { 260 252 ast::Expr const * postvisit( ast::TupleExpr const * expr ) { 261 253 return replaceTupleExpr( expr->location, … … 275 267 276 268 void expandTuples( ast::TranslationUnit & translationUnit ) { 277 // These may not have to be seperate passes. 278 ast::Pass<TupleAssignExpander>::run( translationUnit ); 279 ast::Pass<TupleTypeReplacer>::run( translationUnit ); 280 ast::Pass<TupleIndexExpander>::run( translationUnit ); 269 // These can't just be combined simply (there might be a way with work). 270 ast::Pass<TupleMainExpander>::run( translationUnit ); 281 271 ast::Pass<TupleExprExpander>::run( translationUnit ); 282 272 } -
src/Validate/Autogen.cpp
r428adbc r7f6a7c9 10 10 // Created On : Thu Dec 2 13:44:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Jan 27 9:29:00 202213 // Update Count : 112 // Last Modified On : Tue Sep 20 16:00:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 25 25 26 26 #include "AST/Attribute.hpp" 27 #include "AST/Create.hpp" 27 28 #include "AST/Decl.hpp" 28 29 #include "AST/DeclReplacer.hpp" … … 236 237 if ( !enumDecl->body ) return; 237 238 239 // if ( auto enumBaseType = enumDecl->base ) { 240 // if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) { 241 // const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get(); 242 // this->previsit( structDecl ); 243 // } 244 // } 245 238 246 ast::EnumInstType enumInst( enumDecl->name ); 239 247 enumInst.base = enumDecl; … … 321 329 void FuncGenerator::produceForwardDecl( const ast::FunctionDecl * decl ) { 322 330 if (0 != functionNesting) return; 323 ast::FunctionDecl * fwd = ast::deepCopy( decl );324 fwd->stmts = nullptr;331 ast::FunctionDecl * fwd = 332 ( decl->stmts ) ? ast::asForward( decl ) : ast::deepCopy( decl ) ; 325 333 fwd->fixUniqueId(); 326 334 forwards.push_back( fwd ); -
src/Validate/EnumAndPointerDecay.cpp
r428adbc r7f6a7c9 10 10 // Created On : Tue Jun 28 15:50:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Jul 12 14:45:00 202213 // Update Count : 012 // Last Modified On : Tue Sep 20 16:14:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 26 26 namespace { 27 27 28 struct EnumAndPointerDecayCore final : public ast::WithGuards { 29 CodeLocation const * location = nullptr; 30 void previsit( ast::ParseNode const * node ); 28 struct EnumAndPointerDecayCore final : public ast::WithCodeLocation { 31 29 ast::EnumDecl const * previsit( ast::EnumDecl const * decl ); 32 30 ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl ); 33 31 ast::FunctionType const * previsit( ast::FunctionType const * type ); 34 32 }; 35 36 void EnumAndPointerDecayCore::previsit( ast::ParseNode const * node ) {37 GuardValue( location ) = &node->location;38 }39 33 40 34 ast::EnumDecl const * EnumAndPointerDecayCore::previsit( … … 50 44 new ast::EnumInstType( decl, ast::CV::Const ) ); 51 45 } 52 GuardValue( location ) = &decl->location;53 46 return mut; 54 47 } … … 79 72 ast::FunctionDecl const * decl ) { 80 73 auto mut = ast::mutate( decl ); 81 GuardValue( location ) = &decl->location;82 74 ast::ArgumentFlag isVarArgs = mut->type->isVarArgs; 83 75 // It seems fixFunction (via fixFunctionList) does the pointer decay part. -
src/Validate/FixQualifiedTypes.cpp
r428adbc r7f6a7c9 10 10 // Created On : Thr Apr 21 11:13:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Apr 22 11:36:00 202213 // Update Count : 012 // Last Modified On : Tue Sep 20 16:15:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 19 19 #include "AST/TranslationUnit.hpp" 20 20 #include "Validate/NoIdSymbolTable.hpp" 21 #include "SymTab/Mangler.h" // for Mangler 22 #include "AST/LinkageSpec.hpp" // for Linkage 21 23 22 24 namespace Validate { … … 25 27 26 28 struct FixQualifiedTypesCore : 27 public WithNoIdSymbolTable, public ast::WithGuards { 28 CodeLocation const * location = nullptr; 29 30 void previsit( ast::ParseNode const * node ) { 31 GuardValue( location ) = &node->location; 32 } 33 29 public WithNoIdSymbolTable, 30 public ast::WithCodeLocation { 34 31 ast::Type const * postvisit( ast::QualifiedType const * type ) { 35 32 assert( location ); … … 89 86 } 90 87 } 88 89 ast::Expr const * postvisit( ast::QualifiedNameExpr const * t) { 90 assert( location ); 91 if ( t->type_decl ) { 92 auto enumName = t->type_decl->name; 93 const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName ); 94 for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) { 95 if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) { 96 if ( memberAsObj->name == t->name ) { 97 return new ast::VariableExpr( t->location, memberAsObj ); 98 } 99 } else { 100 assertf( false, "unhandled qualified child type"); 101 } 102 } 103 104 105 auto var = new ast::ObjectDecl( t->var->location, t->name, 106 new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall ); 107 var->scopeLevel = 1; // 1 for now; should copy the scopeLevel of the enumValue 108 var->mangleName = Mangle::mangle( var ); 109 return new ast::VariableExpr( t->location, var ); 110 // return ret; 111 } 112 113 return t; 114 } 115 91 116 }; 92 117 -
src/Validate/GenericParameter.cpp
r428adbc r7f6a7c9 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // GenericParameter. hpp -- Generic parameter related passes.7 // GenericParameter.cpp -- Generic parameter related passes. 8 8 // 9 9 // Author : Andrew Beach 10 10 // Created On : Fri Mar 21 10:02:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Apr 22 16:43:00 202213 // Update Count : 112 // Last Modified On : Tue Sep 20 16:28:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 119 119 } 120 120 121 struct ValidateGenericParamsCore : public ast::WithGuards { 122 const CodeLocation * locationPtr = nullptr; 123 124 void previsit( const ast::ParseNode * node ) { 125 GuardValue( locationPtr ) = &node->location; 126 } 127 121 struct ValidateGenericParamsCore : public ast::WithCodeLocation { 128 122 const ast::StructInstType * previsit( const ast::StructInstType * type ) { 129 assert( location Ptr);130 return validateGeneric( *location Ptr, type );123 assert( location ); 124 return validateGeneric( *location, type ); 131 125 } 132 126 133 127 const ast::UnionInstType * previsit( const ast::UnionInstType * type ) { 134 assert( location Ptr);135 return validateGeneric( *location Ptr, type );128 assert( location ); 129 return validateGeneric( *location, type ); 136 130 } 137 131 }; -
src/Validate/LinkReferenceToTypes.cpp
r428adbc r7f6a7c9 10 10 // Created On : Thr Apr 21 11:41:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Jun 28 14:58:00 202213 // Update Count : 112 // Last Modified On : Tue Sep 20 16:17:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 26 26 27 27 struct LinkTypesCore : public WithNoIdSymbolTable, 28 public ast::WithCodeLocation, 28 29 public ast::WithGuards, 29 public ast::WithVisitorRef<LinkTypesCore>, 30 public ast::WithShortCircuiting { 31 30 public ast::WithShortCircuiting, 31 public ast::WithVisitorRef<LinkTypesCore> { 32 32 ast::TypeInstType const * postvisit( ast::TypeInstType const * type ); 33 33 ast::EnumInstType const * postvisit( ast::EnumInstType const * type ); … … 38 38 void postvisit( ast::QualifiedType const * type ); 39 39 40 void previsit( ast::ParseNode const * node );41 42 40 ast::EnumDecl const * postvisit( ast::EnumDecl const * decl ); 43 41 ast::StructDecl const * previsit( ast::StructDecl const * decl ); … … 46 44 void postvisit( ast::UnionDecl const * decl ); 47 45 ast::TraitDecl const * postvisit( ast::TraitDecl const * decl ); 46 ast::QualifiedNameExpr const * previsit( ast::QualifiedNameExpr const * decl); 48 47 49 48 private: … … 59 58 ForwardEnumsType forwardEnums; 60 59 61 const CodeLocation * location = nullptr;62 60 /// true if currently in a generic type body, 63 61 /// so that type parameter instances can be renamed appropriately … … 176 174 // Linking only makes sense for the 'oldest ancestor' of the qualified type. 177 175 type->parent->accept( *visitor ); 178 }179 180 void LinkTypesCore::previsit( ast::ParseNode const * node ) {181 GuardValue( location ) = &node->location;182 176 } 183 177 … … 224 218 GuardValue( inGeneric ) = !decl->params.empty(); 225 219 if ( !inGeneric ) { 226 GuardValue( location ) = &decl->location;227 220 return decl; 228 221 } 229 222 auto mut = ast::mutate( decl ); 230 GuardValue( location ) = &mut->location;231 223 for ( ast::ptr<ast::TypeDecl> & typeDecl : mut->params ) { 232 224 typeDecl.get_and_mutate()->name = "__" + typeDecl->name + "_generic_"; … … 292 284 } 293 285 286 ast::QualifiedNameExpr const * LinkTypesCore::previsit( ast::QualifiedNameExpr const * decl ) { 287 // Try to lookup type 288 if ( auto objDecl = decl->type_decl.as<ast::ObjectDecl>() ) { 289 if ( auto inst = objDecl->type.as<ast::TypeInstType>()) { 290 if ( auto enumDecl = symtab.lookupEnum ( inst->name ) ) { 291 auto mut = ast::mutate( decl ); 292 mut->type_decl = enumDecl; 293 auto enumInst = new ast::EnumInstType( enumDecl ); 294 enumInst->name = decl->name; 295 // Adding result; addCandidate() use result 296 mut->result = enumInst; 297 decl = mut; 298 } 299 } 300 } else if ( auto enumDecl = decl->type_decl.as<ast::EnumDecl>() ) { 301 auto mut = ast::mutate( decl ); 302 auto enumInst = new ast::EnumInstType( enumDecl ); 303 enumInst->name = decl->name; 304 // Adding result; addCandidate() use result 305 mut->result = enumInst; 306 decl = mut; 307 } 308 // ast::EnumDecl const * decl = symtab.lookupEnum( type->name ); 309 // // It's not a semantic error if the enum is not found, just an implicit forward declaration. 310 // if ( decl ) { 311 // // Just linking in the node. 312 // auto mut = ast::mutate( type ); 313 // mut->base = const_cast<ast::EnumDecl *>( decl ); 314 // type = mut; 315 // } 316 return decl; 317 } 318 294 319 } // namespace 295 320 -
src/Validate/ReplaceTypedef.cpp
r428adbc r7f6a7c9 10 10 // Created On : Tue Jun 29 14:59:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jul 13 14:45:00 202213 // Update Count : 112 // Last Modified On : Tue Sep 20 17:00:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 39 39 40 40 struct ReplaceTypedefCore final : 41 public ast::WithVisitorRef<ReplaceTypedefCore>, 41 public ast::WithCodeLocation, 42 public ast::WithDeclsToAdd<>, 42 43 public ast::WithGuards, 43 44 public ast::WithShortCircuiting, 44 public ast::WithDeclsToAdd<> { 45 46 void previsit( ast::ParseNode const * node ); 45 public ast::WithVisitorRef<ReplaceTypedefCore> { 46 47 47 void previsit( ast::QualifiedType const * ); 48 48 ast::Type const * postvisit( ast::QualifiedType const * ); … … 74 74 TypedefMap typedefNames; 75 75 TypeDeclMap typedeclNames; 76 CodeLocation const * nearestLocation = nullptr;77 76 int scopeLevel; 78 77 bool isAtFunctionTop = false; 79 78 }; 80 81 void ReplaceTypedefCore::previsit( ast::ParseNode const * node ) {82 GuardValue( nearestLocation ) = &node->location;83 }84 79 85 80 void ReplaceTypedefCore::previsit( ast::QualifiedType const * ) { … … 115 110 auto rtt = dynamic_cast<ast::BaseInstType *>( ret ); 116 111 if ( !rtt ) { 117 assert( nearestLocation );118 SemanticError( * nearestLocation, "Cannot apply type parameters to base type of " + type->name );112 assert( location ); 113 SemanticError( *location, "Cannot apply type parameters to base type of " + type->name ); 119 114 } 120 115 rtt->params.clear(); … … 129 124 TypeDeclMap::const_iterator base = typedeclNames.find( type->name ); 130 125 if ( base == typedeclNames.end() ) { 131 assert( nearestLocation );132 SemanticError( * nearestLocation, toString( "Use of undefined type ", type->name ) );126 assert( location ); 127 SemanticError( *location, toString( "Use of undefined type ", type->name ) ); 133 128 } 134 129 return ast::mutate_field( type, &ast::TypeInstType::base, base->second ); … … 183 178 } else if ( auto enumType = dynamic_cast<ast::EnumInstType const *>( designatorType ) ) { 184 179 declsToAddBefore.push_back( new ast::EnumDecl( 185 decl->location, enumType->name, {}, decl->linkage,180 decl->location, enumType->name, false, {}, decl->linkage, 186 181 ( (enumType->base) ? enumType->base->base : nullptr ) 187 182 ) ); … … 191 186 192 187 void ReplaceTypedefCore::previsit( ast::TypeDecl const * decl ) { 193 previsit( (ast::ParseNode const *)decl );194 188 TypedefMap::iterator iter = typedefNames.find( decl->name ); 195 189 if ( iter != typedefNames.end() ) { … … 199 193 } 200 194 201 void ReplaceTypedefCore::previsit( ast::FunctionDecl const * decl ) { 202 previsit( (ast::ParseNode const *)decl ); 195 void ReplaceTypedefCore::previsit( ast::FunctionDecl const * ) { 203 196 GuardScope( typedefNames ); 204 197 GuardScope( typedeclNames ); … … 206 199 } 207 200 208 void ReplaceTypedefCore::previsit( ast::ObjectDecl const * decl ) { 209 previsit( (ast::ParseNode const *)decl ); 201 void ReplaceTypedefCore::previsit( ast::ObjectDecl const * ) { 210 202 GuardScope( typedefNames ); 211 203 GuardScope( typedeclNames ); … … 217 209 using DWTVector = std::vector<ast::ptr<ast::DeclWithType>>; 218 210 using DeclVector = std::vector<ast::ptr<ast::TypeDecl>>; 219 CodeLocation const & location = decl->location;211 CodeLocation const & declLocation = decl->location; 220 212 UniqueName paramNamer( decl->name + "Param" ); 221 213 222 214 // Replace the current object declaration with a function declaration. 223 215 ast::FunctionDecl const * newDecl = new ast::FunctionDecl( 224 location,216 declLocation, 225 217 decl->name, 226 218 map_range<DeclVector>( type->forall, []( const ast::TypeInstType * inst ) { … … 230 222 return ast::deepCopy( expr->var ); 231 223 } ), 232 map_range<DWTVector>( type->params, [& location, ¶mNamer]( const ast::Type * type ) {224 map_range<DWTVector>( type->params, [&declLocation, ¶mNamer]( const ast::Type * type ) { 233 225 assert( type ); 234 return new ast::ObjectDecl( location, paramNamer.newName(), ast::deepCopy( type ) );226 return new ast::ObjectDecl( declLocation, paramNamer.newName(), ast::deepCopy( type ) ); 235 227 } ), 236 map_range<DWTVector>( type->returns, [& location, ¶mNamer]( const ast::Type * type ) {228 map_range<DWTVector>( type->returns, [&declLocation, ¶mNamer]( const ast::Type * type ) { 237 229 assert( type ); 238 return new ast::ObjectDecl( location, paramNamer.newName(), ast::deepCopy( type ) );230 return new ast::ObjectDecl( declLocation, paramNamer.newName(), ast::deepCopy( type ) ); 239 231 } ), 240 232 nullptr, … … 249 241 } 250 242 251 void ReplaceTypedefCore::previsit( ast::CastExpr const * expr ) { 252 previsit( (ast::ParseNode const *)expr ); 253 GuardScope( typedefNames ); 254 GuardScope( typedeclNames ); 255 } 256 257 void ReplaceTypedefCore::previsit( ast::CompoundStmt const * expr ) { 258 previsit( (ast::ParseNode const *)expr ); 243 void ReplaceTypedefCore::previsit( ast::CastExpr const * ) { 244 GuardScope( typedefNames ); 245 GuardScope( typedeclNames ); 246 } 247 248 void ReplaceTypedefCore::previsit( ast::CompoundStmt const * ) { 259 249 GuardScope( typedefNames ); 260 250 GuardScope( typedeclNames ); … … 268 258 269 259 ast::StructDecl const * ReplaceTypedefCore::previsit( ast::StructDecl const * decl ) { 270 previsit( (ast::ParseNode const *)decl );271 260 visit_children = false; 272 261 addImplicitTypedef( decl ); … … 275 264 276 265 ast::UnionDecl const * ReplaceTypedefCore::previsit( ast::UnionDecl const * decl ) { 277 previsit( (ast::ParseNode const *)decl );278 266 visit_children = false; 279 267 addImplicitTypedef( decl ); … … 282 270 283 271 void ReplaceTypedefCore::previsit( ast::EnumDecl const * decl ) { 284 previsit( (ast::ParseNode const *)decl );285 272 addImplicitTypedef( decl ); 286 273 } 287 274 288 void ReplaceTypedefCore::previsit( ast::TraitDecl const * decl ) { 289 previsit( (ast::ParseNode const *)decl ); 275 void ReplaceTypedefCore::previsit( ast::TraitDecl const * ) { 290 276 GuardScope( typedefNames ); 291 277 GuardScope( typedeclNames ); -
src/Virtual/ExpandCasts.cc
r428adbc r7f6a7c9 10 10 // Created On : Mon Jul 24 13:59:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 31 10:29:00 202013 // Update Count : 412 // Last Modified On : Thu Aug 11 12:06:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 20 20 #include <string> // for string, allocator, operator==, ope... 21 21 22 #include "AST/Decl.hpp" 23 #include "AST/Expr.hpp" 24 #include "AST/Pass.hpp" 22 25 #include "Common/PassVisitor.h" // for PassVisitor 23 26 #include "Common/ScopedMap.h" // for ScopedMap … … 32 35 namespace Virtual { 33 36 34 static bool is_prefix( const std::string & prefix, const std::string& entire ) { 37 namespace { 38 39 bool is_prefix( const std::string & prefix, const std::string& entire ) { 35 40 size_t const p_size = prefix.size(); 36 41 return (p_size < entire.size() && prefix == entire.substr(0, p_size)); 37 42 } 38 43 39 staticbool is_type_id_object( const ObjectDecl * objectDecl ) {44 bool is_type_id_object( const ObjectDecl * objectDecl ) { 40 45 const std::string & objectName = objectDecl->name; 41 46 return is_prefix( "__cfatid_", objectName ); 47 } 48 49 bool is_type_id_object( const ast::ObjectDecl * decl ) { 50 return is_prefix( "__cfatid_", decl->name ); 42 51 } 43 52 … … 124 133 } 125 134 } 126 127 namespace {128 135 129 136 /// Better error locations for generated casts. … … 229 236 } 230 237 231 } // namespace232 233 238 Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) { 234 239 assertf( castExpr->result, "Virtual Cast target not found before expansion." ); … … 265 270 } 266 271 267 void expandCasts( std::list< Declaration * > & translationUnit ) { 268 PassVisitor<VirtualCastCore> translator; 269 mutateAll( translationUnit, translator ); 270 } 271 } 272 /// Better error locations for generated casts. 273 // TODO: Does the improved distribution of code locations make this unneeded? 274 CodeLocation castLocation( const ast::VirtualCastExpr * castExpr ) { 275 if ( castExpr->location.isSet() ) { 276 return castExpr->location; 277 } else if ( castExpr->arg->location.isSet() ) { 278 return castExpr->arg->location; 279 } else { 280 return CodeLocation(); 281 } 282 } 283 284 [[noreturn]] void castError( ast::VirtualCastExpr const * castExpr, std::string const & message ) { 285 SemanticError( castLocation( castExpr ), message ); 286 } 287 288 class TypeIdTable final { 289 ScopedMap<std::string, ast::ObjectDecl const *> instances; 290 public: 291 void enterScope() { instances.beginScope(); } 292 void leaveScope() { instances.endScope(); } 293 294 // Attempt to insert an instance into the map. If there is a conflict, 295 // returns the previous declaration for error messages. 296 ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) { 297 std::string const & mangledName = 298 Mangle::mangle( typeIdDecl->type, Mangle::typeMode() ); 299 ast::ObjectDecl const *& value = instances[ mangledName ]; 300 if ( value ) { 301 if ( typeIdDecl->storage.is_extern ) { 302 return nullptr; 303 } else if ( !value->storage.is_extern ) { 304 return value; 305 } 306 } 307 value = typeIdDecl; 308 return nullptr; 309 } 310 311 ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) { 312 std::string const & mangledName = 313 Mangle::mangle( typeIdType, Mangle::typeMode() ); 314 auto const it = instances.find( mangledName ); 315 return ( instances.end() == it ) ? nullptr : it->second; 316 } 317 }; 318 319 struct ExpandCastsCore final { 320 void previsit( ast::FunctionDecl const * decl ); 321 void previsit( ast::StructDecl const * decl ); 322 void previsit( ast::ObjectDecl const * decl ); 323 ast::Expr const * postvisit( ast::VirtualCastExpr const * expr ); 324 325 ast::CastExpr const * cast_to_type_id( 326 ast::Expr const * expr, unsigned int level_of_indirection ); 327 328 ast::FunctionDecl const * vcast_decl = nullptr; 329 ast::StructDecl const * info_decl = nullptr; 330 331 TypeIdTable symtab; 332 }; 333 334 void ExpandCastsCore::previsit( ast::FunctionDecl const * decl ) { 335 if ( !vcast_decl && "__cfavir_virtual_cast" == decl->name ) { 336 vcast_decl = decl; 337 } 338 } 339 340 void ExpandCastsCore::previsit( ast::StructDecl const * decl ) { 341 if ( !info_decl && decl->body && "__cfavir_type_info" == decl->name ) { 342 info_decl = decl; 343 } 344 } 345 346 void ExpandCastsCore::previsit( ast::ObjectDecl const * decl ) { 347 if ( is_type_id_object( decl ) ) { 348 // Multiple definitions should be fine because of linkonce. 349 symtab.insert( decl ); 350 } 351 } 352 353 /// Get the base type from a pointer or reference. 354 ast::Type const * getBaseType( ast::ptr<ast::Type> const & type ) { 355 if ( auto target = type.as<ast::PointerType>() ) { 356 return target->base.get(); 357 } else if ( auto target = type.as<ast::ReferenceType>() ) { 358 return target->base.get(); 359 } else { 360 return nullptr; 361 } 362 } 363 364 /// Copy newType, but give the copy the params of the oldType. 365 ast::StructInstType * polyCopy( 366 ast::StructInstType const * oldType, 367 ast::StructInstType const * newType ) { 368 assert( oldType->params.size() == newType->params.size() ); 369 ast::StructInstType * retType = ast::deepCopy( newType ); 370 if ( ! oldType->params.empty() ) { 371 retType->params.clear(); 372 for ( auto oldParams : oldType->params ) { 373 retType->params.push_back( ast::deepCopy( oldParams ) ); 374 } 375 } 376 return retType; 377 } 378 379 /// Follow the "head" field of the structure to get the type that is pointed 380 /// to by that field. 381 ast::StructInstType const * followHeadPointerType( 382 CodeLocation const & errorLocation, 383 ast::StructInstType const * oldType, 384 std::string const & fieldName ) { 385 ast::StructDecl const * oldDecl = oldType->base; 386 assert( oldDecl ); 387 388 // Helper function for throwing semantic errors. 389 auto throwError = [&fieldName, &errorLocation, &oldDecl]( 390 std::string const & message ) { 391 std::string const & context = "While following head pointer of " + 392 oldDecl->name + " named '" + fieldName + "': "; 393 SemanticError( errorLocation, context + message ); 394 }; 395 396 if ( oldDecl->members.empty() ) { 397 throwError( "Type has no fields." ); 398 } 399 ast::ptr<ast::Decl> const & memberDecl = oldDecl->members.front(); 400 assert( memberDecl ); 401 ast::ObjectDecl const * fieldDecl = memberDecl.as<ast::ObjectDecl>(); 402 assert( fieldDecl ); 403 if ( fieldName != fieldDecl->name ) { 404 throwError( "Head field did not have expected name." ); 405 } 406 407 ast::ptr<ast::Type> const & fieldType = fieldDecl->type; 408 if ( nullptr == fieldType ) { 409 throwError( "Could not get head field." ); 410 } 411 auto ptrType = fieldType.as<ast::PointerType>(); 412 if ( nullptr == ptrType ) { 413 throwError( "First field is not a pointer type." ); 414 } 415 assert( ptrType->base ); 416 auto newType = ptrType->base.as<ast::StructInstType>(); 417 if ( nullptr == newType ) { 418 throwError( "First field does not point to a structure type." ); 419 } 420 421 return polyCopy( oldType, newType ); 422 } 423 424 /// Get the type-id type from a virtual type. 425 ast::StructInstType const * getTypeIdType( 426 CodeLocation const & errorLocation, 427 ast::Type const * type ) { 428 auto typeInst = dynamic_cast<ast::StructInstType const *>( type ); 429 if ( nullptr == typeInst ) { 430 return nullptr; 431 } 432 ast::ptr<ast::StructInstType> tableInst = 433 followHeadPointerType( errorLocation, typeInst, "virtual_table" ); 434 if ( nullptr == tableInst ) { 435 return nullptr; 436 } 437 ast::StructInstType const * typeIdInst = 438 followHeadPointerType( errorLocation, tableInst, "__cfavir_typeid" ); 439 return typeIdInst; 440 } 441 442 ast::Expr const * ExpandCastsCore::postvisit( 443 ast::VirtualCastExpr const * expr ) { 444 assertf( expr->result, "Virtual cast target not found before expansion." ); 445 446 assert( vcast_decl ); 447 assert( info_decl ); 448 449 ast::Type const * base_type = getBaseType( expr->result ); 450 if ( nullptr == base_type ) { 451 castError( expr, "Virtual cast target must be a pointer or reference type." ); 452 } 453 ast::StructInstType const * type_id_type = 454 getTypeIdType( castLocation( expr ), base_type ); 455 if ( nullptr == type_id_type ) { 456 castError( expr, "Ill formed virtual cast target type." ); 457 } 458 ast::ObjectDecl const * type_id = symtab.lookup( type_id_type ); 459 if ( nullptr == type_id ) { 460 // I'm trying to give a different error for polymorpic types as 461 // different things can go wrong there. 462 if ( type_id_type->params.empty() ) { 463 castError( expr, "Virtual cast does not target a virtual type." ); 464 } else { 465 castError( expr, "Virtual cast does not target a type with a " 466 "type id (possible missing virtual table)." ); 467 } 468 } 469 470 return new ast::CastExpr( expr->location, 471 new ast::ApplicationExpr( expr->location, 472 ast::VariableExpr::functionPointer( expr->location, vcast_decl ), 473 { 474 cast_to_type_id( 475 new ast::AddressExpr( expr->location, 476 new ast::VariableExpr( expr->location, type_id ) ), 477 1 ), 478 cast_to_type_id( expr->arg, 2 ), 479 } 480 ), 481 ast::deepCopy( expr->result ) 482 ); 483 } 484 485 ast::CastExpr const * ExpandCastsCore::cast_to_type_id( 486 ast::Expr const * expr, unsigned int level_of_indirection ) { 487 assert( info_decl ); 488 ast::Type * type = new ast::StructInstType( info_decl, ast::CV::Const ); 489 for ( unsigned int i = 0 ; i < level_of_indirection ; ++i ) { 490 type = new ast::PointerType( type ); 491 } 492 return new ast::CastExpr( expr->location, expr, type ); 493 } 494 495 } // namespace 496 497 void expandCasts( std::list< Declaration * > & translationUnit ) { 498 PassVisitor<VirtualCastCore> translator; 499 mutateAll( translationUnit, translator ); 500 } 501 502 void expandCasts( ast::TranslationUnit & translationUnit ) { 503 ast::Pass<ExpandCastsCore>::run( translationUnit ); 504 } 505 506 } // namespace Virtual -
src/Virtual/ExpandCasts.h
r428adbc r7f6a7c9 10 10 // Created On : Mon Jul 24 13:54:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 25 14:51:00 201713 // Update Count : 012 // Last Modified On : Fri Jul 29 14:40:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 19 19 20 20 class Declaration; 21 namespace ast { 22 class TranslationUnit; 23 } 21 24 22 25 namespace Virtual { 23 void expandCasts( std::list< Declaration * > & translationUnit ); 24 // Breaks all virtual cast nodes up into translatable nodes. 26 void expandCasts( std::list< Declaration * > & translationUnit ); 27 void expandCasts( ast::TranslationUnit & translationUnit ); 28 // Breaks all virtual cast nodes up into translatable nodes. 25 29 26 30 // Later this might just set some information so it can happen at CodeGen. 27 31 28 32 } -
src/config.h.in
r428adbc r7f6a7c9 27 27 /* Location of cfa install. */ 28 28 #undef CFA_PREFIX 29 30 /* Sets whether or not to use the new-ast, this is adefault value and can be31 overrided by --old-ast and --new-ast */32 #undef CFA_USE_NEW_AST33 29 34 30 /* Major.Minor */ -
src/main.cc
r428adbc r7f6a7c9 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jul 18 11:08:00 202213 // Update Count : 67 612 // Last Modified On : Thu Sep 15 13:58:00 2022 13 // Update Count : 678 14 14 // 15 15 … … 38 38 #include "CodeGen/Generate.h" // for generate 39 39 #include "CodeGen/LinkOnce.h" // for translateLinkOnce 40 #include "CodeTools/DeclStats.h" // for printDeclStats41 #include "CodeTools/ResolvProtoDump.h" // for dumpAsResolvProto42 40 #include "CodeTools/TrackLoc.h" // for fillLocations 43 41 #include "Common/CodeLocationTools.hpp" // for forceFillCodeLocations … … 45 43 #include "Common/DeclStats.hpp" // for printDeclStats 46 44 #include "Common/ResolvProtoDump.hpp" // for dumpAsResolverProto 47 #include "Common/Stats.h" 48 #include "Common/PassVisitor.h" 49 #include "Common/SemanticError.h" // for SemanticError 45 #include "Common/Stats.h" // for Stats 50 46 #include "Common/UnimplementedError.h" // for UnimplementedError 51 47 #include "Common/utility.h" // for deleteAll, filter, printAll … … 53 49 #include "Concurrency/Waitfor.h" // for generateWaitfor 54 50 #include "ControlStruct/ExceptDecl.h" // for translateExcept 55 #include "ControlStruct/ExceptTranslate.h" // for translate EHM51 #include "ControlStruct/ExceptTranslate.h" // for translateThrows, translat... 56 52 #include "ControlStruct/FixLabels.hpp" // for fixLabels 57 53 #include "ControlStruct/HoistControlDecls.hpp" // hoistControlDecls 58 #include "ControlStruct/Mutate.h" // for mutate59 54 #include "GenPoly/Box.h" // for box 60 55 #include "GenPoly/InstantiateGeneric.h" // for instantiateGeneric … … 66 61 #include "Parser/ParseNode.h" // for DeclarationNode, buildList 67 62 #include "Parser/TypedefTable.h" // for TypedefTable 68 #include "ResolvExpr/AlternativePrinter.h" // for AlternativePrinter69 63 #include "ResolvExpr/CandidatePrinter.hpp" // for printCandidates 70 64 #include "ResolvExpr/Resolver.h" // for resolve 71 #include "SymTab/Validate.h" // for validate72 #include "SymTab/ValidateType.h" // for linkReferenceToTypes73 65 #include "SynTree/LinkageSpec.h" // for Spec, Cforall, Intrinsic 74 66 #include "SynTree/Declaration.h" // for Declaration 75 #include "SynTree/Visitor.h" // for acceptAll76 67 #include "Tuples/Tuples.h" // for expandMemberTuples, expan... 77 68 #include "Validate/Autogen.hpp" // for autogenerateRoutines … … 330 321 Stats::Time::StopBlock(); 331 322 332 if( useNewAST ) { 333 if (Stats::Counters::enabled) { 334 ast::pass_visitor_stats.avg = Stats::Counters::build<Stats::Counters::AverageCounter<double>>("Average Depth - New"); 335 ast::pass_visitor_stats.max = Stats::Counters::build<Stats::Counters::MaxCounter<double>>("Max depth - New"); 336 } 337 auto transUnit = convert( move( translationUnit ) ); 338 339 forceFillCodeLocations( transUnit ); 340 341 PASS( "Translate Exception Declarations", ControlStruct::translateExcept( transUnit ) ); 342 if ( exdeclp ) { 343 dump( move( transUnit ) ); 344 return EXIT_SUCCESS; 345 } 346 347 PASS( "Verify Ctor, Dtor & Assign", Validate::verifyCtorDtorAssign( transUnit ) ); 348 PASS( "Hoist Type Decls", Validate::hoistTypeDecls( transUnit ) ); 349 // Hoist Type Decls pulls some declarations out of contexts where 350 // locations are not tracked. Perhaps they should be, but for now 351 // the full fill solves it. 352 forceFillCodeLocations( transUnit ); 353 354 PASS( "Replace Typedefs", Validate::replaceTypedef( transUnit ) ); 355 PASS( "Fix Return Types", Validate::fixReturnTypes( transUnit ) ); 356 PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers( transUnit ) ); 357 358 PASS( "Link Reference To Types", Validate::linkReferenceToTypes( transUnit ) ); 359 360 PASS( "Fix Qualified Types", Validate::fixQualifiedTypes( transUnit ) ); 361 PASS( "Hoist Struct", Validate::hoistStruct( transUnit ) ); 362 PASS( "Eliminate Typedef", Validate::eliminateTypedef( transUnit ) ); 363 PASS( "Validate Generic Parameters", Validate::fillGenericParameters( transUnit ) ); 364 PASS( "Translate Dimensions", Validate::translateDimensionParameters( transUnit ) ); 365 PASS( "Check Function Returns", Validate::checkReturnStatements( transUnit ) ); 366 PASS( "Fix Return Statements", InitTweak::fixReturnStatements( transUnit ) ); 367 PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) ); 368 PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) ); 369 PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls( transUnit ) ); 370 371 PASS( "Generate Autogen Routines", Validate::autogenerateRoutines( transUnit ) ); 372 373 PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) ); 374 PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) ); 375 PASS( "Compound Literal", Validate::handleCompoundLiterals( transUnit ) ); 376 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer( transUnit ) ); 377 PASS( "Find Global Decls", Validate::findGlobalDecls( transUnit ) ); 378 PASS( "Fix Label Address", Validate::fixLabelAddresses( transUnit ) ); 379 380 if ( symtabp ) { 381 return EXIT_SUCCESS; 382 } // if 383 384 if ( expraltp ) { 385 ResolvExpr::printCandidates( transUnit ); 386 return EXIT_SUCCESS; 387 } // if 388 389 if ( validp ) { 390 dump( move( transUnit ) ); 391 return EXIT_SUCCESS; 392 } // if 393 394 PASS( "Translate Throws", ControlStruct::translateThrows( transUnit ) ); 395 PASS( "Fix Labels", ControlStruct::fixLabels( transUnit ) ); 396 PASS( "Fix Names", CodeGen::fixNames( transUnit ) ); 397 PASS( "Gen Init", InitTweak::genInit( transUnit ) ); 398 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( transUnit ) ); 399 400 if ( libcfap ) { 401 // Generate the bodies of cfa library functions. 402 LibCfa::makeLibCfa( transUnit ); 403 } // if 404 405 if ( declstatsp ) { 406 printDeclStats( transUnit ); 407 return EXIT_SUCCESS; 408 } // if 409 410 if ( bresolvep ) { 411 dump( move( transUnit ) ); 412 return EXIT_SUCCESS; 413 } // if 414 415 if ( resolvprotop ) { 416 dumpAsResolverProto( transUnit ); 417 return EXIT_SUCCESS; 418 } // if 419 420 PASS( "Resolve", ResolvExpr::resolve( transUnit ) ); 421 if ( exprp ) { 422 dump( move( transUnit ) ); 423 return EXIT_SUCCESS; 424 } // if 425 426 forceFillCodeLocations( transUnit ); 427 428 PASS( "Fix Init", InitTweak::fix(transUnit, buildingLibrary())); 429 430 // fix ObjectDecl - replaces ConstructorInit nodes 431 if ( ctorinitp ) { 432 dump( move( transUnit ) ); 433 return EXIT_SUCCESS; 434 } // if 435 436 // Currently not working due to unresolved issues with UniqueExpr 437 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( transUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused 438 439 PASS( "Translate Tries", ControlStruct::translateTries( transUnit ) ); 440 PASS( "Gen Waitfor", Concurrency::generateWaitFor( transUnit ) ); 441 442 // Needs to happen before tuple types are expanded. 443 PASS( "Convert Specializations", GenPoly::convertSpecializations( transUnit ) ); 444 445 PASS( "Expand Tuples", Tuples::expandTuples( transUnit ) ); 446 447 translationUnit = convert( move( transUnit ) ); 448 } else { 449 PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) ); 450 if ( exdeclp ) { 451 dump( translationUnit ); 452 return EXIT_SUCCESS; 453 } // if 454 455 // add the assignment statement after the initialization of a type parameter 456 PASS( "Validate", SymTab::validate( translationUnit ) ); 457 458 if ( symtabp ) { 459 deleteAll( translationUnit ); 460 return EXIT_SUCCESS; 461 } // if 462 463 if ( expraltp ) { 464 PassVisitor<ResolvExpr::AlternativePrinter> printer( cout ); 465 acceptAll( translationUnit, printer ); 466 return EXIT_SUCCESS; 467 } // if 468 469 if ( validp ) { 470 dump( translationUnit ); 471 return EXIT_SUCCESS; 472 } // if 473 474 PASS( "Translate Throws", ControlStruct::translateThrows( translationUnit ) ); 475 PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) ); 476 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) ); 477 PASS( "Gen Init", InitTweak::genInit( translationUnit ) ); 478 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) ); 479 480 if ( libcfap ) { 481 // Generate the bodies of cfa library functions. 482 LibCfa::makeLibCfa( translationUnit ); 483 } // if 484 485 if ( declstatsp ) { 486 CodeTools::printDeclStats( translationUnit ); 487 deleteAll( translationUnit ); 488 return EXIT_SUCCESS; 489 } // if 490 491 if ( bresolvep ) { 492 dump( translationUnit ); 493 return EXIT_SUCCESS; 494 } // if 495 496 CodeTools::fillLocations( translationUnit ); 497 498 if ( resolvprotop ) { 499 CodeTools::dumpAsResolvProto( translationUnit ); 500 return EXIT_SUCCESS; 501 } // if 502 503 PASS( "Resolve", ResolvExpr::resolve( translationUnit ) ); 504 if ( exprp ) { 505 dump( translationUnit ); 506 return EXIT_SUCCESS; 507 } 508 509 PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) ); 510 511 // fix ObjectDecl - replaces ConstructorInit nodes 512 if ( ctorinitp ) { 513 dump ( translationUnit ); 514 return EXIT_SUCCESS; 515 } // if 516 517 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused 518 PASS( "Translate Tries", ControlStruct::translateTries( translationUnit ) ); 519 PASS( "Gen Waitfor", Concurrency::generateWaitFor( translationUnit ) ); 520 PASS( "Convert Specializations", GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded 521 PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this? 323 if (Stats::Counters::enabled) { 324 ast::pass_visitor_stats.avg = Stats::Counters::build<Stats::Counters::AverageCounter<double>>("Average Depth - New"); 325 ast::pass_visitor_stats.max = Stats::Counters::build<Stats::Counters::MaxCounter<double>>("Max depth - New"); 522 326 } 327 auto transUnit = convert( std::move( translationUnit ) ); 328 329 forceFillCodeLocations( transUnit ); 330 331 PASS( "Translate Exception Declarations", ControlStruct::translateExcept( transUnit ) ); 332 if ( exdeclp ) { 333 dump( std::move( transUnit ) ); 334 return EXIT_SUCCESS; 335 } 336 337 PASS( "Verify Ctor, Dtor & Assign", Validate::verifyCtorDtorAssign( transUnit ) ); 338 PASS( "Hoist Type Decls", Validate::hoistTypeDecls( transUnit ) ); 339 // Hoist Type Decls pulls some declarations out of contexts where 340 // locations are not tracked. Perhaps they should be, but for now 341 // the full fill solves it. 342 forceFillCodeLocations( transUnit ); 343 344 PASS( "Replace Typedefs", Validate::replaceTypedef( transUnit ) ); 345 PASS( "Fix Return Types", Validate::fixReturnTypes( transUnit ) ); 346 PASS( "Enum and Pointer Decay", Validate::decayEnumsAndPointers( transUnit ) ); 347 348 PASS( "Link Reference To Types", Validate::linkReferenceToTypes( transUnit ) ); 349 350 PASS( "Fix Qualified Types", Validate::fixQualifiedTypes( transUnit ) ); 351 PASS( "Hoist Struct", Validate::hoistStruct( transUnit ) ); 352 PASS( "Eliminate Typedef", Validate::eliminateTypedef( transUnit ) ); 353 PASS( "Validate Generic Parameters", Validate::fillGenericParameters( transUnit ) ); 354 PASS( "Translate Dimensions", Validate::translateDimensionParameters( transUnit ) ); 355 PASS( "Check Function Returns", Validate::checkReturnStatements( transUnit ) ); 356 PASS( "Fix Return Statements", InitTweak::fixReturnStatements( transUnit ) ); 357 PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) ); 358 PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) ); 359 PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls( transUnit ) ); 360 361 PASS( "Generate Autogen Routines", Validate::autogenerateRoutines( transUnit ) ); 362 363 PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) ); 364 PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) ); 365 PASS( "Compound Literal", Validate::handleCompoundLiterals( transUnit ) ); 366 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer( transUnit ) ); 367 PASS( "Find Global Decls", Validate::findGlobalDecls( transUnit ) ); 368 PASS( "Fix Label Address", Validate::fixLabelAddresses( transUnit ) ); 369 370 if ( symtabp ) { 371 return EXIT_SUCCESS; 372 } // if 373 374 if ( expraltp ) { 375 ResolvExpr::printCandidates( transUnit ); 376 return EXIT_SUCCESS; 377 } // if 378 379 if ( validp ) { 380 dump( std::move( transUnit ) ); 381 return EXIT_SUCCESS; 382 } // if 383 384 PASS( "Translate Throws", ControlStruct::translateThrows( transUnit ) ); 385 PASS( "Fix Labels", ControlStruct::fixLabels( transUnit ) ); 386 PASS( "Fix Names", CodeGen::fixNames( transUnit ) ); 387 PASS( "Gen Init", InitTweak::genInit( transUnit ) ); 388 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( transUnit ) ); 389 390 if ( libcfap ) { 391 // Generate the bodies of cfa library functions. 392 LibCfa::makeLibCfa( transUnit ); 393 } // if 394 395 if ( declstatsp ) { 396 printDeclStats( transUnit ); 397 return EXIT_SUCCESS; 398 } // if 399 400 if ( bresolvep ) { 401 dump( std::move( transUnit ) ); 402 return EXIT_SUCCESS; 403 } // if 404 405 if ( resolvprotop ) { 406 dumpAsResolverProto( transUnit ); 407 return EXIT_SUCCESS; 408 } // if 409 410 PASS( "Resolve", ResolvExpr::resolve( transUnit ) ); 411 if ( exprp ) { 412 dump( std::move( transUnit ) ); 413 return EXIT_SUCCESS; 414 } // if 415 416 forceFillCodeLocations( transUnit ); 417 418 PASS( "Fix Init", InitTweak::fix(transUnit, buildingLibrary())); 419 420 // fix ObjectDecl - replaces ConstructorInit nodes 421 if ( ctorinitp ) { 422 dump( std::move( transUnit ) ); 423 return EXIT_SUCCESS; 424 } // if 425 426 // Currently not working due to unresolved issues with UniqueExpr 427 PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( transUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused 428 429 PASS( "Translate Tries", ControlStruct::translateTries( transUnit ) ); 430 PASS( "Gen Waitfor", Concurrency::generateWaitFor( transUnit ) ); 431 432 // Needs to happen before tuple types are expanded. 433 PASS( "Convert Specializations", GenPoly::convertSpecializations( transUnit ) ); 434 435 PASS( "Expand Tuples", Tuples::expandTuples( transUnit ) ); 523 436 524 437 if ( tuplep ) { 525 dump( translationUnit ); 526 return EXIT_SUCCESS; 527 } // if 528 529 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM 530 531 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) ); 438 dump( std::move( transUnit ) ); 439 return EXIT_SUCCESS; 440 } // if 441 442 // Must come after Translate Tries. 443 PASS( "Virtual Expand Casts", Virtual::expandCasts( transUnit ) ); 444 445 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( transUnit ) ); 446 447 translationUnit = convert( std::move( transUnit ) ); 448 532 449 if ( genericsp ) { 533 450 dump( translationUnit ); … … 612 529 613 530 614 static const char optstring[] = ":c:ghlLmNnpd OAP:S:twW:D:";531 static const char optstring[] = ":c:ghlLmNnpdP:S:twW:D:"; 615 532 616 533 enum { PreludeDir = 128 }; … … 626 543 { "prototypes", no_argument, nullptr, 'p' }, 627 544 { "deterministic-out", no_argument, nullptr, 'd' }, 628 { "old-ast", no_argument, nullptr, 'O'},629 { "new-ast", no_argument, nullptr, 'A'},630 545 { "print", required_argument, nullptr, 'P' }, 631 546 { "prelude-dir", required_argument, nullptr, PreludeDir }, … … 649 564 "do not generate prelude prototypes => prelude not printed", // -p 650 565 "only print deterministic output", // -d 651 "Use the old-ast", // -O652 "Use the new-ast", // -A653 566 "print", // -P 654 567 "<directory> prelude directory for debug/nodebug", // no flag … … 759 672 deterministic_output = true; 760 673 break; 761 case 'O': // don't print non-deterministic output762 useNewAST = false;763 break;764 case 'A': // don't print non-deterministic output765 useNewAST = true;766 break;767 674 case 'P': // print options 768 675 for ( int i = 0;; i += 1 ) { … … 881 788 882 789 static void dump( ast::TranslationUnit && transUnit, ostream & out ) { 883 std::list< Declaration * > translationUnit = convert( move( transUnit ) );790 std::list< Declaration * > translationUnit = convert( std::move( transUnit ) ); 884 791 dump( translationUnit, out ); 885 792 }
Note:
See TracChangeset
for help on using the changeset viewer.