Changeset 204358b
- Timestamp:
- May 16, 2019, 2:57:41 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b336af9
- Parents:
- 10248ae0 (diff), f3cc5b6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 1 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/CVQualifiers.hpp
r10248ae0 r204358b 59 59 // ordering is a subtype relationship over qualifiers, e.g. `int` => `const int` is free 60 60 61 bool operator== ( Qualifiers a, Qualifiers b ) {61 inline bool operator== ( Qualifiers a, Qualifiers b ) { 62 62 return (a.val & EquivQualifiers) == (b.val & EquivQualifiers); 63 63 } 64 bool operator!= ( Qualifiers a, Qualifiers b ) {64 inline bool operator!= ( Qualifiers a, Qualifiers b ) { 65 65 return !(a == b); 66 66 } 67 bool operator<= ( Qualifiers a, Qualifiers b ) {67 inline 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 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; }73 inline bool operator< ( Qualifiers a, Qualifiers b ) { return a != b && a <= b; } 74 inline bool operator>= ( Qualifiers a, Qualifiers b ) { return b <= a; } 75 inline bool operator> ( Qualifiers a, Qualifiers b ) { return b < a; } 76 76 77 77 } -
src/AST/Convert.cpp
r10248ae0 r204358b 413 413 } 414 414 415 virtual void visit( AttrExpr * ) override final {416 417 }418 419 415 virtual void visit( LogicalExpr * ) override final { 420 416 -
src/AST/Decl.hpp
r10248ae0 r204358b 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 file 33 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node); 34 32 35 namespace ast { 33 34 class Attribute;35 class Expr;36 class Init;37 class TypeDecl;38 36 39 37 /// Base declaration class … … 60 58 private: 61 59 Decl * clone() const override = 0; 60 MUTATE_FRIEND 62 61 }; 63 62 … … 92 91 private: 93 92 DeclWithType * clone() const override = 0; 93 MUTATE_FRIEND 94 94 }; 95 95 … … 113 113 private: 114 114 ObjectDecl * clone() const override { return new ObjectDecl{ *this }; } 115 116 /// Must be copied in ALL derived classes 117 template<typename node_t> 118 friend auto mutate(const node_t * node); 115 MUTATE_FRIEND 119 116 }; 120 117 … … 140 137 private: 141 138 FunctionDecl * clone() const override { return new FunctionDecl( *this ); } 142 143 /// Must be copied in ALL derived classes 144 template<typename node_t> 145 friend auto mutate(const node_t * node); 139 MUTATE_FRIEND 146 140 }; 147 141 … … 150 144 public: 151 145 ptr<Type> base; 152 std::vector<ptr<TypeDecl>> param eters;146 std::vector<ptr<TypeDecl>> params; 153 147 std::vector<ptr<DeclWithType>> assertions; 154 148 155 149 NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 156 150 Type* b, Linkage::Spec spec = Linkage::Cforall ) 157 : Decl( loc, name, storage, spec ), base( b ), param eters(), assertions() {}151 : Decl( loc, name, storage, spec ), base( b ), params(), assertions() {} 158 152 159 153 /// Produces a name for the kind of alias … … 162 156 private: 163 157 NamedTypeDecl* clone() const override = 0; 158 MUTATE_FRIEND 164 159 }; 165 160 … … 203 198 private: 204 199 TypeDecl * clone() const override { return new TypeDecl{ *this }; } 205 206 /// Must be copied in ALL derived classes 207 template<typename node_t> 208 friend auto mutate(const node_t * node); 200 MUTATE_FRIEND 209 201 }; 210 202 … … 221 213 private: 222 214 TypedefDecl * clone() const override { return new TypedefDecl{ *this }; } 223 224 /// Must be copied in ALL derived classes 225 template<typename node_t> 226 friend auto mutate(const node_t * node); 215 MUTATE_FRIEND 227 216 }; 228 217 … … 231 220 public: 232 221 std::vector<ptr<Decl>> members; 233 std::vector<ptr<TypeDecl>> param eters;222 std::vector<ptr<TypeDecl>> params; 234 223 std::vector<ptr<Attribute>> attributes; 235 224 bool body = false; … … 238 227 AggregateDecl( const CodeLocation& loc, const std::string& name, 239 228 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall ) 240 : Decl( loc, name, Storage::Classes{}, linkage ), members(), param eters(),229 : Decl( loc, name, Storage::Classes{}, linkage ), members(), params(), 241 230 attributes( std::move(attrs) ) {} 242 231 243 232 AggregateDecl* set_body( bool b ) { body = b; return this; } 233 234 private: 235 AggregateDecl * clone() const override = 0; 236 MUTATE_FRIEND 244 237 245 238 protected: … … 265 258 private: 266 259 StructDecl * clone() const override { return new StructDecl{ *this }; } 267 268 /// Must be copied in ALL derived classes 269 template<typename node_t> 270 friend auto mutate(const node_t * node); 260 MUTATE_FRIEND 271 261 272 262 std::string typeString() const override { return "struct"; } … … 283 273 private: 284 274 UnionDecl * clone() const override { return new UnionDecl{ *this }; } 285 286 /// Must be copied in ALL derived classes 287 template<typename node_t> 288 friend auto mutate(const node_t * node); 275 MUTATE_FRIEND 289 276 290 277 std::string typeString() const override { return "union"; } … … 304 291 private: 305 292 EnumDecl * clone() const override { return new EnumDecl{ *this }; } 306 307 /// Must be copied in ALL derived classes 308 template<typename node_t> 309 friend auto mutate(const node_t * node); 293 MUTATE_FRIEND 310 294 311 295 std::string typeString() const override { return "enum"; } … … 325 309 private: 326 310 TraitDecl * clone() const override { return new TraitDecl{ *this }; } 327 328 /// Must be copied in ALL derived classes 329 template<typename node_t> 330 friend auto mutate(const node_t * node); 311 MUTATE_FRIEND 331 312 332 313 std::string typeString() const override { return "trait"; } … … 343 324 private: 344 325 AsmDecl *clone() const override { return new AsmDecl( *this ); } 345 346 /// Must be copied in ALL derived classes 347 template<typename node_t> 348 friend auto mutate(const node_t * node); 326 MUTATE_FRIEND 349 327 }; 350 328 … … 360 338 private: 361 339 StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 362 363 /// Must be copied in ALL derived classes 364 template<typename node_t> 365 friend auto mutate(const node_t * node); 340 MUTATE_FRIEND 366 341 }; 367 342 … … 402 377 } 403 378 379 #undef MUTATE_FRIEND 380 404 381 // Local Variables: // 405 382 // tab-width: 4 // -
src/AST/Expr.hpp
r10248ae0 r204358b 18 18 #include <cassert> 19 19 #include <map> 20 #include <string> 20 21 #include <utility> // for move 21 22 #include <vector> 22 23 23 24 #include "Fwd.hpp" // for UniqueId 25 #include "Label.hpp" 24 26 #include "ParseNode.hpp" 25 27 #include "Visitor.hpp" 28 29 // Must be included in *all* AST classes; should be #undef'd at the end of the file 30 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node); 26 31 27 32 namespace ast { … … 117 122 bool extension = false; 118 123 119 Expr(const CodeLocation & loc ) : ParseNode( loc ), result(), env(), inferred() {} 124 Expr( const CodeLocation & loc, const Type * res = nullptr ) 125 : ParseNode( loc ), result( res ), env(), inferred() {} 120 126 121 127 Expr * set_extension( bool ex ) { extension = ex; return this; } … … 124 130 private: 125 131 Expr * clone() const override = 0; 132 MUTATE_FRIEND 133 }; 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_FRIEND 148 }; 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 expression 160 static UntypedExpr * createDeref( const CodeLocation & loc, Expr * arg ); 161 /// Creates a new assignment expression 162 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_FRIEND 168 }; 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_FRIEND 182 }; 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_FRIEND 195 }; 196 197 /// GCC &&label 198 /// https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html 199 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_FRIEND 209 }; 210 211 /// Whether a cast existed in the program source or not 212 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-void 223 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_FRIEND 229 }; 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 type 241 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_FRIEND 247 }; 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_FRIEND 261 }; 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_FRIEND 276 }; 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_FRIEND 290 }; 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 function 300 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_FRIEND 306 }; 307 308 /// A compile-time constant 309 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 integer 327 long long int intValue() const; 328 /// Gets the value of this constant as floating point 329 double floatValue() const; 330 331 /// generates a boolean constant of the given bool 332 static ConstantExpr * from_bool( const CodeLocation & loc, bool b ); 333 /// generates a char constant of the given char 334 static ConstantExpr * from_char( const CodeLocation & loc, char c ); 335 /// generates an integer constant of the given int 336 static ConstantExpr * from_int( const CodeLocation & loc, int i ); 337 /// generates an integer constant of the given unsigned long int 338 static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i ); 339 /// generates a floating point constant of the given double 340 static ConstantExpr * from_double( const CodeLocation & loc, double d ); 341 /// generates an array of chars constant of the given string 342 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_FRIEND 350 }; 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_t 361 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_FRIEND 366 }; 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_t 377 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_FRIEND 382 }; 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_FRIEND 397 }; 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_FRIEND 411 }; 412 413 /// a pack of field-offsets for a generic type 414 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_FRIEND 424 }; 425 426 /// Variants of short-circuiting logical expression 427 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_FRIEND 442 }; 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_FRIEND 458 }; 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_FRIEND 126 473 }; 127 474 … … 136 483 private: 137 484 TypeExpr * clone() const override { return new TypeExpr{ *this }; } 138 }; 139 485 MUTATE_FRIEND 486 }; 487 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-Constraints 490 class AsmExpr final : public Expr { 491 public: 492 ptr<Expr> inout; 493 ptr<Expr> constraint; 494 }; 140 495 141 496 //================================================================================================= … … 146 501 inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); } 147 502 inline void decrement( const class Expr * 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); } 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); } 194 547 // inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); } 195 548 // inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); } … … 226 579 } 227 580 581 #undef MUTATE_FRIEND 582 228 583 // Local Variables: // 229 584 // tab-width: 4 // -
src/AST/Fwd.hpp
r10248ae0 r204358b 77 77 class OffsetofExpr; 78 78 class OffsetPackExpr; 79 class AttrExpr;80 79 class LogicalExpr; 81 80 class ConditionalExpr; … … 252 251 inline void increment( const class OffsetPackExpr *, Node::ref_type ); 253 252 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 );256 253 inline void increment( const class LogicalExpr *, Node::ref_type ); 257 254 inline void decrement( const class LogicalExpr *, Node::ref_type ); -
src/AST/Init.hpp
r10248ae0 r204358b 23 23 #include "Visitor.hpp" 24 24 25 // Must be included in *all* AST classes; should be #undef'd at the end of the file 26 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node); 27 25 28 namespace ast { 26 29 … … 40 43 private: 41 44 Designation* clone() const override { return new Designation{ *this }; } 45 MUTATE_FRIEND 42 46 }; 43 47 … … 55 59 private: 56 60 const Init * clone() const override = 0; 61 MUTATE_FRIEND 57 62 }; 58 63 … … 69 74 private: 70 75 SingleInit * clone() const override { return new SingleInit{ *this }; } 71 72 /// Must be copied in ALL derived classes 73 template<typename node_t> 74 friend auto mutate(const node_t * node); 76 MUTATE_FRIEND 75 77 }; 76 78 … … 97 99 private: 98 100 ListInit * clone() const override { return new ListInit{ *this }; } 99 100 /// Must be copied in ALL derived classes 101 template<typename node_t> 102 friend auto mutate(const node_t * node); 101 MUTATE_FRIEND 103 102 }; 104 103 … … 120 119 private: 121 120 ConstructorInit * clone() const override { return new ConstructorInit{ *this }; } 122 123 /// Must be copied in ALL derived classes 124 template<typename node_t> 125 friend auto mutate(const node_t * node); 121 MUTATE_FRIEND 126 122 }; 127 123 … … 142 138 } 143 139 140 #undef MUTATE_FRIEND 141 144 142 // Local Variables: // 145 143 // tab-width: 4 // -
src/AST/Node.hpp
r10248ae0 r204358b 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_cast 139 140 template<typename o_node_t> 140 141 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 mutates 147 assign( n ); 148 // get mutable version of `n` 149 auto r = mutate( node ); 150 // re-assign mutable version in case `mutate()` produced a new pointer 151 assign( r ); 152 return r; 153 } 141 154 142 155 using ptr = const node_t *; -
src/AST/Stmt.hpp
r10248ae0 r204358b 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 file 29 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node); 30 28 31 namespace ast { 29 32 … … 35 38 std::vector<Label> labels; 36 39 37 Stmt( const CodeLocation & loc, std::vector<Label>&& labels = {} )40 Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} ) 38 41 : ParseNode(loc), labels(std::move(labels)) {} 39 42 40 43 Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {} 41 44 42 const Stmt* accept( Visitor& v ) const override = 0; 43 private: 44 Stmt* clone() const override = 0; 45 const Stmt * accept( Visitor & v ) const override = 0; 46 private: 47 Stmt * clone() const override = 0; 48 MUTATE_FRIEND 45 49 }; 46 50 … … 50 54 std::list<ptr<Stmt>> kids; 51 55 52 CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>>&& ks = {} )56 CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {} ) 53 57 : Stmt(loc), kids(std::move(ks)) {} 54 58 … … 56 60 CompoundStmt( CompoundStmt&& o ) = default; 57 61 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); 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 68 69 }; 69 70 … … 71 72 class NullStmt final : public Stmt { 72 73 public: 73 NullStmt( const CodeLocation & loc, std::vector<Label>&& labels = {} )74 NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} ) 74 75 : Stmt(loc, std::move(labels)) {} 75 76 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); 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 83 81 }; 84 82 … … 90 88 ExprStmt( const CodeLocation & loc, const Expr * e ) : Stmt(loc), expr(e) {} 91 89 92 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }90 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 93 91 private: 94 92 ExprStmt * clone() const override { return new ExprStmt{ *this }; } 95 96 /// Must be copied in ALL derived classes 97 template<typename node_t> 98 friend auto mutate(const node_t * node); 93 MUTATE_FRIEND 99 94 }; 100 95 … … 107 102 std::vector<Label> gotoLabels; 108 103 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 = {})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 = {}) 113 108 : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction), 114 109 output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)), 115 110 gotoLabels(std::move(gotoLabels)) {} 116 111 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); 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 124 116 }; 125 117 … … 128 120 std::string directive; 129 121 130 DirectiveStmt( const CodeLocation & loc, const std::string & directive,131 std::vector<Label> && labels = {} )122 DirectiveStmt( const CodeLocation & loc, const std::string & directive, 123 std::vector<Label> && labels = {} ) 132 124 : Stmt(loc, std::move(labels)), directive(directive) {} 133 125 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); 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 141 130 }; 142 131 … … 148 137 std::vector<ptr<Stmt>> inits; 149 138 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 = {} )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 = {} ) 153 142 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart), 154 143 inits(std::move(inits)) {} 155 144 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); 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 163 149 }; 164 150 … … 168 154 std::vector<ptr<Stmt>> stmts; 169 155 170 SwitchStmt( const CodeLocation & loc, const Expr* cond, std::vector<ptr<Stmt>>&& stmts,171 std::vector<Label> && labels = {} )156 SwitchStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts, 157 std::vector<Label> && labels = {} ) 172 158 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 173 159 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); 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 181 164 }; 182 165 … … 186 169 std::vector<ptr<Stmt>> stmts; 187 170 188 CaseStmt( const CodeLocation& loc, const Expr* cond, std::vector<ptr<Stmt>>&& stmts,189 std::vector<Label>&& labels = {} )190 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)) {} 191 174 192 175 bool isDefault() { return !cond; } 193 176 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); 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 201 181 }; 202 182 … … 208 188 bool isDoWhile; 209 189 210 WhileStmt( const CodeLocation & loc, const Expr* cond, const Stmt* body,211 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label>&& labels = {} )190 WhileStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, 191 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} ) 212 192 : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)), 213 193 isDoWhile(isDoWhile) {} 214 194 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); 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 222 199 }; 223 200 … … 229 206 ptr<Stmt> body; 230 207 231 ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>>&& inits, const Expr* cond,232 const Expr * inc, const Stmt* body, std::vector<Label>&& labels = {} )208 ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>> && inits, const Expr * cond, 209 const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} ) 233 210 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), 234 211 body(body) {} 235 212 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); 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 243 217 }; 244 218 … … 253 227 Kind kind; 254 228 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 = {} )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 = {} ) 259 233 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), 260 234 computedTarget(computedTarget), kind(Goto) {} … … 262 236 const char * kindName() { return kindNames[kind]; } 263 237 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); 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 271 242 272 243 static const char * kindNames[kindEnd]; … … 277 248 ptr<Expr> expr; 278 249 279 ReturnStmt( const CodeLocation & loc, const Expr* expr, std::vector<Label>&& labels = {} )250 ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} ) 280 251 : Stmt(loc, std::move(labels)), expr(expr) {} 281 252 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); 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 289 257 }; 290 258 … … 297 265 Kind kind; 298 266 299 ThrowStmt( const CodeLocation & loc, Kind kind, const Expr* expr, const Expr* target,300 std::vector<Label> && labels = {} )267 ThrowStmt( const CodeLocation & loc, Kind kind, const Expr * expr, const Expr * target, 268 std::vector<Label> && labels = {} ) 301 269 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {} 302 270 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); 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 310 275 }; 311 276 … … 316 281 ptr<FinallyStmt> finally; 317 282 318 TryStmt( const CodeLocation & loc, const CompoundStmt* body,319 std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt* finally,320 std::vector<Label> && labels = {} )283 TryStmt( const CodeLocation & loc, const CompoundStmt * body, 284 std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt * finally, 285 std::vector<Label> && labels = {} ) 321 286 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {} 322 287 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); 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 330 292 }; 331 293 … … 339 301 Kind kind; 340 302 341 CatchStmt( const CodeLocation & loc, Kind kind, const Decl* decl, const Expr* cond,342 const Stmt * body, std::vector<Label>&& labels = {} )303 CatchStmt( const CodeLocation & loc, Kind kind, const Decl * decl, const Expr * cond, 304 const Stmt * body, std::vector<Label> && labels = {} ) 343 305 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {} 344 306 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); 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 352 311 }; 353 312 … … 356 315 ptr<CompoundStmt> body; 357 316 358 FinallyStmt( const CodeLocation & loc, const CompoundStmt* body,359 std::vector<Label> && labels = {} )317 FinallyStmt( const CodeLocation & loc, const CompoundStmt * body, 318 std::vector<Label> && labels = {} ) 360 319 : Stmt(loc, std::move(labels)), body(body) {} 361 320 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); 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 369 325 }; 370 326 … … 397 353 OrElse orElse; 398 354 399 WaitForStmt( const CodeLocation & loc, std::vector<Label>&& labels = {} )355 WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} ) 400 356 : Stmt(loc, std::move(labels)) {} 401 357 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); 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 409 362 }; 410 363 … … 414 367 ptr<Stmt> stmt; 415 368 416 WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>>&& exprs, const Stmt* stmt,417 std::vector<Label> && labels = {} )369 WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt, 370 std::vector<Label> && labels = {} ) 418 371 : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {} 419 372 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); 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 427 377 }; 428 378 … … 431 381 ptr<Decl> decl; 432 382 433 DeclStmt( const CodeLocation & loc, const Decl* decl, std::vector<Label>&& labels = {} )383 DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} ) 434 384 : Stmt(loc, std::move(labels)), decl(decl) {} 435 385 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); 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 443 390 }; 444 391 … … 447 394 readonly<Stmt> callStmt; 448 395 449 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt* callStmt,450 std::vector<Label> && labels = {} )396 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt, 397 std::vector<Label> && labels = {} ) 451 398 : Stmt(loc, std::move(labels)), callStmt(callStmt) {} 452 399 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); 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 460 404 }; 461 405 … … 510 454 } 511 455 456 #undef MUTATE_FRIEND 457 512 458 // Local Variables: // 513 459 // tab-width: 4 // -
src/AST/Type.hpp
r10248ae0 r204358b 29 29 #include "Visitor.hpp" 30 30 31 // Must be included in *all* AST classes; should be #undef'd at the end of the file 32 #define MUTATE_FRIEND template<typename node_t> friend auto mutate(const node_t * node); 33 31 34 namespace ast { 32 35 33 36 class Type : public Node { 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; } 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; } 52 54 53 55 /// How many elemental types are represented by this type … … 71 73 private: 72 74 virtual Type * clone() const override = 0; 75 MUTATE_FRIEND 73 76 }; 74 77 … … 85 88 private: 86 89 VoidType * clone() const override { return new VoidType{ *this }; } 90 MUTATE_FRIEND 87 91 }; 88 92 … … 147 151 private: 148 152 BasicType * clone() const override { return new BasicType{ *this }; } 153 MUTATE_FRIEND 149 154 }; 150 155 … … 177 182 private: 178 183 PointerType * clone() const override { return new PointerType{ *this }; } 184 MUTATE_FRIEND 179 185 }; 180 186 … … 198 204 private: 199 205 ArrayType * clone() const override { return new ArrayType{ *this }; } 206 MUTATE_FRIEND 200 207 }; 201 208 … … 217 224 private: 218 225 ReferenceType * clone() const override { return new ReferenceType{ *this }; } 226 MUTATE_FRIEND 219 227 }; 220 228 … … 231 239 private: 232 240 QualifiedType * clone() const override { return new QualifiedType{ *this }; } 241 MUTATE_FRIEND 233 242 }; 234 243 … … 246 255 private: 247 256 virtual ParameterizedType * clone() const override = 0; 257 MUTATE_FRIEND 248 258 }; 249 259 … … 254 264 class FunctionType final : public ParameterizedType { 255 265 public: 256 std::vector<ptr<DeclWithType>> return Vals;257 std::vector<ptr<DeclWithType>> param eters;266 std::vector<ptr<DeclWithType>> returns; 267 std::vector<ptr<DeclWithType>> params; 258 268 259 269 /// Does the function accept a variable number of arguments following the arguments specified … … 265 275 266 276 FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} ) 267 : ParameterizedType(q), return Vals(), parameters(), isVarArgs(va) {}277 : ParameterizedType(q), returns(), params(), isVarArgs(va) {} 268 278 269 279 /// true if either the parameters or return values contain a tttype 270 280 bool isTtype() const; 271 281 /// true if function parameters are unconstrained by prototype 272 bool isUnprototyped() const { return isVarArgs && param eters.size() == 0; }282 bool isUnprototyped() const { return isVarArgs && params.size() == 0; } 273 283 274 284 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 275 285 private: 276 286 FunctionType * clone() const override { return new FunctionType{ *this }; } 287 MUTATE_FRIEND 277 288 }; 278 289 … … 280 291 class ReferenceToType : public ParameterizedType { 281 292 public: 282 std::vector<ptr<Expr>> param eters;293 std::vector<ptr<Expr>> params; 283 294 std::vector<ptr<Attribute>> attributes; 284 295 std::string name; … … 287 298 ReferenceToType( const std::string& n, CV::Qualifiers q = {}, 288 299 std::vector<ptr<Attribute>> && as = {} ) 289 : ParameterizedType(q), param eters(), attributes(std::move(as)), name(n) {}300 : ParameterizedType(q), params(), attributes(std::move(as)), name(n) {} 290 301 291 302 /// Gets aggregate declaration this type refers to … … 296 307 private: 297 308 virtual ReferenceToType * clone() const override = 0; 309 MUTATE_FRIEND 298 310 299 311 protected: … … 320 332 private: 321 333 StructInstType * clone() const override { return new StructInstType{ *this }; } 334 MUTATE_FRIEND 322 335 323 336 std::string typeString() const override { return "struct"; } … … 342 355 private: 343 356 UnionInstType * clone() const override { return new UnionInstType{ *this }; } 357 MUTATE_FRIEND 344 358 345 359 std::string typeString() const override { return "union"; } … … 364 378 private: 365 379 EnumInstType * clone() const override { return new EnumInstType{ *this }; } 380 MUTATE_FRIEND 366 381 367 382 std::string typeString() const override { return "enum"; } … … 387 402 private: 388 403 TraitInstType * clone() const override { return new TraitInstType{ *this }; } 404 MUTATE_FRIEND 389 405 390 406 std::string typeString() const override { return "trait"; } … … 415 431 private: 416 432 TypeInstType * clone() const override { return new TypeInstType{ *this }; } 433 MUTATE_FRIEND 417 434 418 435 std::string typeString() const override { return "type"; } … … 443 460 private: 444 461 TupleType * clone() const override { return new TupleType{ *this }; } 462 MUTATE_FRIEND 445 463 }; 446 464 … … 457 475 private: 458 476 TypeofType * clone() const override { return new TypeofType{ *this }; } 477 MUTATE_FRIEND 459 478 }; 460 479 … … 467 486 private: 468 487 VarArgsType * clone() const override { return new VarArgsType{ *this }; } 488 MUTATE_FRIEND 469 489 }; 470 490 … … 476 496 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 477 497 private: 478 ZeroType * clone() const override { return new ZeroType{ *this }; } 498 ZeroType * clone() const override { return new ZeroType{ *this }; } 499 MUTATE_FRIEND 479 500 }; 480 501 … … 487 508 private: 488 509 OneType * clone() const override { return new OneType{ *this }; } 510 MUTATE_FRIEND 489 511 }; 490 512 … … 497 519 private: 498 520 GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; } 521 MUTATE_FRIEND 499 522 }; 500 523 … … 547 570 } 548 571 572 #undef MUTATE_FRIEND 573 549 574 // Local Variables: // 550 575 // tab-width: 4 // -
src/AST/Visitor.hpp
r10248ae0 r204358b 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;72 71 virtual const ast::Expr * visit( const ast::LogicalExpr * ) = 0; 73 72 virtual const ast::Expr * visit( const ast::ConditionalExpr * ) = 0; -
src/AST/porting.md
r10248ae0 r204358b 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)` 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 9 27 10 28 ## Visitors ## … … 106 124 * allows `newObject` as just default settings 107 125 126 `NamedTypeDecl` 127 * `parameters` => `params` 128 108 129 `TypeDecl` 109 130 * moved `TypeDecl::Kind` to `ast::TypeVar::Kind` 131 132 `AggregateDecl` 133 * `parameters` => `params` 110 134 111 135 `EnumDecl` … … 115 139 * Merged `inferParams`/`resnSlots` into union, as suggested by comment in old version 116 140 * does imply get_/set_ API, and some care about moving backward 141 * added constructor that sets result, for benefit of types that set it directly 142 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 constructor 152 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 uses 157 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 `||` 117 167 118 168 `Init` … … 148 198 `Type` 149 199 * `CV::Qualifiers` moved to end of constructor parameter list, defaulted to `{}` 200 * removed getter, setter in favour of public `qualifiers` field 150 201 * `ReferenceToType` puts a defaulted list of attributes after qualifiers 151 202 * `forall` field split off into `ParameterizedType` subclass … … 160 211 * `getAggr()` => `aggr()` 161 212 * also now returns `const AggregateDecl *` 162 * `genericSubstitution()` moved to own visitor **TODO** write213 * `genericSubstitution()` moved to own visitor in `AST/GenericSubstitution.hpp` **TODO** write 163 214 164 215 `BasicType` … … 167 218 `ReferenceToType` 168 219 * deleted `get_baseParameters()` from children 169 * replace with `aggr() ? aggr()->parameters : nullptr` 220 * replace with `aggr() ? aggr()->params : nullptr` 221 * `parameters` => `params` 170 222 * hoisted `lookup` implementation into parent, made non-virtual 171 223 * also changed to return vector rather than filling; change back if any great win for reuse … … 178 230 179 231 `FunctionType` 232 * `returnVals` => `returns` 233 * `parameters` => `params` 180 234 * `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;` 181 235 -
src/ResolvExpr/Unify.cc
r10248ae0 r204358b 21 21 #include <string> // for string, operator==, operator!=, bas... 22 22 #include <utility> // for pair, move 23 23 #include <vector> 24 25 #include "AST/Node.hpp" 26 #include "AST/Type.hpp" 24 27 #include "Common/PassVisitor.h" // for PassVisitor 25 28 #include "FindOpenVars.h" // for findOpenVars … … 630 633 } 631 634 632 // xxx - compute once and store in the FunctionType?633 635 Type * extractResultType( FunctionType * function ) { 634 636 if ( function->get_returnVals().size() == 0 ) { … … 644 646 } 645 647 } 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 } 646 660 } // namespace ResolvExpr 647 661 -
src/ResolvExpr/typeops.h
r10248ae0 r204358b 18 18 #include <vector> 19 19 20 #include "AST/Node.hpp" 21 #include "AST/Type.hpp" 20 22 #include "SynTree/SynTree.h" 21 23 #include "SynTree/Type.h" … … 99 101 /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value. 100 102 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 ); 101 105 102 106 // in CommonType.cc
Note: See TracChangeset
for help on using the changeset viewer.