Changes in / [204358b:10248ae0]
- Location:
- src
- Files:
-
- 1 deleted
- 13 edited
-
AST/CVQualifiers.hpp (modified) (2 diffs)
-
AST/Convert.cpp (modified) (1 diff)
-
AST/Decl.hpp (modified) (18 diffs)
-
AST/Expr.cpp (deleted)
-
AST/Expr.hpp (modified) (6 diffs)
-
AST/Fwd.hpp (modified) (2 diffs)
-
AST/Init.hpp (modified) (7 diffs)
-
AST/Node.hpp (modified) (3 diffs)
-
AST/Stmt.hpp (modified) (25 diffs)
-
AST/Type.hpp (modified) (26 diffs)
-
AST/Visitor.hpp (modified) (1 diff)
-
AST/porting.md (modified) (7 diffs)
-
ResolvExpr/Unify.cc (modified) (3 diffs)
-
ResolvExpr/typeops.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/CVQualifiers.hpp
r204358b r10248ae0 59 59 // ordering is a subtype relationship over qualifiers, e.g. `int` => `const int` is free 60 60 61 inlinebool operator== ( Qualifiers a, Qualifiers b ) {61 bool operator== ( Qualifiers a, Qualifiers b ) { 62 62 return (a.val & EquivQualifiers) == (b.val & EquivQualifiers); 63 63 } 64 inlinebool operator!= ( Qualifiers a, Qualifiers b ) {64 bool operator!= ( Qualifiers a, Qualifiers b ) { 65 65 return !(a == b); 66 66 } 67 inlinebool operator<= ( Qualifiers a, Qualifiers b ) {67 bool operator<= ( Qualifiers a, Qualifiers b ) { 68 68 return a.is_const <= b.is_const // non-const converts to const for free 69 69 && a.is_volatile <= b.is_volatile // non-volatile converts to volatile for free … … 71 71 && a.is_atomic == b.is_atomic; // atomicity must be preserved in free conversion 72 72 } 73 inlinebool operator< ( Qualifiers a, Qualifiers b ) { return a != b && a <= b; }74 inlinebool operator>= ( Qualifiers a, Qualifiers b ) { return b <= a; }75 inlinebool operator> ( Qualifiers a, Qualifiers b ) { return b < a; }73 bool operator< ( Qualifiers a, Qualifiers b ) { return a != b && a <= b; } 74 bool operator>= ( Qualifiers a, Qualifiers b ) { return b <= a; } 75 bool operator> ( Qualifiers a, Qualifiers b ) { return b < a; } 76 76 77 77 } -
src/AST/Convert.cpp
r204358b r10248ae0 413 413 } 414 414 415 virtual void visit( AttrExpr * ) override final { 416 417 } 418 415 419 virtual void visit( LogicalExpr * ) override final { 416 420 -
src/AST/Decl.hpp
r204358b r10248ae0 30 30 #include "Parser/ParseNode.h" // for DeclarationNode::Aggregate 31 31 32 // Must be included in *all* AST classes; should be #undef'd at the end of the file33 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);34 35 32 namespace ast { 33 34 class Attribute; 35 class Expr; 36 class Init; 37 class TypeDecl; 36 38 37 39 /// Base declaration class … … 58 60 private: 59 61 Decl * clone() const override = 0; 60 MUTATE_FRIEND61 62 }; 62 63 … … 91 92 private: 92 93 DeclWithType * clone() const override = 0; 93 MUTATE_FRIEND94 94 }; 95 95 … … 113 113 private: 114 114 ObjectDecl * clone() const override { return new ObjectDecl{ *this }; } 115 MUTATE_FRIEND 115 116 /// Must be copied in ALL derived classes 117 template<typename node_t> 118 friend auto mutate(const node_t * node); 116 119 }; 117 120 … … 137 140 private: 138 141 FunctionDecl * clone() const override { return new FunctionDecl( *this ); } 139 MUTATE_FRIEND 142 143 /// Must be copied in ALL derived classes 144 template<typename node_t> 145 friend auto mutate(const node_t * node); 140 146 }; 141 147 … … 144 150 public: 145 151 ptr<Type> base; 146 std::vector<ptr<TypeDecl>> param s;152 std::vector<ptr<TypeDecl>> parameters; 147 153 std::vector<ptr<DeclWithType>> assertions; 148 154 149 155 NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 150 156 Type* b, Linkage::Spec spec = Linkage::Cforall ) 151 : Decl( loc, name, storage, spec ), base( b ), param s(), assertions() {}157 : Decl( loc, name, storage, spec ), base( b ), parameters(), assertions() {} 152 158 153 159 /// Produces a name for the kind of alias … … 156 162 private: 157 163 NamedTypeDecl* clone() const override = 0; 158 MUTATE_FRIEND159 164 }; 160 165 … … 198 203 private: 199 204 TypeDecl * clone() const override { return new TypeDecl{ *this }; } 200 MUTATE_FRIEND 205 206 /// Must be copied in ALL derived classes 207 template<typename node_t> 208 friend auto mutate(const node_t * node); 201 209 }; 202 210 … … 213 221 private: 214 222 TypedefDecl * clone() const override { return new TypedefDecl{ *this }; } 215 MUTATE_FRIEND 223 224 /// Must be copied in ALL derived classes 225 template<typename node_t> 226 friend auto mutate(const node_t * node); 216 227 }; 217 228 … … 220 231 public: 221 232 std::vector<ptr<Decl>> members; 222 std::vector<ptr<TypeDecl>> param s;233 std::vector<ptr<TypeDecl>> parameters; 223 234 std::vector<ptr<Attribute>> attributes; 224 235 bool body = false; … … 227 238 AggregateDecl( const CodeLocation& loc, const std::string& name, 228 239 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall ) 229 : Decl( loc, name, Storage::Classes{}, linkage ), members(), param s(),240 : Decl( loc, name, Storage::Classes{}, linkage ), members(), parameters(), 230 241 attributes( std::move(attrs) ) {} 231 242 232 243 AggregateDecl* set_body( bool b ) { body = b; return this; } 233 234 private:235 AggregateDecl * clone() const override = 0;236 MUTATE_FRIEND237 244 238 245 protected: … … 258 265 private: 259 266 StructDecl * clone() const override { return new StructDecl{ *this }; } 260 MUTATE_FRIEND 267 268 /// Must be copied in ALL derived classes 269 template<typename node_t> 270 friend auto mutate(const node_t * node); 261 271 262 272 std::string typeString() const override { return "struct"; } … … 273 283 private: 274 284 UnionDecl * clone() const override { return new UnionDecl{ *this }; } 275 MUTATE_FRIEND 285 286 /// Must be copied in ALL derived classes 287 template<typename node_t> 288 friend auto mutate(const node_t * node); 276 289 277 290 std::string typeString() const override { return "union"; } … … 291 304 private: 292 305 EnumDecl * clone() const override { return new EnumDecl{ *this }; } 293 MUTATE_FRIEND 306 307 /// Must be copied in ALL derived classes 308 template<typename node_t> 309 friend auto mutate(const node_t * node); 294 310 295 311 std::string typeString() const override { return "enum"; } … … 309 325 private: 310 326 TraitDecl * clone() const override { return new TraitDecl{ *this }; } 311 MUTATE_FRIEND 327 328 /// Must be copied in ALL derived classes 329 template<typename node_t> 330 friend auto mutate(const node_t * node); 312 331 313 332 std::string typeString() const override { return "trait"; } … … 324 343 private: 325 344 AsmDecl *clone() const override { return new AsmDecl( *this ); } 326 MUTATE_FRIEND 345 346 /// Must be copied in ALL derived classes 347 template<typename node_t> 348 friend auto mutate(const node_t * node); 327 349 }; 328 350 … … 338 360 private: 339 361 StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 340 MUTATE_FRIEND 362 363 /// Must be copied in ALL derived classes 364 template<typename node_t> 365 friend auto mutate(const node_t * node); 341 366 }; 342 367 … … 377 402 } 378 403 379 #undef MUTATE_FRIEND380 381 404 // Local Variables: // 382 405 // tab-width: 4 // -
src/AST/Expr.hpp
r204358b r10248ae0 18 18 #include <cassert> 19 19 #include <map> 20 #include <string>21 20 #include <utility> // for move 22 21 #include <vector> 23 22 24 23 #include "Fwd.hpp" // for UniqueId 25 #include "Label.hpp"26 24 #include "ParseNode.hpp" 27 25 #include "Visitor.hpp" 28 29 // Must be included in *all* AST classes; should be #undef'd at the end of the file30 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);31 26 32 27 namespace ast { … … 122 117 bool extension = false; 123 118 124 Expr( const CodeLocation & loc, const Type * res = nullptr ) 125 : ParseNode( loc ), result( res ), env(), inferred() {} 119 Expr(const CodeLocation & loc ) : ParseNode( loc ), result(), env(), inferred() {} 126 120 127 121 Expr * set_extension( bool ex ) { extension = ex; return this; } … … 130 124 private: 131 125 Expr * clone() const override = 0; 132 MUTATE_FRIEND133 };134 135 /// The application of a function to a set of parameters.136 /// Post-resolver form of `UntypedExpr`137 class ApplicationExpr final : public Expr {138 public:139 ptr<Expr> func;140 std::vector<ptr<Expr>> args;141 142 ApplicationExpr( const CodeLocation & loc, const Expr * f, std::vector<ptr<Expr>> && as = {} );143 144 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }145 private:146 ApplicationExpr * clone() const override { return new ApplicationExpr{ *this }; }147 MUTATE_FRIEND148 };149 150 /// The application of a function to a set of parameters, pre-overload resolution.151 class UntypedExpr final : public Expr {152 public:153 ptr<Expr> func;154 std::vector<ptr<Expr>> args;155 156 UntypedExpr( const CodeLocation & loc, const Expr * f, std::vector<ptr<Expr>> && as = {} )157 : Expr( loc ), func( f ), args( std::move(as) ) {}158 159 /// Creates a new dereference expression160 static UntypedExpr * createDeref( const CodeLocation & loc, Expr * arg );161 /// Creates a new assignment expression162 static UntypedExpr * createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs );163 164 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }165 private:166 UntypedExpr * clone() const override { return new UntypedExpr{ *this }; }167 MUTATE_FRIEND168 };169 170 /// A name whose name is as-yet undetermined.171 /// May also be used to avoid name mangling in codegen phase.172 class NameExpr final : public Expr {173 public:174 std::string name;175 176 NameExpr( const CodeLocation & loc, const std::string & n ) : Expr( loc ), name( n ) {}177 178 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }179 private:180 NameExpr * clone() const override { return new NameExpr{ *this }; }181 MUTATE_FRIEND182 };183 184 /// Address-of expression `&e`185 class AddressExpr final : public Expr {186 public:187 ptr<Expr> arg;188 189 AddressExpr( const CodeLocation & loc, const Expr * a );190 191 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }192 private:193 AddressExpr * clone() const override { return new AddressExpr{ *this }; }194 MUTATE_FRIEND195 };196 197 /// GCC &&label198 /// https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html199 class LabelAddressExpr final : public Expr {200 public:201 Label arg;202 203 LabelAddressExpr( const CodeLocation & loc, Label && a );204 205 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }206 private:207 LabelAddressExpr * clone() const override { return new LabelAddressExpr{ *this }; }208 MUTATE_FRIEND209 };210 211 /// Whether a cast existed in the program source or not212 enum GeneratedFlag { ExplicitCast, GeneratedCast };213 214 /// A type cast, e.g. `(int)e`215 class CastExpr final : public Expr {216 public:217 ptr<Expr> arg;218 GeneratedFlag isGenerated;219 220 CastExpr( const CodeLocation & loc, const Expr * a, const Type * to,221 GeneratedFlag g = GeneratedCast ) : Expr( loc, to ), arg( a ), isGenerated( g ) {}222 /// Cast-to-void223 CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast );224 225 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }226 private:227 CastExpr * clone() const override { return new CastExpr{ *this }; }228 MUTATE_FRIEND229 };230 231 /// A cast to "keyword types", e.g. `(thread &)t`232 class KeywordCastExpr final : public Expr {233 public:234 ptr<Expr> arg;235 enum Target { Coroutine, Thread, Monitor, NUMBER_OF_TARGETS } target;236 237 KeywordCastExpr( const CodeLocation & loc, const Expr * a, Target t )238 : Expr( loc ), arg( a ), target( t ) {}239 240 /// Get a name for the target type241 const std::string& targetString() const;242 243 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }244 private:245 KeywordCastExpr * clone() const override { return new KeywordCastExpr{ *this }; }246 MUTATE_FRIEND247 };248 249 /// A virtual dynamic cast, e.g. `(virtual exception)e`250 class VirtualCastExpr final : public Expr {251 public:252 ptr<Expr> arg;253 254 VirtualCastExpr( const CodeLocation & loc, const Expr * a, const Type * to )255 : Expr( loc, to ), arg( a ) {}256 257 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }258 private:259 VirtualCastExpr * clone() const override { return new VirtualCastExpr{ *this }; }260 MUTATE_FRIEND261 };262 263 /// A member selection operation before expression resolution, e.g. `q.p`264 class UntypedMemberExpr final : public Expr {265 public:266 ptr<Expr> member;267 ptr<Expr> aggregate;268 269 UntypedMemberExpr( const CodeLocation & loc, const Expr * mem, const Expr * agg )270 : Expr( loc ), member( mem ), aggregate( agg ) { assert( aggregate ); }271 272 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }273 private:274 UntypedMemberExpr * clone() const override { return new UntypedMemberExpr{ *this }; }275 MUTATE_FRIEND276 };277 278 /// A member selection operation after expression resolution, e.g. `q.p`279 class MemberExpr final : public Expr {280 public:281 readonly<DeclWithType> member;282 ptr<Expr> aggregate;283 284 MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg );285 286 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }287 private:288 MemberExpr * clone() const override { return new MemberExpr{ *this }; }289 MUTATE_FRIEND290 };291 292 /// A reference to a named variable.293 class VariableExpr final : public Expr {294 public:295 readonly<DeclWithType> var;296 297 VariableExpr( const CodeLocation & loc, const DeclWithType * v );298 299 /// generates a function pointer for a given function300 static VariableExpr * functionPointer( const CodeLocation & loc, const FunctionDecl * decl );301 302 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }303 private:304 VariableExpr * clone() const override { return new VariableExpr{ *this }; }305 MUTATE_FRIEND306 };307 308 /// A compile-time constant309 class ConstantExpr final : public Expr {310 union Val {311 unsigned long long ival;312 double dval;313 314 Val( unsigned long long i ) : ival( i ) {}315 Val( double d ) : dval( d ) {}316 } val;317 public:318 std::string rep;319 320 ConstantExpr(321 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v )322 : Expr( loc, ty ), val( v ), rep( r ) {}323 ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v )324 : Expr( loc, ty ), val( v ), rep( r ) {}325 326 /// Gets the value of this constant as an integer327 long long int intValue() const;328 /// Gets the value of this constant as floating point329 double floatValue() const;330 331 /// generates a boolean constant of the given bool332 static ConstantExpr * from_bool( const CodeLocation & loc, bool b );333 /// generates a char constant of the given char334 static ConstantExpr * from_char( const CodeLocation & loc, char c );335 /// generates an integer constant of the given int336 static ConstantExpr * from_int( const CodeLocation & loc, int i );337 /// generates an integer constant of the given unsigned long int338 static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i );339 /// generates a floating point constant of the given double340 static ConstantExpr * from_double( const CodeLocation & loc, double d );341 /// generates an array of chars constant of the given string342 static ConstantExpr * from_string( const CodeLocation & loc, const std::string & s );343 /// generates a null pointer value for the given type. void * if omitted.344 static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr );345 346 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }347 private:348 ConstantExpr * clone() const override { return new ConstantExpr{ *this }; }349 MUTATE_FRIEND350 };351 352 /// sizeof expression, e.g. `sizeof(int)`, `sizeof 3+4`353 class SizeofExpr final : public Expr {354 public:355 ptr<Expr> expr;356 ptr<Type> type;357 358 SizeofExpr( const CodeLocation & loc, const Expr * e );359 SizeofExpr( const CodeLocation & loc, const Type * t );360 // deliberately no disambiguating overload for nullptr_t361 362 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }363 private:364 SizeofExpr * clone() const override { return new SizeofExpr{ *this }; }365 MUTATE_FRIEND366 };367 368 /// alignof expression, e.g. `alignof(int)`, `alignof 3+4`369 class AlignofExpr final : public Expr {370 public:371 ptr<Expr> expr;372 ptr<Type> type;373 374 AlignofExpr( const CodeLocation & loc, const Expr * e );375 AlignofExpr( const CodeLocation & loc, const Type * t );376 // deliberately no disambiguating overload for nullptr_t377 378 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }379 private:380 AlignofExpr * clone() const override { return new AlignofExpr{ *this }; }381 MUTATE_FRIEND382 };383 384 /// offsetof expression before resolver determines field, e.g. `offsetof(MyStruct, myfield)`385 class UntypedOffsetofExpr final : public Expr {386 public:387 ptr<Type> type;388 std::string member;389 390 UntypedOffsetofExpr( const CodeLocation & loc, const Type * ty, const std::string & mem )391 : Expr( loc ), type( ty ), member( mem ) {}392 393 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }394 private:395 UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr{ *this }; }396 MUTATE_FRIEND397 };398 399 /// offsetof expression after resolver determines field, e.g. `offsetof(MyStruct, myfield)`400 class OffsetofExpr final : public Expr {401 public:402 ptr<Type> type;403 readonly<DeclWithType> member;404 405 OffsetofExpr( const CodeLocation & loc, const Type * ty, const DeclWithType * mem );406 407 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }408 private:409 OffsetofExpr * clone() const override { return new OffsetofExpr{ *this }; }410 MUTATE_FRIEND411 };412 413 /// a pack of field-offsets for a generic type414 class OffsetPackExpr final : public Expr {415 public:416 ptr<StructInstType> type;417 418 OffsetPackExpr( const CodeLocation & loc, const StructInstType * ty );419 420 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }421 private:422 OffsetPackExpr * clone() const override { return new OffsetPackExpr{ *this }; }423 MUTATE_FRIEND424 };425 426 /// Variants of short-circuiting logical expression427 enum LogicalFlag { OrExpr, AndExpr };428 429 /// Short-circuiting boolean expression (`&&` or `||`)430 class LogicalExpr final : public Expr {431 public:432 ptr<Expr> arg1;433 ptr<Expr> arg2;434 LogicalFlag isAnd;435 436 LogicalExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2, LogicalFlag ia );437 438 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }439 private:440 LogicalExpr * clone() const override { return new LogicalExpr{ *this }; }441 MUTATE_FRIEND442 };443 444 /// Three-argument conditional e.g. `p ? a : b`445 class ConditionalExpr final : public Expr {446 public:447 ptr<Expr> arg1;448 ptr<Expr> arg2;449 ptr<Expr> arg3;450 451 ConditionalExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2, const Expr * a3 )452 : Expr( loc ), arg1( a1 ), arg2( a2 ), arg3( a3 ) {}453 454 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }455 private:456 ConditionalExpr * clone() const override { return new ConditionalExpr{ *this }; }457 MUTATE_FRIEND458 };459 460 /// Comma expression e.g. `( a , b )`461 class CommaExpr final : public Expr {462 public:463 ptr<Expr> arg1;464 ptr<Expr> arg2;465 466 CommaExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2 )467 : Expr( loc ), arg1( a1 ), arg2( a2 ) {}468 469 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }470 private:471 CommaExpr * clone() const override { return new CommaExpr{ *this }; }472 MUTATE_FRIEND473 126 }; 474 127 … … 483 136 private: 484 137 TypeExpr * clone() const override { return new TypeExpr{ *this }; } 485 MUTATE_FRIEND486 138 }; 487 139 488 /// A GCC "asm constraint operand" used in an asm statement, e.g. `[output] "=f" (result)`.489 /// https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints490 class AsmExpr final : public Expr {491 public:492 ptr<Expr> inout;493 ptr<Expr> constraint;494 };495 140 496 141 //================================================================================================= … … 501 146 inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); } 502 147 inline void decrement( const class Expr * node, Node::ref_type ref ) { node->decrement(ref); } 503 inline void increment( const class ApplicationExpr * node, Node::ref_type ref ) { node->increment(ref); } 504 inline void decrement( const class ApplicationExpr * node, Node::ref_type ref ) { node->decrement(ref); } 505 inline void increment( const class UntypedExpr * node, Node::ref_type ref ) { node->increment(ref); } 506 inline void decrement( const class UntypedExpr * node, Node::ref_type ref ) { node->decrement(ref); } 507 inline void increment( const class NameExpr * node, Node::ref_type ref ) { node->increment(ref); } 508 inline void decrement( const class NameExpr * node, Node::ref_type ref ) { node->decrement(ref); } 509 inline void increment( const class AddressExpr * node, Node::ref_type ref ) { node->increment(ref); } 510 inline void decrement( const class AddressExpr * node, Node::ref_type ref ) { node->decrement(ref); } 511 inline void increment( const class LabelAddressExpr * node, Node::ref_type ref ) { node->increment(ref); } 512 inline void decrement( const class LabelAddressExpr * node, Node::ref_type ref ) { node->decrement(ref); } 513 inline void increment( const class CastExpr * node, Node::ref_type ref ) { node->increment(ref); } 514 inline void decrement( const class CastExpr * node, Node::ref_type ref ) { node->decrement(ref); } 515 inline void increment( const class KeywordCastExpr * node, Node::ref_type ref ) { node->increment(ref); } 516 inline void decrement( const class KeywordCastExpr * node, Node::ref_type ref ) { node->decrement(ref); } 517 inline void increment( const class VirtualCastExpr * node, Node::ref_type ref ) { node->increment(ref); } 518 inline void decrement( const class VirtualCastExpr * node, Node::ref_type ref ) { node->decrement(ref); } 519 inline void increment( const class MemberExpr * node, Node::ref_type ref ) { node->increment(ref); } 520 inline void decrement( const class MemberExpr * node, Node::ref_type ref ) { node->decrement(ref); } 521 inline void increment( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->increment(ref); } 522 inline void decrement( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->decrement(ref); } 523 inline void increment( const class VariableExpr * node, Node::ref_type ref ) { node->increment(ref); } 524 inline void decrement( const class VariableExpr * node, Node::ref_type ref ) { node->decrement(ref); } 525 inline void increment( const class ConstantExpr * node, Node::ref_type ref ) { node->increment(ref); } 526 inline void decrement( const class ConstantExpr * node, Node::ref_type ref ) { node->decrement(ref); } 527 inline void increment( const class SizeofExpr * node, Node::ref_type ref ) { node->increment(ref); } 528 inline void decrement( const class SizeofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 529 inline void increment( const class AlignofExpr * node, Node::ref_type ref ) { node->increment(ref); } 530 inline void decrement( const class AlignofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 531 inline void increment( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); } 532 inline void decrement( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 533 inline void increment( const class OffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); } 534 inline void decrement( const class OffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 535 inline void increment( const class OffsetPackExpr * node, Node::ref_type ref ) { node->increment(ref); } 536 inline void decrement( const class OffsetPackExpr * node, Node::ref_type ref ) { node->decrement(ref); } 537 inline void increment( const class LogicalExpr * node, Node::ref_type ref ) { node->increment(ref); } 538 inline void decrement( const class LogicalExpr * node, Node::ref_type ref ) { node->decrement(ref); } 539 inline void increment( const class ConditionalExpr * node, Node::ref_type ref ) { node->increment(ref); } 540 inline void decrement( const class ConditionalExpr * node, Node::ref_type ref ) { node->decrement(ref); } 541 inline void increment( const class CommaExpr * node, Node::ref_type ref ) { node->increment(ref); } 542 inline void decrement( const class CommaExpr * node, Node::ref_type ref ) { node->decrement(ref); } 543 inline void increment( const class TypeExpr * node, Node::ref_type ref ) { node->increment(ref); } 544 inline void decrement( const class TypeExpr * node, Node::ref_type ref ) { node->decrement(ref); } 545 inline void increment( const class AsmExpr * node, Node::ref_type ref ) { node->increment(ref); } 546 inline void decrement( const class AsmExpr * node, Node::ref_type ref ) { node->decrement(ref); } 148 // inline void increment( const class ApplicationExpr * node, Node::ref_type ref ) { node->increment(ref); } 149 // inline void decrement( const class ApplicationExpr * node, Node::ref_type ref ) { node->decrement(ref); } 150 // inline void increment( const class UntypedExpr * node, Node::ref_type ref ) { node->increment(ref); } 151 // inline void decrement( const class UntypedExpr * node, Node::ref_type ref ) { node->decrement(ref); } 152 // inline void increment( const class NameExpr * node, Node::ref_type ref ) { node->increment(ref); } 153 // inline void decrement( const class NameExpr * node, Node::ref_type ref ) { node->decrement(ref); } 154 // inline void increment( const class AddressExpr * node, Node::ref_type ref ) { node->increment(ref); } 155 // inline void decrement( const class AddressExpr * node, Node::ref_type ref ) { node->decrement(ref); } 156 // inline void increment( const class LabelAddressExpr * node, Node::ref_type ref ) { node->increment(ref); } 157 // inline void decrement( const class LabelAddressExpr * node, Node::ref_type ref ) { node->decrement(ref); } 158 // inline void increment( const class CastExpr * node, Node::ref_type ref ) { node->increment(ref); } 159 // inline void decrement( const class CastExpr * node, Node::ref_type ref ) { node->decrement(ref); } 160 // inline void increment( const class KeywordCastExpr * node, Node::ref_type ref ) { node->increment(ref); } 161 // inline void decrement( const class KeywordCastExpr * node, Node::ref_type ref ) { node->decrement(ref); } 162 // inline void increment( const class VirtualCastExpr * node, Node::ref_type ref ) { node->increment(ref); } 163 // inline void decrement( const class VirtualCastExpr * node, Node::ref_type ref ) { node->decrement(ref); } 164 // inline void increment( const class MemberExpr * node, Node::ref_type ref ) { node->increment(ref); } 165 // inline void decrement( const class MemberExpr * node, Node::ref_type ref ) { node->decrement(ref); } 166 // inline void increment( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->increment(ref); } 167 // inline void decrement( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->decrement(ref); } 168 // inline void increment( const class VariableExpr * node, Node::ref_type ref ) { node->increment(ref); } 169 // inline void decrement( const class VariableExpr * node, Node::ref_type ref ) { node->decrement(ref); } 170 // inline void increment( const class ConstantExpr * node, Node::ref_type ref ) { node->increment(ref); } 171 // inline void decrement( const class ConstantExpr * node, Node::ref_type ref ) { node->decrement(ref); } 172 // inline void increment( const class SizeofExpr * node, Node::ref_type ref ) { node->increment(ref); } 173 // inline void decrement( const class SizeofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 174 // inline void increment( const class AlignofExpr * node, Node::ref_type ref ) { node->increment(ref); } 175 // inline void decrement( const class AlignofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 176 // inline void increment( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); } 177 // inline void decrement( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 178 // inline void increment( const class OffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); } 179 // inline void decrement( const class OffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); } 180 // inline void increment( const class OffsetPackExpr * node, Node::ref_type ref ) { node->increment(ref); } 181 // inline void decrement( const class OffsetPackExpr * node, Node::ref_type ref ) { node->decrement(ref); } 182 // inline void increment( const class AttrExpr * node, Node::ref_type ref ) { node->increment(ref); } 183 // inline void decrement( const class AttrExpr * node, Node::ref_type ref ) { node->decrement(ref); } 184 // inline void increment( const class LogicalExpr * node, Node::ref_type ref ) { node->increment(ref); } 185 // inline void decrement( const class LogicalExpr * node, Node::ref_type ref ) { node->decrement(ref); } 186 // inline void increment( const class ConditionalExpr * node, Node::ref_type ref ) { node->increment(ref); } 187 // inline void decrement( const class ConditionalExpr * node, Node::ref_type ref ) { node->decrement(ref); } 188 // inline void increment( const class CommaExpr * node, Node::ref_type ref ) { node->increment(ref); } 189 // inline void decrement( const class CommaExpr * node, Node::ref_type ref ) { node->decrement(ref); } 190 // inline void increment( const class TypeExpr * node, Node::ref_type ref ) { node->increment(ref); } 191 // inline void decrement( const class TypeExpr * node, Node::ref_type ref ) { node->decrement(ref); } 192 // inline void increment( const class AsmExpr * node, Node::ref_type ref ) { node->increment(ref); } 193 // inline void decrement( const class AsmExpr * node, Node::ref_type ref ) { node->decrement(ref); } 547 194 // inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); } 548 195 // inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); } … … 579 226 } 580 227 581 #undef MUTATE_FRIEND582 583 228 // Local Variables: // 584 229 // tab-width: 4 // -
src/AST/Fwd.hpp
r204358b r10248ae0 77 77 class OffsetofExpr; 78 78 class OffsetPackExpr; 79 class AttrExpr; 79 80 class LogicalExpr; 80 81 class ConditionalExpr; … … 251 252 inline void increment( const class OffsetPackExpr *, Node::ref_type ); 252 253 inline void decrement( const class OffsetPackExpr *, Node::ref_type ); 254 inline void increment( const class AttrExpr *, Node::ref_type ); 255 inline void decrement( const class AttrExpr *, Node::ref_type ); 253 256 inline void increment( const class LogicalExpr *, Node::ref_type ); 254 257 inline void decrement( const class LogicalExpr *, Node::ref_type ); -
src/AST/Init.hpp
r204358b r10248ae0 23 23 #include "Visitor.hpp" 24 24 25 // Must be included in *all* AST classes; should be #undef'd at the end of the file26 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);27 28 25 namespace ast { 29 26 … … 43 40 private: 44 41 Designation* clone() const override { return new Designation{ *this }; } 45 MUTATE_FRIEND46 42 }; 47 43 … … 59 55 private: 60 56 const Init * clone() const override = 0; 61 MUTATE_FRIEND62 57 }; 63 58 … … 74 69 private: 75 70 SingleInit * clone() const override { return new SingleInit{ *this }; } 76 MUTATE_FRIEND 71 72 /// Must be copied in ALL derived classes 73 template<typename node_t> 74 friend auto mutate(const node_t * node); 77 75 }; 78 76 … … 99 97 private: 100 98 ListInit * clone() const override { return new ListInit{ *this }; } 101 MUTATE_FRIEND 99 100 /// Must be copied in ALL derived classes 101 template<typename node_t> 102 friend auto mutate(const node_t * node); 102 103 }; 103 104 … … 119 120 private: 120 121 ConstructorInit * clone() const override { return new ConstructorInit{ *this }; } 121 MUTATE_FRIEND 122 123 /// Must be copied in ALL derived classes 124 template<typename node_t> 125 friend auto mutate(const node_t * node); 122 126 }; 123 127 … … 138 142 } 139 143 140 #undef MUTATE_FRIEND141 142 144 // Local Variables: // 143 145 // tab-width: 4 // -
src/AST/Node.hpp
r204358b r10248ae0 76 76 // problems and be able to use auto return 77 77 template<typename node_t> 78 auto mutate( const node_t * node) {78 auto mutate(const node_t * node) { 79 79 assertf( 80 80 node->strong_count >= 1, … … 92 92 } 93 93 94 std::ostream& operator<< ( std::ostream& out, const Node * node );94 std::ostream& operator<< ( std::ostream& out, const Node* node ); 95 95 96 96 /// Base class for the smart pointer types … … 137 137 operator const node_t * () const { return node; } 138 138 139 /// wrapper for convenient access to dynamic_cast140 139 template<typename o_node_t> 141 140 const o_node_t * as() const { return dynamic_cast<const o_node_t *>(node); } 142 143 /// Sets this pointer to a mutated version of a pointer (possibly) owned elsehere.144 /// Returns a mutable version of the pointer in this node.145 node_t * set_and_mutate( const node_t * n ) {146 // ensure ownership of `n` by this node to avoid spurious single-owner mutates147 assign( n );148 // get mutable version of `n`149 auto r = mutate( node );150 // re-assign mutable version in case `mutate()` produced a new pointer151 assign( r );152 return r;153 }154 141 155 142 using ptr = const node_t *; -
src/AST/Stmt.hpp
r204358b r10248ae0 26 26 #include "Common/CodeLocation.h" 27 27 28 // Must be included in *all* AST classes; should be #undef'd at the end of the file29 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);30 31 28 namespace ast { 32 29 … … 38 35 std::vector<Label> labels; 39 36 40 Stmt( const CodeLocation & loc, std::vector<Label>&& labels = {} )37 Stmt( const CodeLocation& loc, std::vector<Label>&& labels = {} ) 41 38 : ParseNode(loc), labels(std::move(labels)) {} 42 39 43 40 Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {} 44 41 45 const Stmt * accept( Visitor & v ) const override = 0; 46 private: 47 Stmt * clone() const override = 0; 48 MUTATE_FRIEND 42 const Stmt* accept( Visitor& v ) const override = 0; 43 private: 44 Stmt* clone() const override = 0; 49 45 }; 50 46 … … 54 50 std::list<ptr<Stmt>> kids; 55 51 56 CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>>&& ks = {} )52 CompoundStmt(const CodeLocation& loc, std::list<ptr<Stmt>>&& ks = {} ) 57 53 : Stmt(loc), kids(std::move(ks)) {} 58 54 … … 60 56 CompoundStmt( CompoundStmt&& o ) = default; 61 57 62 void push_back( Stmt * s ) { kids.emplace_back( s ); } 63 void push_front( Stmt * s ) { kids.emplace_front( s ); } 64 65 const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); } 66 private: 67 CompoundStmt * clone() const override { return new CompoundStmt{ *this }; } 68 MUTATE_FRIEND 58 void push_back( Stmt* s ) { kids.emplace_back( s ); } 59 void push_front( Stmt* s ) { kids.emplace_front( s ); } 60 61 const CompoundStmt* accept( Visitor& v ) const override { return v.visit( this ); } 62 private: 63 CompoundStmt* clone() const override { return new CompoundStmt{ *this }; } 64 65 /// Must be copied in ALL derived classes 66 template<typename node_t> 67 friend auto mutate(const node_t * node); 69 68 }; 70 69 … … 72 71 class NullStmt final : public Stmt { 73 72 public: 74 NullStmt( const CodeLocation & loc, std::vector<Label>&& labels = {} )73 NullStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} ) 75 74 : Stmt(loc, std::move(labels)) {} 76 75 77 const NullStmt * accept( Visitor & v ) const override { return v.visit( this ); } 78 private: 79 NullStmt * clone() const override { return new NullStmt{ *this }; } 80 MUTATE_FRIEND 76 const NullStmt* accept( Visitor& v ) const override { return v.visit( this ); } 77 private: 78 NullStmt* clone() const override { return new NullStmt{ *this }; } 79 80 /// Must be copied in ALL derived classes 81 template<typename node_t> 82 friend auto mutate(const node_t * node); 81 83 }; 82 84 … … 88 90 ExprStmt( const CodeLocation & loc, const Expr * e ) : Stmt(loc), expr(e) {} 89 91 90 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }92 const Stmt * accept( Visitor& v ) const override { return v.visit( this ); } 91 93 private: 92 94 ExprStmt * clone() const override { return new ExprStmt{ *this }; } 93 MUTATE_FRIEND 95 96 /// Must be copied in ALL derived classes 97 template<typename node_t> 98 friend auto mutate(const node_t * node); 94 99 }; 95 100 … … 102 107 std::vector<Label> gotoLabels; 103 108 104 AsmStmt( const CodeLocation & loc, bool isVolatile, const Expr * instruction,105 std::vector<ptr<Expr>> && output, std::vector<ptr<Expr>>&& input,106 std::vector<ptr<ConstantExpr>> && clobber, std::vector<Label>&& gotoLabels,107 std::vector<Label> && labels = {})109 AsmStmt( const CodeLocation& loc, bool isVolatile, const Expr * instruction, 110 std::vector<ptr<Expr>>&& output, std::vector<ptr<Expr>>&& input, 111 std::vector<ptr<ConstantExpr>>&& clobber, std::vector<Label>&& gotoLabels, 112 std::vector<Label>&& labels = {}) 108 113 : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction), 109 114 output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)), 110 115 gotoLabels(std::move(gotoLabels)) {} 111 116 112 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 113 private: 114 AsmStmt * clone() const override { return new AsmStmt{ *this }; } 115 MUTATE_FRIEND 117 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 118 private: 119 AsmStmt* clone() const override { return new AsmStmt{ *this }; } 120 121 /// Must be copied in ALL derived classes 122 template<typename node_t> 123 friend auto mutate(const node_t * node); 116 124 }; 117 125 … … 120 128 std::string directive; 121 129 122 DirectiveStmt( const CodeLocation & loc, const std::string & directive,123 std::vector<Label> && labels = {} )130 DirectiveStmt( const CodeLocation& loc, const std::string & directive, 131 std::vector<Label>&& labels = {} ) 124 132 : Stmt(loc, std::move(labels)), directive(directive) {} 125 133 126 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 127 private: 128 DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; } 129 MUTATE_FRIEND 134 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 135 private: 136 DirectiveStmt* clone() const override { return new DirectiveStmt{ *this }; } 137 138 /// Must be copied in ALL derived classes 139 template<typename node_t> 140 friend auto mutate(const node_t * node); 130 141 }; 131 142 … … 137 148 std::vector<ptr<Stmt>> inits; 138 149 139 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt* thenPart,140 Stmt * const elsePart, std::vector<ptr<Stmt>> && inits,141 std::vector<Label> && labels = {} )150 IfStmt( const CodeLocation& loc, const Expr* cond, const Stmt* thenPart, 151 Stmt * const elsePart, std::vector<ptr<Stmt>>&& inits, 152 std::vector<Label>&& labels = {} ) 142 153 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart), 143 154 inits(std::move(inits)) {} 144 155 145 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 146 private: 147 IfStmt * clone() const override { return new IfStmt{ *this }; } 148 MUTATE_FRIEND 156 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 157 private: 158 IfStmt* clone() const override { return new IfStmt{ *this }; } 159 160 /// Must be copied in ALL derived classes 161 template<typename node_t> 162 friend auto mutate(const node_t * node); 149 163 }; 150 164 … … 154 168 std::vector<ptr<Stmt>> stmts; 155 169 156 SwitchStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>>&& stmts,157 std::vector<Label> && labels = {} )170 SwitchStmt( const CodeLocation& loc, const Expr* cond, std::vector<ptr<Stmt>>&& stmts, 171 std::vector<Label>&& labels = {} ) 158 172 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 159 173 160 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 161 private: 162 SwitchStmt * clone() const override { return new SwitchStmt{ *this }; } 163 MUTATE_FRIEND 174 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 175 private: 176 SwitchStmt* clone() const override { return new SwitchStmt{ *this }; } 177 178 /// Must be copied in ALL derived classes 179 template<typename node_t> 180 friend auto mutate(const node_t * node); 164 181 }; 165 182 … … 169 186 std::vector<ptr<Stmt>> stmts; 170 187 171 CaseStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>>&& stmts,172 std::vector<Label>&& labels = {} )173 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}188 CaseStmt( const CodeLocation& loc, const Expr* cond, std::vector<ptr<Stmt>>&& stmts, 189 std::vector<Label>&& labels = {} ) 190 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 174 191 175 192 bool isDefault() { return !cond; } 176 193 177 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 178 private: 179 CaseStmt * clone() const override { return new CaseStmt{ *this }; } 180 MUTATE_FRIEND 194 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 195 private: 196 CaseStmt* clone() const override { return new CaseStmt{ *this }; } 197 198 /// Must be copied in ALL derived classes 199 template<typename node_t> 200 friend auto mutate(const node_t * node); 181 201 }; 182 202 … … 188 208 bool isDoWhile; 189 209 190 WhileStmt( const CodeLocation & loc, const Expr * cond, const Stmt* body,191 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label>&& labels = {} )210 WhileStmt( const CodeLocation& loc, const Expr* cond, const Stmt* body, 211 std::vector<ptr<Stmt>>&& inits, bool isDoWhile = false, std::vector<Label>&& labels = {} ) 192 212 : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)), 193 213 isDoWhile(isDoWhile) {} 194 214 195 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 196 private: 197 WhileStmt * clone() const override { return new WhileStmt{ *this }; } 198 MUTATE_FRIEND 215 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 216 private: 217 WhileStmt* clone() const override { return new WhileStmt{ *this }; } 218 219 /// Must be copied in ALL derived classes 220 template<typename node_t> 221 friend auto mutate(const node_t * node); 199 222 }; 200 223 … … 206 229 ptr<Stmt> body; 207 230 208 ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>> && inits, const Expr* cond,209 const Expr * inc, const Stmt * body, std::vector<Label>&& labels = {} )231 ForStmt( const CodeLocation& loc, std::vector<ptr<Stmt>>&& inits, const Expr* cond, 232 const Expr* inc, const Stmt* body, std::vector<Label>&& labels = {} ) 210 233 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), 211 234 body(body) {} 212 235 213 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 214 private: 215 ForStmt * clone() const override { return new ForStmt{ *this }; } 216 MUTATE_FRIEND 236 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 237 private: 238 ForStmt* clone() const override { return new ForStmt{ *this }; } 239 240 /// Must be copied in ALL derived classes 241 template<typename node_t> 242 friend auto mutate(const node_t * node); 217 243 }; 218 244 … … 227 253 Kind kind; 228 254 229 BranchStmt( const CodeLocation & loc, Kind kind, Label target,230 std::vector<Label> && labels = {} );231 BranchStmt( const CodeLocation & loc, const Expr* computedTarget,232 std::vector<Label> && labels = {} )255 BranchStmt( const CodeLocation& loc, Kind kind, Label target, 256 std::vector<Label>&& labels = {} ); 257 BranchStmt( const CodeLocation& loc, const Expr* computedTarget, 258 std::vector<Label>&& labels = {} ) 233 259 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), 234 260 computedTarget(computedTarget), kind(Goto) {} … … 236 262 const char * kindName() { return kindNames[kind]; } 237 263 238 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 239 private: 240 BranchStmt * clone() const override { return new BranchStmt{ *this }; } 241 MUTATE_FRIEND 264 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 265 private: 266 BranchStmt* clone() const override { return new BranchStmt{ *this }; } 267 268 /// Must be copied in ALL derived classes 269 template<typename node_t> 270 friend auto mutate(const node_t * node); 242 271 243 272 static const char * kindNames[kindEnd]; … … 248 277 ptr<Expr> expr; 249 278 250 ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label>&& labels = {} )279 ReturnStmt( const CodeLocation& loc, const Expr* expr, std::vector<Label>&& labels = {} ) 251 280 : Stmt(loc, std::move(labels)), expr(expr) {} 252 281 253 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 254 private: 255 ReturnStmt * clone() const override { return new ReturnStmt{ *this }; } 256 MUTATE_FRIEND 282 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 283 private: 284 ReturnStmt* clone() const override { return new ReturnStmt{ *this }; } 285 286 /// Must be copied in ALL derived classes 287 template<typename node_t> 288 friend auto mutate(const node_t * node); 257 289 }; 258 290 … … 265 297 Kind kind; 266 298 267 ThrowStmt( const CodeLocation & loc, Kind kind, const Expr * expr, const Expr* target,268 std::vector<Label> && labels = {} )299 ThrowStmt( const CodeLocation& loc, Kind kind, const Expr* expr, const Expr* target, 300 std::vector<Label>&& labels = {} ) 269 301 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {} 270 302 271 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 272 private: 273 ThrowStmt * clone() const override { return new ThrowStmt{ *this }; } 274 MUTATE_FRIEND 303 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 304 private: 305 ThrowStmt* clone() const override { return new ThrowStmt{ *this }; } 306 307 /// Must be copied in ALL derived classes 308 template<typename node_t> 309 friend auto mutate(const node_t * node); 275 310 }; 276 311 … … 281 316 ptr<FinallyStmt> finally; 282 317 283 TryStmt( const CodeLocation & loc, const CompoundStmt* body,284 std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt* finally,285 std::vector<Label> && labels = {} )318 TryStmt( const CodeLocation& loc, const CompoundStmt* body, 319 std::vector<ptr<CatchStmt>>&& handlers, const FinallyStmt* finally, 320 std::vector<Label>&& labels = {} ) 286 321 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {} 287 322 288 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 289 private: 290 TryStmt * clone() const override { return new TryStmt{ *this }; } 291 MUTATE_FRIEND 323 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 324 private: 325 TryStmt* clone() const override { return new TryStmt{ *this }; } 326 327 /// Must be copied in ALL derived classes 328 template<typename node_t> 329 friend auto mutate(const node_t * node); 292 330 }; 293 331 … … 301 339 Kind kind; 302 340 303 CatchStmt( const CodeLocation & loc, Kind kind, const Decl * decl, const Expr* cond,304 const Stmt * body, std::vector<Label>&& labels = {} )341 CatchStmt( const CodeLocation& loc, Kind kind, const Decl* decl, const Expr* cond, 342 const Stmt* body, std::vector<Label>&& labels = {} ) 305 343 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {} 306 344 307 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 308 private: 309 CatchStmt * clone() const override { return new CatchStmt{ *this }; } 310 MUTATE_FRIEND 345 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 346 private: 347 CatchStmt* clone() const override { return new CatchStmt{ *this }; } 348 349 /// Must be copied in ALL derived classes 350 template<typename node_t> 351 friend auto mutate(const node_t * node); 311 352 }; 312 353 … … 315 356 ptr<CompoundStmt> body; 316 357 317 FinallyStmt( const CodeLocation & loc, const CompoundStmt* body,318 std::vector<Label> && labels = {} )358 FinallyStmt( const CodeLocation& loc, const CompoundStmt* body, 359 std::vector<Label>&& labels = {} ) 319 360 : Stmt(loc, std::move(labels)), body(body) {} 320 361 321 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 322 private: 323 FinallyStmt * clone() const override { return new FinallyStmt{ *this }; } 324 MUTATE_FRIEND 362 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 363 private: 364 FinallyStmt* clone() const override { return new FinallyStmt{ *this }; } 365 366 /// Must be copied in ALL derived classes 367 template<typename node_t> 368 friend auto mutate(const node_t * node); 325 369 }; 326 370 … … 353 397 OrElse orElse; 354 398 355 WaitForStmt( const CodeLocation & loc, std::vector<Label>&& labels = {} )399 WaitForStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} ) 356 400 : Stmt(loc, std::move(labels)) {} 357 401 358 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 359 private: 360 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; } 361 MUTATE_FRIEND 402 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 403 private: 404 WaitForStmt* clone() const override { return new WaitForStmt{ *this }; } 405 406 /// Must be copied in ALL derived classes 407 template<typename node_t> 408 friend auto mutate(const node_t * node); 362 409 }; 363 410 … … 367 414 ptr<Stmt> stmt; 368 415 369 WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt* stmt,370 std::vector<Label> && labels = {} )416 WithStmt( const CodeLocation& loc, std::vector<ptr<Expr>>&& exprs, const Stmt* stmt, 417 std::vector<Label>&& labels = {} ) 371 418 : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {} 372 419 373 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 374 private: 375 WithStmt * clone() const override { return new WithStmt{ *this }; } 376 MUTATE_FRIEND 420 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 421 private: 422 WithStmt* clone() const override { return new WithStmt{ *this }; } 423 424 /// Must be copied in ALL derived classes 425 template<typename node_t> 426 friend auto mutate(const node_t * node); 377 427 }; 378 428 … … 381 431 ptr<Decl> decl; 382 432 383 DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label>&& labels = {} )433 DeclStmt( const CodeLocation& loc, const Decl* decl, std::vector<Label>&& labels = {} ) 384 434 : Stmt(loc, std::move(labels)), decl(decl) {} 385 435 386 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 387 private: 388 DeclStmt * clone() const override { return new DeclStmt{ *this }; } 389 MUTATE_FRIEND 436 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 437 private: 438 DeclStmt* clone() const override { return new DeclStmt{ *this }; } 439 440 /// Must be copied in ALL derived classes 441 template<typename node_t> 442 friend auto mutate(const node_t * node); 390 443 }; 391 444 … … 394 447 readonly<Stmt> callStmt; 395 448 396 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt* callStmt,397 std::vector<Label> && labels = {} )449 ImplicitCtorDtorStmt( const CodeLocation& loc, const Stmt* callStmt, 450 std::vector<Label>&& labels = {} ) 398 451 : Stmt(loc, std::move(labels)), callStmt(callStmt) {} 399 452 400 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 401 private: 402 ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; } 403 MUTATE_FRIEND 453 const Stmt* accept( Visitor& v ) const override { return v.visit( this ); } 454 private: 455 ImplicitCtorDtorStmt* clone() const override { return new ImplicitCtorDtorStmt{ *this }; } 456 457 /// Must be copied in ALL derived classes 458 template<typename node_t> 459 friend auto mutate(const node_t * node); 404 460 }; 405 461 … … 454 510 } 455 511 456 #undef MUTATE_FRIEND457 458 512 // Local Variables: // 459 513 // tab-width: 4 // -
src/AST/Type.hpp
r204358b r10248ae0 29 29 #include "Visitor.hpp" 30 30 31 // Must be included in *all* AST classes; should be #undef'd at the end of the file32 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node);33 34 31 namespace ast { 35 32 36 33 class Type : public Node { 37 public: 38 CV::Qualifiers qualifiers; 39 40 Type( CV::Qualifiers q = {} ) : qualifiers(q) {} 41 42 bool is_const() const { return qualifiers.is_const; } 43 bool is_volatile() const { return qualifiers.is_volatile; } 44 bool is_restrict() const { return qualifiers.is_restrict; } 45 bool is_lvalue() const { return qualifiers.is_lvalue; } 46 bool is_mutex() const { return qualifiers.is_mutex; } 47 bool is_atomic() const { return qualifiers.is_atomic; } 48 49 void set_const( bool v ) { qualifiers.is_const = v; } 50 void set_restrict( bool v ) { qualifiers.is_restrict = v; } 51 void set_lvalue( bool v ) { qualifiers.is_lvalue = v; } 52 void set_mutex( bool v ) { qualifiers.is_mutex = v; } 53 void set_atomic( bool v ) { qualifiers.is_atomic = v; } 34 CV::Qualifiers tq; 35 public: 36 Type( CV::Qualifiers q = {} ) : tq(q) {} 37 38 CV::Qualifiers qualifiers() const { return tq; } 39 bool is_const() const { return tq.is_const; } 40 bool is_volatile() const { return tq.is_volatile; } 41 bool is_restrict() const { return tq.is_restrict; } 42 bool is_lvalue() const { return tq.is_lvalue; } 43 bool is_mutex() const { return tq.is_mutex; } 44 bool is_atomic() const { return tq.is_atomic; } 45 46 void set_qualifiers( CV::Qualifiers q ) { tq = q; } 47 void set_const( bool v ) { tq.is_const = v; } 48 void set_restrict( bool v ) { tq.is_restrict = v; } 49 void set_lvalue( bool v ) { tq.is_lvalue = v; } 50 void set_mutex( bool v ) { tq.is_mutex = v; } 51 void set_atomic( bool v ) { tq.is_atomic = v; } 54 52 55 53 /// How many elemental types are represented by this type … … 73 71 private: 74 72 virtual Type * clone() const override = 0; 75 MUTATE_FRIEND76 73 }; 77 74 … … 88 85 private: 89 86 VoidType * clone() const override { return new VoidType{ *this }; } 90 MUTATE_FRIEND91 87 }; 92 88 … … 151 147 private: 152 148 BasicType * clone() const override { return new BasicType{ *this }; } 153 MUTATE_FRIEND154 149 }; 155 150 … … 182 177 private: 183 178 PointerType * clone() const override { return new PointerType{ *this }; } 184 MUTATE_FRIEND185 179 }; 186 180 … … 204 198 private: 205 199 ArrayType * clone() const override { return new ArrayType{ *this }; } 206 MUTATE_FRIEND207 200 }; 208 201 … … 224 217 private: 225 218 ReferenceType * clone() const override { return new ReferenceType{ *this }; } 226 MUTATE_FRIEND227 219 }; 228 220 … … 239 231 private: 240 232 QualifiedType * clone() const override { return new QualifiedType{ *this }; } 241 MUTATE_FRIEND242 233 }; 243 234 … … 255 246 private: 256 247 virtual ParameterizedType * clone() const override = 0; 257 MUTATE_FRIEND258 248 }; 259 249 … … 264 254 class FunctionType final : public ParameterizedType { 265 255 public: 266 std::vector<ptr<DeclWithType>> return s;267 std::vector<ptr<DeclWithType>> param s;256 std::vector<ptr<DeclWithType>> returnVals; 257 std::vector<ptr<DeclWithType>> parameters; 268 258 269 259 /// Does the function accept a variable number of arguments following the arguments specified … … 275 265 276 266 FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} ) 277 : ParameterizedType(q), return s(), params(), isVarArgs(va) {}267 : ParameterizedType(q), returnVals(), parameters(), isVarArgs(va) {} 278 268 279 269 /// true if either the parameters or return values contain a tttype 280 270 bool isTtype() const; 281 271 /// true if function parameters are unconstrained by prototype 282 bool isUnprototyped() const { return isVarArgs && param s.size() == 0; }272 bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; } 283 273 284 274 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 285 275 private: 286 276 FunctionType * clone() const override { return new FunctionType{ *this }; } 287 MUTATE_FRIEND288 277 }; 289 278 … … 291 280 class ReferenceToType : public ParameterizedType { 292 281 public: 293 std::vector<ptr<Expr>> param s;282 std::vector<ptr<Expr>> parameters; 294 283 std::vector<ptr<Attribute>> attributes; 295 284 std::string name; … … 298 287 ReferenceToType( const std::string& n, CV::Qualifiers q = {}, 299 288 std::vector<ptr<Attribute>> && as = {} ) 300 : ParameterizedType(q), param s(), attributes(std::move(as)), name(n) {}289 : ParameterizedType(q), parameters(), attributes(std::move(as)), name(n) {} 301 290 302 291 /// Gets aggregate declaration this type refers to … … 307 296 private: 308 297 virtual ReferenceToType * clone() const override = 0; 309 MUTATE_FRIEND310 298 311 299 protected: … … 332 320 private: 333 321 StructInstType * clone() const override { return new StructInstType{ *this }; } 334 MUTATE_FRIEND335 322 336 323 std::string typeString() const override { return "struct"; } … … 355 342 private: 356 343 UnionInstType * clone() const override { return new UnionInstType{ *this }; } 357 MUTATE_FRIEND358 344 359 345 std::string typeString() const override { return "union"; } … … 378 364 private: 379 365 EnumInstType * clone() const override { return new EnumInstType{ *this }; } 380 MUTATE_FRIEND381 366 382 367 std::string typeString() const override { return "enum"; } … … 402 387 private: 403 388 TraitInstType * clone() const override { return new TraitInstType{ *this }; } 404 MUTATE_FRIEND405 389 406 390 std::string typeString() const override { return "trait"; } … … 431 415 private: 432 416 TypeInstType * clone() const override { return new TypeInstType{ *this }; } 433 MUTATE_FRIEND434 417 435 418 std::string typeString() const override { return "type"; } … … 460 443 private: 461 444 TupleType * clone() const override { return new TupleType{ *this }; } 462 MUTATE_FRIEND463 445 }; 464 446 … … 475 457 private: 476 458 TypeofType * clone() const override { return new TypeofType{ *this }; } 477 MUTATE_FRIEND478 459 }; 479 460 … … 486 467 private: 487 468 VarArgsType * clone() const override { return new VarArgsType{ *this }; } 488 MUTATE_FRIEND489 469 }; 490 470 … … 496 476 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 497 477 private: 498 ZeroType * clone() const override { return new ZeroType{ *this }; } 499 MUTATE_FRIEND 478 ZeroType * clone() const override { return new ZeroType{ *this }; } 500 479 }; 501 480 … … 508 487 private: 509 488 OneType * clone() const override { return new OneType{ *this }; } 510 MUTATE_FRIEND511 489 }; 512 490 … … 519 497 private: 520 498 GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; } 521 MUTATE_FRIEND522 499 }; 523 500 … … 570 547 } 571 548 572 #undef MUTATE_FRIEND573 574 549 // Local Variables: // 575 550 // tab-width: 4 // -
src/AST/Visitor.hpp
r204358b r10248ae0 69 69 virtual const ast::Expr * visit( const ast::OffsetofExpr * ) = 0; 70 70 virtual const ast::Expr * visit( const ast::OffsetPackExpr * ) = 0; 71 virtual const ast::Expr * visit( const ast::AttrExpr * ) = 0; 71 72 virtual const ast::Expr * visit( const ast::LogicalExpr * ) = 0; 72 73 virtual const ast::Expr * visit( const ast::ConditionalExpr * ) = 0; -
src/AST/porting.md
r204358b r10248ae0 6 6 * specialization: strong pointer `ast::ptr<T>` is used for an ownership relationship 7 7 * specialization: weak pointer `ast::readonly<T>` is used for an observation relationship 8 * added `ast::ptr_base<T,R>::as<S>()` with same semantics as `dynamic_cast<S*>(p)` 9 * added `N * ast::ptr_base<N,R>::set_and_mutate( const N * n )` 10 * takes ownership of `n`, then returns a mutable version owned by this pointer 11 * Some debate on whether this is a good approach: 12 * makes an easy path to cloning, which we were trying to eliminate 13 * counter-point: these are all mutating clones rather than lifetime-preserving clones, and thus "necessary" (for some definition) 14 * existing uses: 15 * `VariableExpr::VariableExpr`, `UntypedExpr::createDeref` 16 * both involve grabbing a type from elsewhere and making an `lvalue` copy of it 17 * could potentially be replaced by a view class something like this: 18 ``` 19 template<unsigned Quals> 20 class AddQualifiersType final : public Type { 21 readonly<Type> base; 22 // ... 23 }; 24 ``` 25 * requires all `qualifiers` use (and related helpers) to be virtual, non-zero overhead 26 * also subtle semantic change, where mutations to the source decl now change the viewing expression 8 * added `ast::ptr_base<T,R>::as<S>()` with same semantics as `dynamic_cast<S*>(p)` 27 9 28 10 ## Visitors ## … … 124 106 * allows `newObject` as just default settings 125 107 126 `NamedTypeDecl`127 * `parameters` => `params`128 129 108 `TypeDecl` 130 109 * moved `TypeDecl::Kind` to `ast::TypeVar::Kind` 131 132 `AggregateDecl`133 * `parameters` => `params`134 110 135 111 `EnumDecl` … … 139 115 * Merged `inferParams`/`resnSlots` into union, as suggested by comment in old version 140 116 * does imply get_/set_ API, and some care about moving backward 141 * added constructor that sets result, for benefit of types that set it directly142 143 `ApplicationExpr`144 * `function` => `func`145 146 `UntypedExpr`147 * `function` => `func`148 * removed `begin_args()` in favour of `args.begin()`149 150 `MemberExpr`151 * **TODO** port setup of `result` in constructor152 153 `ConstantExpr`154 * inlined features of `Constant`, never used elsewhere, so removed `Constant`155 * `Constant Constant::from_int(int)` etc. => `ConstantExpr * ConstantExpr::from_int(CodeLocation, int)`156 * allocates new `ConstantExpr`, consistent with all existing uses157 158 `SizeofExpr`, `AlignofExpr`159 * `isType` deprecated in favour of boolean check on `type`160 * all existing uses assume `type` set if true and don't use `expr`161 162 `AttrExpr`163 * did not port due to feature deprecation (e.g. `expr@attribute`)164 165 `LogicalExpr`166 * un-defaulted constructor parameter determining `&&` or `||`167 117 168 118 `Init` … … 198 148 `Type` 199 149 * `CV::Qualifiers` moved to end of constructor parameter list, defaulted to `{}` 200 * removed getter, setter in favour of public `qualifiers` field201 150 * `ReferenceToType` puts a defaulted list of attributes after qualifiers 202 151 * `forall` field split off into `ParameterizedType` subclass … … 211 160 * `getAggr()` => `aggr()` 212 161 * also now returns `const AggregateDecl *` 213 * `genericSubstitution()` moved to own visitor in `AST/GenericSubstitution.hpp`**TODO** write162 * `genericSubstitution()` moved to own visitor **TODO** write 214 163 215 164 `BasicType` … … 218 167 `ReferenceToType` 219 168 * deleted `get_baseParameters()` from children 220 * replace with `aggr() ? aggr()->params : nullptr` 221 * `parameters` => `params` 169 * replace with `aggr() ? aggr()->parameters : nullptr` 222 170 * hoisted `lookup` implementation into parent, made non-virtual 223 171 * also changed to return vector rather than filling; change back if any great win for reuse … … 230 178 231 179 `FunctionType` 232 * `returnVals` => `returns`233 * `parameters` => `params`234 180 * `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;` 235 181 -
src/ResolvExpr/Unify.cc
r204358b r10248ae0 21 21 #include <string> // for string, operator==, operator!=, bas... 22 22 #include <utility> // for pair, move 23 #include <vector> 24 25 #include "AST/Node.hpp" 26 #include "AST/Type.hpp" 23 27 24 #include "Common/PassVisitor.h" // for PassVisitor 28 25 #include "FindOpenVars.h" // for findOpenVars … … 633 630 } 634 631 632 // xxx - compute once and store in the FunctionType? 635 633 Type * extractResultType( FunctionType * function ) { 636 634 if ( function->get_returnVals().size() == 0 ) { … … 646 644 } 647 645 } 648 649 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) {650 assert(!"restore after AST added to build");651 // if ( func->returns.empty() ) return new ast::VoidType{};652 // if ( func->returns.size() == 1 ) return func->returns[0]->get_type();653 654 // std::vector<ast::ptr<ast::Type>> tys;655 // for ( const ast::DeclWithType * decl : func->returns ) {656 // tys.emplace_back( decl->get_type() );657 // }658 // return new ast::TupleType{ std::move(tys) };659 }660 646 } // namespace ResolvExpr 661 647 -
src/ResolvExpr/typeops.h
r204358b r10248ae0 18 18 #include <vector> 19 19 20 #include "AST/Node.hpp"21 #include "AST/Type.hpp"22 20 #include "SynTree/SynTree.h" 23 21 #include "SynTree/Type.h" … … 101 99 /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value. 102 100 Type * extractResultType( FunctionType * functionType ); 103 /// Creates or extracts the type represented by the list of returns in a `FunctionType`.104 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );105 101 106 102 // in CommonType.cc
Note:
See TracChangeset
for help on using the changeset viewer.