Changes in / [204358b:10248ae0]


Ignore:
Location:
src
Files:
1 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • src/AST/CVQualifiers.hpp

    r204358b r10248ae0  
    5959        // ordering is a subtype relationship over qualifiers, e.g. `int` => `const int` is free
    6060
    61         inline bool operator== ( Qualifiers a, Qualifiers b ) {
     61        bool operator== ( Qualifiers a, Qualifiers b ) {
    6262                return (a.val & EquivQualifiers) == (b.val & EquivQualifiers);
    6363        }
    64         inline bool operator!= ( Qualifiers a, Qualifiers b ) {
     64        bool operator!= ( Qualifiers a, Qualifiers b ) {
    6565                return !(a == b);
    6666        }
    67         inline bool operator<= ( Qualifiers a, Qualifiers b ) {
     67        bool operator<= ( Qualifiers a, Qualifiers b ) {
    6868                return a.is_const    <= b.is_const    // non-const converts to const for free
    6969                        && a.is_volatile <= b.is_volatile // non-volatile converts to volatile for free
     
    7171                        && a.is_atomic   == b.is_atomic;  // atomicity must be preserved in free conversion
    7272        }
    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; }
     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; }
    7676
    7777}
  • src/AST/Convert.cpp

    r204358b r10248ae0  
    413413        }
    414414
     415        virtual void visit( AttrExpr * ) override final {
     416
     417        }
     418
    415419        virtual void visit( LogicalExpr * ) override final {
    416420
  • src/AST/Decl.hpp

    r204358b r10248ae0  
    3030#include "Parser/ParseNode.h"  // for DeclarationNode::Aggregate
    3131
    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 
    3532namespace ast {
     33
     34class Attribute;
     35class Expr;
     36class Init;
     37class TypeDecl;
    3638
    3739/// Base declaration class
     
    5860private:
    5961        Decl * clone() const override = 0;
    60         MUTATE_FRIEND
    6162};
    6263
     
    9192private:
    9293        DeclWithType * clone() const override = 0;
    93         MUTATE_FRIEND
    9494};
    9595
     
    113113private:
    114114        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);
    116119};
    117120
     
    137140private:
    138141        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);
    140146};
    141147
     
    144150public:
    145151        ptr<Type> base;
    146         std::vector<ptr<TypeDecl>> params;
     152        std::vector<ptr<TypeDecl>> parameters;
    147153        std::vector<ptr<DeclWithType>> assertions;
    148154
    149155        NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
    150156                Type* b, Linkage::Spec spec = Linkage::Cforall )
    151         : Decl( loc, name, storage, spec ), base( b ), params(), assertions() {}
     157        : Decl( loc, name, storage, spec ), base( b ), parameters(), assertions() {}
    152158
    153159        /// Produces a name for the kind of alias
     
    156162private:
    157163        NamedTypeDecl* clone() const override = 0;
    158         MUTATE_FRIEND
    159164};
    160165
     
    198203private:
    199204        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);
    201209};
    202210
     
    213221private:
    214222        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);
    216227};
    217228
     
    220231public:
    221232        std::vector<ptr<Decl>> members;
    222         std::vector<ptr<TypeDecl>> params;
     233        std::vector<ptr<TypeDecl>> parameters;
    223234        std::vector<ptr<Attribute>> attributes;
    224235        bool body = false;
     
    227238        AggregateDecl( const CodeLocation& loc, const std::string& name,
    228239                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    229         : Decl( loc, name, Storage::Classes{}, linkage ), members(), params(),
     240        : Decl( loc, name, Storage::Classes{}, linkage ), members(), parameters(),
    230241          attributes( std::move(attrs) ) {}
    231242
    232243        AggregateDecl* set_body( bool b ) { body = b; return this; }
    233 
    234 private:
    235         AggregateDecl * clone() const override = 0;
    236         MUTATE_FRIEND
    237244
    238245protected:
     
    258265private:
    259266        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);
    261271
    262272        std::string typeString() const override { return "struct"; }
     
    273283private:
    274284        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);
    276289
    277290        std::string typeString() const override { return "union"; }
     
    291304private:
    292305        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);
    294310
    295311        std::string typeString() const override { return "enum"; }
     
    309325private:
    310326        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);
    312331
    313332        std::string typeString() const override { return "trait"; }
     
    324343private:
    325344        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);
    327349};
    328350
     
    338360private:
    339361        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);
    341366};
    342367
     
    377402}
    378403
    379 #undef MUTATE_FRIEND
    380 
    381404// Local Variables: //
    382405// tab-width: 4 //
  • src/AST/Expr.hpp

    r204358b r10248ae0  
    1818#include <cassert>
    1919#include <map>
    20 #include <string>
    2120#include <utility>        // for move
    2221#include <vector>
    2322
    2423#include "Fwd.hpp"        // for UniqueId
    25 #include "Label.hpp"
    2624#include "ParseNode.hpp"
    2725#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);
    3126
    3227namespace ast {
     
    122117        bool extension = false;
    123118
    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() {}
    126120
    127121        Expr * set_extension( bool ex ) { extension = ex; return this; }
     
    130124private:
    131125        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
    473126};
    474127
     
    483136private:
    484137        TypeExpr * clone() const override { return new TypeExpr{ *this }; }
    485         MUTATE_FRIEND
    486138};
    487139
    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 };
    495140
    496141//=================================================================================================
     
    501146inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); }
    502147inline 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); }
    547194// inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); }
    548195// inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     
    579226}
    580227
    581 #undef MUTATE_FRIEND
    582 
    583228// Local Variables: //
    584229// tab-width: 4 //
  • src/AST/Fwd.hpp

    r204358b r10248ae0  
    7777class OffsetofExpr;
    7878class OffsetPackExpr;
     79class AttrExpr;
    7980class LogicalExpr;
    8081class ConditionalExpr;
     
    251252inline void increment( const class OffsetPackExpr *, Node::ref_type );
    252253inline void decrement( const class OffsetPackExpr *, Node::ref_type );
     254inline void increment( const class AttrExpr *, Node::ref_type );
     255inline void decrement( const class AttrExpr *, Node::ref_type );
    253256inline void increment( const class LogicalExpr *, Node::ref_type );
    254257inline void decrement( const class LogicalExpr *, Node::ref_type );
  • src/AST/Init.hpp

    r204358b r10248ae0  
    2323#include "Visitor.hpp"
    2424
    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 
    2825namespace ast {
    2926
     
    4340private:
    4441        Designation* clone() const override { return new Designation{ *this }; }
    45         MUTATE_FRIEND
    4642};
    4743
     
    5955private:
    6056        const Init * clone() const override = 0;
    61         MUTATE_FRIEND
    6257};
    6358
     
    7469private:
    7570        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);
    7775};
    7876
     
    9997private:
    10098        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);
    102103};
    103104
     
    119120private:
    120121        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);
    122126};
    123127
     
    138142}
    139143
    140 #undef MUTATE_FRIEND
    141 
    142144// Local Variables: //
    143145// tab-width: 4 //
  • src/AST/Node.hpp

    r204358b r10248ae0  
    7676// problems and be able to use auto return
    7777template<typename node_t>
    78 auto mutate( const node_t * node ) {
     78auto mutate(const node_t * node) {
    7979        assertf(
    8080                node->strong_count >= 1,
     
    9292}
    9393
    94 std::ostream& operator<< ( std::ostream& out, const Node * node );
     94std::ostream& operator<< ( std::ostream& out, const Node* node );
    9595
    9696/// Base class for the smart pointer types
     
    137137        operator const node_t * () const { return node; }
    138138
    139         /// wrapper for convenient access to dynamic_cast
    140139        template<typename o_node_t>
    141140        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         }
    154141
    155142        using ptr = const node_t *;
  • src/AST/Stmt.hpp

    r204358b r10248ae0  
    2626#include "Common/CodeLocation.h"
    2727
    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 
    3128namespace ast {
    3229
     
    3835        std::vector<Label> labels;
    3936
    40         Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
     37        Stmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
    4138        : ParseNode(loc), labels(std::move(labels)) {}
    4239
    4340        Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {}
    4441
    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;
     43private:
     44        Stmt* clone() const override = 0;
    4945};
    5046
     
    5450        std::list<ptr<Stmt>> kids;
    5551
    56         CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {} )
     52        CompoundStmt(const CodeLocation& loc, std::list<ptr<Stmt>>&& ks = {} )
    5753        : Stmt(loc), kids(std::move(ks)) {}
    5854
     
    6056        CompoundStmt( CompoundStmt&& o ) = default;
    6157
    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 ); }
     62private:
     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);
    6968};
    7069
     
    7271class NullStmt final : public Stmt {
    7372public:
    74         NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
     73        NullStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
    7574        : Stmt(loc, std::move(labels)) {}
    7675
    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 ); }
     77private:
     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);
    8183};
    8284
     
    8890        ExprStmt( const CodeLocation & loc, const Expr * e ) : Stmt(loc), expr(e) {}
    8991
    90         const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     92        const Stmt * accept( Visitor& v ) const override { return v.visit( this ); }
    9193private:
    9294        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);
    9499};
    95100
     
    102107        std::vector<Label> gotoLabels;
    103108
    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 = {})
    108113        : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),
    109114          output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),
    110115          gotoLabels(std::move(gotoLabels)) {}
    111116
    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 ); }
     118private:
     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);
    116124};
    117125
     
    120128        std::string directive;
    121129
    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 = {} )
    124132        : Stmt(loc, std::move(labels)), directive(directive) {}
    125133
    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 ); }
     135private:
     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);
    130141};
    131142
     
    137148        std::vector<ptr<Stmt>> inits;
    138149
    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 = {} )
    142153        : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),
    143154          inits(std::move(inits)) {}
    144155
    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 ); }
     157private:
     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);
    149163};
    150164
     
    154168        std::vector<ptr<Stmt>> stmts;
    155169
    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 = {} )
    158172        : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
    159173
    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 ); }
     175private:
     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);
    164181};
    165182
     
    169186        std::vector<ptr<Stmt>> stmts;
    170187
    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)) {}
    174191
    175192        bool isDefault() { return !cond; }
    176193
    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 ); }
     195private:
     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);
    181201};
    182202
     
    188208        bool isDoWhile;
    189209
    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 = {} )
    192212        : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)),
    193213          isDoWhile(isDoWhile) {}
    194214
    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 ); }
     216private:
     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);
    199222};
    200223
     
    206229        ptr<Stmt> body;
    207230
    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 = {} )
    210233        : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
    211234          body(body) {}
    212235
    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 ); }
     237private:
     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);
    217243};
    218244
     
    227253        Kind kind;
    228254
    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 = {} )
    233259        : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc),
    234260          computedTarget(computedTarget), kind(Goto) {}
     
    236262        const char * kindName() { return kindNames[kind]; }
    237263
    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 ); }
     265private:
     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);
    242271
    243272        static const char * kindNames[kindEnd];
     
    248277        ptr<Expr> expr;
    249278
    250         ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} )
     279        ReturnStmt( const CodeLocation& loc, const Expr* expr, std::vector<Label>&& labels = {} )
    251280        : Stmt(loc, std::move(labels)), expr(expr) {}
    252281
    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 ); }
     283private:
     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);
    257289};
    258290
     
    265297        Kind kind;
    266298
    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 = {} )
    269301        : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
    270302
    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 ); }
     304private:
     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);
    275310};
    276311
     
    281316        ptr<FinallyStmt> finally;
    282317
    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 = {} )
    286321        : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
    287322
    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 ); }
     324private:
     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);
    292330};
    293331
     
    301339        Kind kind;
    302340
    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 = {} )
    305343        : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {}
    306344
    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 ); }
     346private:
     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);
    311352};
    312353
     
    315356        ptr<CompoundStmt> body;
    316357
    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 = {} )
    319360        : Stmt(loc, std::move(labels)), body(body) {}
    320361
    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 ); }
     363private:
     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);
    325369};
    326370
     
    353397        OrElse orElse;
    354398
    355         WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
     399        WaitForStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
    356400        : Stmt(loc, std::move(labels)) {}
    357401
    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 ); }
     403private:
     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);
    362409};
    363410
     
    367414        ptr<Stmt> stmt;
    368415
    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 = {} )
    371418        : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
    372419
    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 ); }
     421private:
     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);
    377427};
    378428
     
    381431        ptr<Decl> decl;
    382432
    383         DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} )
     433        DeclStmt( const CodeLocation& loc, const Decl* decl, std::vector<Label>&& labels = {} )
    384434        : Stmt(loc, std::move(labels)), decl(decl) {}
    385435
    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 ); }
     437private:
     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);
    390443};
    391444
     
    394447        readonly<Stmt> callStmt;
    395448
    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 = {} )
    398451        : Stmt(loc, std::move(labels)), callStmt(callStmt) {}
    399452
    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 ); }
     454private:
     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);
    404460};
    405461
     
    454510}
    455511
    456 #undef MUTATE_FRIEND
    457 
    458512// Local Variables: //
    459513// tab-width: 4 //
  • src/AST/Type.hpp

    r204358b r10248ae0  
    2929#include "Visitor.hpp"
    3030
    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 
    3431namespace ast {
    3532
    3633class 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;
     35public:
     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; }
    5452
    5553        /// How many elemental types are represented by this type
     
    7371private:
    7472        virtual Type * clone() const override = 0;
    75         MUTATE_FRIEND
    7673};
    7774
     
    8885private:
    8986        VoidType * clone() const override { return new VoidType{ *this }; }
    90         MUTATE_FRIEND
    9187};
    9288
     
    151147private:
    152148        BasicType * clone() const override { return new BasicType{ *this }; }
    153         MUTATE_FRIEND
    154149};
    155150
     
    182177private:
    183178        PointerType * clone() const override { return new PointerType{ *this }; }
    184         MUTATE_FRIEND
    185179};
    186180
     
    204198private:
    205199        ArrayType * clone() const override { return new ArrayType{ *this }; }
    206         MUTATE_FRIEND
    207200};
    208201
     
    224217private:
    225218        ReferenceType * clone() const override { return new ReferenceType{ *this }; }
    226         MUTATE_FRIEND
    227219};
    228220
     
    239231private:
    240232        QualifiedType * clone() const override { return new QualifiedType{ *this }; }
    241         MUTATE_FRIEND
    242233};
    243234
     
    255246private:
    256247        virtual ParameterizedType * clone() const override = 0;
    257         MUTATE_FRIEND
    258248};
    259249
     
    264254class FunctionType final : public ParameterizedType {
    265255public:
    266         std::vector<ptr<DeclWithType>> returns;
    267         std::vector<ptr<DeclWithType>> params;
     256        std::vector<ptr<DeclWithType>> returnVals;
     257        std::vector<ptr<DeclWithType>> parameters;
    268258
    269259        /// Does the function accept a variable number of arguments following the arguments specified
     
    275265
    276266        FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} )
    277         : ParameterizedType(q), returns(), params(), isVarArgs(va) {}
     267        : ParameterizedType(q), returnVals(), parameters(), isVarArgs(va) {}
    278268
    279269        /// true if either the parameters or return values contain a tttype
    280270        bool isTtype() const;
    281271        /// true if function parameters are unconstrained by prototype
    282         bool isUnprototyped() const { return isVarArgs && params.size() == 0; }
     272        bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; }
    283273
    284274        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    285275private:
    286276        FunctionType * clone() const override { return new FunctionType{ *this }; }
    287         MUTATE_FRIEND
    288277};
    289278
     
    291280class ReferenceToType : public ParameterizedType {
    292281public:
    293         std::vector<ptr<Expr>> params;
     282        std::vector<ptr<Expr>> parameters;
    294283        std::vector<ptr<Attribute>> attributes;
    295284        std::string name;
     
    298287        ReferenceToType( const std::string& n, CV::Qualifiers q = {},
    299288                std::vector<ptr<Attribute>> && as = {} )
    300         : ParameterizedType(q), params(), attributes(std::move(as)), name(n) {}
     289        : ParameterizedType(q), parameters(), attributes(std::move(as)), name(n) {}
    301290
    302291        /// Gets aggregate declaration this type refers to
     
    307296private:
    308297        virtual ReferenceToType * clone() const override = 0;
    309         MUTATE_FRIEND
    310298
    311299protected:
     
    332320private:
    333321        StructInstType * clone() const override { return new StructInstType{ *this }; }
    334         MUTATE_FRIEND
    335322
    336323        std::string typeString() const override { return "struct"; }
     
    355342private:
    356343        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
    357         MUTATE_FRIEND
    358344
    359345        std::string typeString() const override { return "union"; }
     
    378364private:
    379365        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
    380         MUTATE_FRIEND
    381366
    382367        std::string typeString() const override { return "enum"; }
     
    402387private:
    403388        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
    404         MUTATE_FRIEND
    405389
    406390        std::string typeString() const override { return "trait"; }
     
    431415private:
    432416        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
    433         MUTATE_FRIEND
    434417
    435418        std::string typeString() const override { return "type"; }
     
    460443private:
    461444        TupleType * clone() const override { return new TupleType{ *this }; }
    462         MUTATE_FRIEND
    463445};
    464446
     
    475457private:
    476458        TypeofType * clone() const override { return new TypeofType{ *this }; }
    477         MUTATE_FRIEND
    478459};
    479460
     
    486467private:
    487468        VarArgsType * clone() const override { return new VarArgsType{ *this }; }
    488         MUTATE_FRIEND
    489469};
    490470
     
    496476        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    497477private:
    498         ZeroType * clone() const override { return new ZeroType{ *this }; }
    499         MUTATE_FRIEND
     478        ZeroType * clone() const override { return new ZeroType{ *this }; }     
    500479};
    501480
     
    508487private:
    509488        OneType * clone() const override { return new OneType{ *this }; }
    510         MUTATE_FRIEND
    511489};
    512490
     
    519497private:
    520498        GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; }
    521         MUTATE_FRIEND
    522499};
    523500
     
    570547}
    571548
    572 #undef MUTATE_FRIEND
    573 
    574549// Local Variables: //
    575550// tab-width: 4 //
  • src/AST/Visitor.hpp

    r204358b r10248ae0  
    6969    virtual const ast::Expr *             visit( const ast::OffsetofExpr         * ) = 0;
    7070    virtual const ast::Expr *             visit( const ast::OffsetPackExpr       * ) = 0;
     71    virtual const ast::Expr *             visit( const ast::AttrExpr             * ) = 0;
    7172    virtual const ast::Expr *             visit( const ast::LogicalExpr          * ) = 0;
    7273    virtual const ast::Expr *             visit( const ast::ConditionalExpr      * ) = 0;
  • src/AST/porting.md

    r204358b r10248ae0  
    66  * specialization: strong pointer `ast::ptr<T>` is used for an ownership relationship
    77  * 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)`
    279
    2810## Visitors ##
     
    124106  * allows `newObject` as just default settings
    125107
    126 `NamedTypeDecl`
    127 * `parameters` => `params`
    128 
    129108`TypeDecl`
    130109* moved `TypeDecl::Kind` to `ast::TypeVar::Kind`
    131 
    132 `AggregateDecl`
    133 * `parameters` => `params`
    134110
    135111`EnumDecl`
     
    139115* Merged `inferParams`/`resnSlots` into union, as suggested by comment in old version
    140116  * 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 `||`
    167117
    168118`Init`
     
    198148`Type`
    199149* `CV::Qualifiers` moved to end of constructor parameter list, defaulted to `{}`
    200   * removed getter, setter in favour of public `qualifiers` field
    201150  * `ReferenceToType` puts a defaulted list of attributes after qualifiers
    202151* `forall` field split off into `ParameterizedType` subclass
     
    211160  * `getAggr()` => `aggr()`
    212161    * also now returns `const AggregateDecl *`
    213 * `genericSubstitution()` moved to own visitor in `AST/GenericSubstitution.hpp` **TODO** write
     162* `genericSubstitution()` moved to own visitor **TODO** write
    214163
    215164`BasicType`
     
    218167`ReferenceToType`
    219168* deleted `get_baseParameters()` from children
    220   * replace with `aggr() ? aggr()->params : nullptr`
    221 * `parameters` => `params`
     169  * replace with `aggr() ? aggr()->parameters : nullptr`
    222170* hoisted `lookup` implementation into parent, made non-virtual
    223171  * also changed to return vector rather than filling; change back if any great win for reuse
     
    230178
    231179`FunctionType`
    232 * `returnVals` => `returns`
    233 * `parameters` => `params`
    234180* `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;`
    235181
  • src/ResolvExpr/Unify.cc

    r204358b r10248ae0  
    2121#include <string>                 // for string, operator==, operator!=, bas...
    2222#include <utility>                // for pair, move
    23 #include <vector>
    24 
    25 #include "AST/Node.hpp"
    26 #include "AST/Type.hpp"
     23
    2724#include "Common/PassVisitor.h"   // for PassVisitor
    2825#include "FindOpenVars.h"         // for findOpenVars
     
    633630        }
    634631
     632        // xxx - compute once and store in the FunctionType?
    635633        Type * extractResultType( FunctionType * function ) {
    636634                if ( function->get_returnVals().size() == 0 ) {
     
    646644                }
    647645        }
    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         }
    660646} // namespace ResolvExpr
    661647
  • src/ResolvExpr/typeops.h

    r204358b r10248ae0  
    1818#include <vector>
    1919
    20 #include "AST/Node.hpp"
    21 #include "AST/Type.hpp"
    2220#include "SynTree/SynTree.h"
    2321#include "SynTree/Type.h"
     
    10199        /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
    102100        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 );
    105101
    106102        // in CommonType.cc
Note: See TracChangeset for help on using the changeset viewer.