Changeset 204358b


Ignore:
Timestamp:
May 16, 2019, 2:57:41 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • src/AST/CVQualifiers.hpp

    r10248ae0 r204358b  
    5959        // ordering is a subtype relationship over qualifiers, e.g. `int` => `const int` is free
    6060
    61         bool operator== ( Qualifiers a, Qualifiers b ) {
     61        inline bool operator== ( Qualifiers a, Qualifiers b ) {
    6262                return (a.val & EquivQualifiers) == (b.val & EquivQualifiers);
    6363        }
    64         bool operator!= ( Qualifiers a, Qualifiers b ) {
     64        inline bool operator!= ( Qualifiers a, Qualifiers b ) {
    6565                return !(a == b);
    6666        }
    67         bool operator<= ( Qualifiers a, Qualifiers b ) {
     67        inline 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         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; }
    7676
    7777}
  • src/AST/Convert.cpp

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

    r10248ae0 r204358b  
    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
    3235namespace ast {
    33 
    34 class Attribute;
    35 class Expr;
    36 class Init;
    37 class TypeDecl;
    3836
    3937/// Base declaration class
     
    6058private:
    6159        Decl * clone() const override = 0;
     60        MUTATE_FRIEND
    6261};
    6362
     
    9291private:
    9392        DeclWithType * clone() const override = 0;
     93        MUTATE_FRIEND
    9494};
    9595
     
    113113private:
    114114        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
    119116};
    120117
     
    140137private:
    141138        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
    146140};
    147141
     
    150144public:
    151145        ptr<Type> base;
    152         std::vector<ptr<TypeDecl>> parameters;
     146        std::vector<ptr<TypeDecl>> params;
    153147        std::vector<ptr<DeclWithType>> assertions;
    154148
    155149        NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
    156150                Type* b, Linkage::Spec spec = Linkage::Cforall )
    157         : Decl( loc, name, storage, spec ), base( b ), parameters(), assertions() {}
     151        : Decl( loc, name, storage, spec ), base( b ), params(), assertions() {}
    158152
    159153        /// Produces a name for the kind of alias
     
    162156private:
    163157        NamedTypeDecl* clone() const override = 0;
     158        MUTATE_FRIEND
    164159};
    165160
     
    203198private:
    204199        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
    209201};
    210202
     
    221213private:
    222214        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
    227216};
    228217
     
    231220public:
    232221        std::vector<ptr<Decl>> members;
    233         std::vector<ptr<TypeDecl>> parameters;
     222        std::vector<ptr<TypeDecl>> params;
    234223        std::vector<ptr<Attribute>> attributes;
    235224        bool body = false;
     
    238227        AggregateDecl( const CodeLocation& loc, const std::string& name,
    239228                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    240         : Decl( loc, name, Storage::Classes{}, linkage ), members(), parameters(),
     229        : Decl( loc, name, Storage::Classes{}, linkage ), members(), params(),
    241230          attributes( std::move(attrs) ) {}
    242231
    243232        AggregateDecl* set_body( bool b ) { body = b; return this; }
     233
     234private:
     235        AggregateDecl * clone() const override = 0;
     236        MUTATE_FRIEND
    244237
    245238protected:
     
    265258private:
    266259        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
    271261
    272262        std::string typeString() const override { return "struct"; }
     
    283273private:
    284274        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
    289276
    290277        std::string typeString() const override { return "union"; }
     
    304291private:
    305292        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
    310294
    311295        std::string typeString() const override { return "enum"; }
     
    325309private:
    326310        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
    331312
    332313        std::string typeString() const override { return "trait"; }
     
    343324private:
    344325        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
    349327};
    350328
     
    360338private:
    361339        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
    366341};
    367342
     
    402377}
    403378
     379#undef MUTATE_FRIEND
     380
    404381// Local Variables: //
    405382// tab-width: 4 //
  • src/AST/Expr.hpp

    r10248ae0 r204358b  
    1818#include <cassert>
    1919#include <map>
     20#include <string>
    2021#include <utility>        // for move
    2122#include <vector>
    2223
    2324#include "Fwd.hpp"        // for UniqueId
     25#include "Label.hpp"
    2426#include "ParseNode.hpp"
    2527#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);
    2631
    2732namespace ast {
     
    117122        bool extension = false;
    118123
    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() {}
    120126
    121127        Expr * set_extension( bool ex ) { extension = ex; return this; }
     
    124130private:
    125131        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`
     137class ApplicationExpr final : public Expr {
     138public:
     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 ); }
     145private:
     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.
     151class UntypedExpr final : public Expr {
     152public:
     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 ); }
     165private:
     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.
     172class NameExpr final : public Expr {
     173public:
     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 ); }
     179private:
     180        NameExpr * clone() const override { return new NameExpr{ *this }; }
     181        MUTATE_FRIEND
     182};
     183
     184/// Address-of expression `&e`
     185class AddressExpr final : public Expr {
     186public:
     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 ); }
     192private:
     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
     199class LabelAddressExpr final : public Expr {
     200public:
     201        Label arg;
     202
     203        LabelAddressExpr( const CodeLocation & loc, Label && a );
     204
     205        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
     206private:
     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
     212enum GeneratedFlag { ExplicitCast, GeneratedCast };
     213
     214/// A type cast, e.g. `(int)e`
     215class CastExpr final : public Expr {
     216public:
     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 ); }
     226private:
     227        CastExpr * clone() const override { return new CastExpr{ *this }; }
     228        MUTATE_FRIEND
     229};
     230
     231/// A cast to "keyword types", e.g. `(thread &)t`
     232class KeywordCastExpr final : public Expr {
     233public:
     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 ); }
     244private:
     245        KeywordCastExpr * clone() const override { return new KeywordCastExpr{ *this }; }
     246        MUTATE_FRIEND
     247};
     248
     249/// A virtual dynamic cast, e.g. `(virtual exception)e`
     250class VirtualCastExpr final : public Expr {
     251public:
     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 ); }
     258private:
     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`
     264class UntypedMemberExpr final : public Expr {
     265public:
     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 ); }
     273private:
     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`
     279class MemberExpr final : public Expr {
     280public:
     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 ); }
     287private:
     288        MemberExpr * clone() const override { return new MemberExpr{ *this }; }
     289        MUTATE_FRIEND
     290};
     291
     292/// A reference to a named variable.
     293class VariableExpr final : public Expr {
     294public:
     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 ); }
     303private:
     304        VariableExpr * clone() const override { return new VariableExpr{ *this }; }
     305        MUTATE_FRIEND
     306};
     307
     308/// A compile-time constant
     309class 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;
     317public:
     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 ); }
     347private:
     348        ConstantExpr * clone() const override { return new ConstantExpr{ *this }; }
     349        MUTATE_FRIEND
     350};
     351
     352/// sizeof expression, e.g. `sizeof(int)`, `sizeof 3+4`
     353class SizeofExpr final : public Expr {
     354public:
     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 ); }
     363private:
     364        SizeofExpr * clone() const override { return new SizeofExpr{ *this }; }
     365        MUTATE_FRIEND
     366};
     367
     368/// alignof expression, e.g. `alignof(int)`, `alignof 3+4`
     369class AlignofExpr final : public Expr {
     370public:
     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 ); }
     379private:
     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)`
     385class UntypedOffsetofExpr final : public Expr {
     386public:
     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 ); }
     394private:
     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)`
     400class OffsetofExpr final : public Expr {
     401public:
     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 ); }
     408private:
     409        OffsetofExpr * clone() const override { return new OffsetofExpr{ *this }; }
     410        MUTATE_FRIEND
     411};
     412
     413/// a pack of field-offsets for a generic type
     414class OffsetPackExpr final : public Expr {
     415public:
     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 ); }
     421private:
     422        OffsetPackExpr * clone() const override { return new OffsetPackExpr{ *this }; }
     423        MUTATE_FRIEND
     424};
     425
     426/// Variants of short-circuiting logical expression
     427enum LogicalFlag { OrExpr, AndExpr };
     428
     429/// Short-circuiting boolean expression (`&&` or `||`)
     430class LogicalExpr final : public Expr {
     431public:
     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 ); }
     439private:
     440        LogicalExpr * clone() const override { return new LogicalExpr{ *this }; }
     441        MUTATE_FRIEND
     442};
     443
     444/// Three-argument conditional e.g. `p ? a : b`
     445class ConditionalExpr final : public Expr {
     446public:
     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 ); }
     455private:
     456        ConditionalExpr * clone() const override { return new ConditionalExpr{ *this }; }
     457        MUTATE_FRIEND
     458};
     459
     460/// Comma expression e.g. `( a , b )`
     461class CommaExpr final : public Expr {
     462public:
     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 ); }
     470private:
     471        CommaExpr * clone() const override { return new CommaExpr{ *this }; }
     472        MUTATE_FRIEND
    126473};
    127474
     
    136483private:
    137484        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
     490class AsmExpr final : public Expr {
     491public:
     492        ptr<Expr> inout;
     493        ptr<Expr> constraint;
     494};
    140495
    141496//=================================================================================================
     
    146501inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); }
    147502inline 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); }
     503inline void increment( const class ApplicationExpr * node, Node::ref_type ref ) { node->increment(ref); }
     504inline void decrement( const class ApplicationExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     505inline void increment( const class UntypedExpr * node, Node::ref_type ref ) { node->increment(ref); }
     506inline void decrement( const class UntypedExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     507inline void increment( const class NameExpr * node, Node::ref_type ref ) { node->increment(ref); }
     508inline void decrement( const class NameExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     509inline void increment( const class AddressExpr * node, Node::ref_type ref ) { node->increment(ref); }
     510inline void decrement( const class AddressExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     511inline void increment( const class LabelAddressExpr * node, Node::ref_type ref ) { node->increment(ref); }
     512inline void decrement( const class LabelAddressExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     513inline void increment( const class CastExpr * node, Node::ref_type ref ) { node->increment(ref); }
     514inline void decrement( const class CastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     515inline void increment( const class KeywordCastExpr * node, Node::ref_type ref ) { node->increment(ref); }
     516inline void decrement( const class KeywordCastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     517inline void increment( const class VirtualCastExpr * node, Node::ref_type ref ) { node->increment(ref); }
     518inline void decrement( const class VirtualCastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     519inline void increment( const class MemberExpr * node, Node::ref_type ref ) { node->increment(ref); }
     520inline void decrement( const class MemberExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     521inline void increment( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->increment(ref); }
     522inline void decrement( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     523inline void increment( const class VariableExpr * node, Node::ref_type ref ) { node->increment(ref); }
     524inline void decrement( const class VariableExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     525inline void increment( const class ConstantExpr * node, Node::ref_type ref ) { node->increment(ref); }
     526inline void decrement( const class ConstantExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     527inline void increment( const class SizeofExpr * node, Node::ref_type ref ) { node->increment(ref); }
     528inline void decrement( const class SizeofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     529inline void increment( const class AlignofExpr * node, Node::ref_type ref ) { node->increment(ref); }
     530inline void decrement( const class AlignofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     531inline void increment( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); }
     532inline void decrement( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     533inline void increment( const class OffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); }
     534inline void decrement( const class OffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     535inline void increment( const class OffsetPackExpr * node, Node::ref_type ref ) { node->increment(ref); }
     536inline void decrement( const class OffsetPackExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     537inline void increment( const class LogicalExpr * node, Node::ref_type ref ) { node->increment(ref); }
     538inline void decrement( const class LogicalExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     539inline void increment( const class ConditionalExpr * node, Node::ref_type ref ) { node->increment(ref); }
     540inline void decrement( const class ConditionalExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     541inline void increment( const class CommaExpr * node, Node::ref_type ref ) { node->increment(ref); }
     542inline void decrement( const class CommaExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     543inline void increment( const class TypeExpr * node, Node::ref_type ref ) { node->increment(ref); }
     544inline void decrement( const class TypeExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     545inline void increment( const class AsmExpr * node, Node::ref_type ref ) { node->increment(ref); }
     546inline void decrement( const class AsmExpr * node, Node::ref_type ref ) { node->decrement(ref); }
    194547// inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); }
    195548// inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     
    226579}
    227580
     581#undef MUTATE_FRIEND
     582
    228583// Local Variables: //
    229584// tab-width: 4 //
  • src/AST/Fwd.hpp

    r10248ae0 r204358b  
    7777class OffsetofExpr;
    7878class OffsetPackExpr;
    79 class AttrExpr;
    8079class LogicalExpr;
    8180class ConditionalExpr;
     
    252251inline void increment( const class OffsetPackExpr *, Node::ref_type );
    253252inline 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 );
    256253inline void increment( const class LogicalExpr *, Node::ref_type );
    257254inline void decrement( const class LogicalExpr *, Node::ref_type );
  • src/AST/Init.hpp

    r10248ae0 r204358b  
    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
    2528namespace ast {
    2629
     
    4043private:
    4144        Designation* clone() const override { return new Designation{ *this }; }
     45        MUTATE_FRIEND
    4246};
    4347
     
    5559private:
    5660        const Init * clone() const override = 0;
     61        MUTATE_FRIEND
    5762};
    5863
     
    6974private:
    7075        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
    7577};
    7678
     
    9799private:
    98100        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
    103102};
    104103
     
    120119private:
    121120        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
    126122};
    127123
     
    142138}
    143139
     140#undef MUTATE_FRIEND
     141
    144142// Local Variables: //
    145143// tab-width: 4 //
  • src/AST/Node.hpp

    r10248ae0 r204358b  
    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
    139140        template<typename o_node_t>
    140141        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        }
    141154
    142155        using ptr = const node_t *;
  • src/AST/Stmt.hpp

    r10248ae0 r204358b  
    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
    2831namespace ast {
    2932
     
    3538        std::vector<Label> labels;
    3639
    37         Stmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
     40        Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
    3841        : ParseNode(loc), labels(std::move(labels)) {}
    3942
    4043        Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {}
    4144
    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;
     46private:
     47        Stmt * clone() const override = 0;
     48        MUTATE_FRIEND
    4549};
    4650
     
    5054        std::list<ptr<Stmt>> kids;
    5155
    52         CompoundStmt(const CodeLocation& loc, std::list<ptr<Stmt>>&& ks = {} )
     56        CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {} )
    5357        : Stmt(loc), kids(std::move(ks)) {}
    5458
     
    5660        CompoundStmt( CompoundStmt&& o ) = default;
    5761
    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 ); }
     66private:
     67        CompoundStmt * clone() const override { return new CompoundStmt{ *this }; }
     68        MUTATE_FRIEND
    6869};
    6970
     
    7172class NullStmt final : public Stmt {
    7273public:
    73         NullStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
     74        NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
    7475        : Stmt(loc, std::move(labels)) {}
    7576
    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 ); }
     78private:
     79        NullStmt * clone() const override { return new NullStmt{ *this }; }
     80        MUTATE_FRIEND
    8381};
    8482
     
    9088        ExprStmt( const CodeLocation & loc, const Expr * e ) : Stmt(loc), expr(e) {}
    9189
    92         const Stmt * accept( Visitor& v ) const override { return v.visit( this ); }
     90        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
    9391private:
    9492        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
    9994};
    10095
     
    107102        std::vector<Label> gotoLabels;
    108103
    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 = {})
    113108        : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),
    114109          output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),
    115110          gotoLabels(std::move(gotoLabels)) {}
    116111
    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 ); }
     113private:
     114        AsmStmt * clone() const override { return new AsmStmt{ *this }; }
     115        MUTATE_FRIEND
    124116};
    125117
     
    128120        std::string directive;
    129121
    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 = {} )
    132124        : Stmt(loc, std::move(labels)), directive(directive) {}
    133125
    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 ); }
     127private:
     128        DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; }
     129        MUTATE_FRIEND
    141130};
    142131
     
    148137        std::vector<ptr<Stmt>> inits;
    149138
    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 = {} )
    153142        : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),
    154143          inits(std::move(inits)) {}
    155144
    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 ); }
     146private:
     147        IfStmt * clone() const override { return new IfStmt{ *this }; }
     148        MUTATE_FRIEND
    163149};
    164150
     
    168154        std::vector<ptr<Stmt>> stmts;
    169155
    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 = {} )
    172158        : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}
    173159
    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 ); }
     161private:
     162        SwitchStmt * clone() const override { return new SwitchStmt{ *this }; }
     163        MUTATE_FRIEND
    181164};
    182165
     
    186169        std::vector<ptr<Stmt>> stmts;
    187170
    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)) {}
     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)) {}
    191174
    192175        bool isDefault() { return !cond; }
    193176
    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 ); }
     178private:
     179        CaseStmt * clone() const override { return new CaseStmt{ *this }; }
     180        MUTATE_FRIEND
    201181};
    202182
     
    208188        bool isDoWhile;
    209189
    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 = {} )
    212192        : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)),
    213193          isDoWhile(isDoWhile) {}
    214194
    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 ); }
     196private:
     197        WhileStmt * clone() const override { return new WhileStmt{ *this }; }
     198        MUTATE_FRIEND
    222199};
    223200
     
    229206        ptr<Stmt> body;
    230207
    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 = {} )
    233210        : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
    234211          body(body) {}
    235212
    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 ); }
     214private:
     215        ForStmt * clone() const override { return new ForStmt{ *this }; }
     216        MUTATE_FRIEND
    243217};
    244218
     
    253227        Kind kind;
    254228
    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 = {} )
    259233        : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc),
    260234          computedTarget(computedTarget), kind(Goto) {}
     
    262236        const char * kindName() { return kindNames[kind]; }
    263237
    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 ); }
     239private:
     240        BranchStmt * clone() const override { return new BranchStmt{ *this }; }
     241        MUTATE_FRIEND
    271242
    272243        static const char * kindNames[kindEnd];
     
    277248        ptr<Expr> expr;
    278249
    279         ReturnStmt( const CodeLocation& loc, const Expr* expr, std::vector<Label>&& labels = {} )
     250        ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} )
    280251        : Stmt(loc, std::move(labels)), expr(expr) {}
    281252
    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 ); }
     254private:
     255        ReturnStmt * clone() const override { return new ReturnStmt{ *this }; }
     256        MUTATE_FRIEND
    289257};
    290258
     
    297265        Kind kind;
    298266
    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 = {} )
    301269        : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {}
    302270
    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 ); }
     272private:
     273        ThrowStmt * clone() const override { return new ThrowStmt{ *this }; }
     274        MUTATE_FRIEND
    310275};
    311276
     
    316281        ptr<FinallyStmt> finally;
    317282
    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 = {} )
    321286        : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {}
    322287
    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 ); }
     289private:
     290        TryStmt * clone() const override { return new TryStmt{ *this }; }
     291        MUTATE_FRIEND
    330292};
    331293
     
    339301        Kind kind;
    340302
    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 = {} )
    343305        : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {}
    344306
    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 ); }
     308private:
     309        CatchStmt * clone() const override { return new CatchStmt{ *this }; }
     310        MUTATE_FRIEND
    352311};
    353312
     
    356315        ptr<CompoundStmt> body;
    357316
    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 = {} )
    360319        : Stmt(loc, std::move(labels)), body(body) {}
    361320
    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 ); }
     322private:
     323        FinallyStmt * clone() const override { return new FinallyStmt{ *this }; }
     324        MUTATE_FRIEND
    369325};
    370326
     
    397353        OrElse orElse;
    398354
    399         WaitForStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
     355        WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )
    400356        : Stmt(loc, std::move(labels)) {}
    401357
    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 ); }
     359private:
     360        WaitForStmt * clone() const override { return new WaitForStmt{ *this }; }
     361        MUTATE_FRIEND
    409362};
    410363
     
    414367        ptr<Stmt> stmt;
    415368
    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 = {} )
    418371        : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}
    419372
    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 ); }
     374private:
     375        WithStmt * clone() const override { return new WithStmt{ *this }; }
     376        MUTATE_FRIEND
    427377};
    428378
     
    431381        ptr<Decl> decl;
    432382
    433         DeclStmt( const CodeLocation& loc, const Decl* decl, std::vector<Label>&& labels = {} )
     383        DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} )
    434384        : Stmt(loc, std::move(labels)), decl(decl) {}
    435385
    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 ); }
     387private:
     388        DeclStmt * clone() const override { return new DeclStmt{ *this }; }
     389        MUTATE_FRIEND
    443390};
    444391
     
    447394        readonly<Stmt> callStmt;
    448395
    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 = {} )
    451398        : Stmt(loc, std::move(labels)), callStmt(callStmt) {}
    452399
    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 ); }
     401private:
     402        ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; }
     403        MUTATE_FRIEND
    460404};
    461405
     
    510454}
    511455
     456#undef MUTATE_FRIEND
     457
    512458// Local Variables: //
    513459// tab-width: 4 //
  • src/AST/Type.hpp

    r10248ae0 r204358b  
    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
    3134namespace ast {
    3235
    3336class 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; }
     37public:
     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; }
    5254
    5355        /// How many elemental types are represented by this type
     
    7173private:
    7274        virtual Type * clone() const override = 0;
     75        MUTATE_FRIEND
    7376};
    7477
     
    8588private:
    8689        VoidType * clone() const override { return new VoidType{ *this }; }
     90        MUTATE_FRIEND
    8791};
    8892
     
    147151private:
    148152        BasicType * clone() const override { return new BasicType{ *this }; }
     153        MUTATE_FRIEND
    149154};
    150155
     
    177182private:
    178183        PointerType * clone() const override { return new PointerType{ *this }; }
     184        MUTATE_FRIEND
    179185};
    180186
     
    198204private:
    199205        ArrayType * clone() const override { return new ArrayType{ *this }; }
     206        MUTATE_FRIEND
    200207};
    201208
     
    217224private:
    218225        ReferenceType * clone() const override { return new ReferenceType{ *this }; }
     226        MUTATE_FRIEND
    219227};
    220228
     
    231239private:
    232240        QualifiedType * clone() const override { return new QualifiedType{ *this }; }
     241        MUTATE_FRIEND
    233242};
    234243
     
    246255private:
    247256        virtual ParameterizedType * clone() const override = 0;
     257        MUTATE_FRIEND
    248258};
    249259
     
    254264class FunctionType final : public ParameterizedType {
    255265public:
    256         std::vector<ptr<DeclWithType>> returnVals;
    257         std::vector<ptr<DeclWithType>> parameters;
     266        std::vector<ptr<DeclWithType>> returns;
     267        std::vector<ptr<DeclWithType>> params;
    258268
    259269        /// Does the function accept a variable number of arguments following the arguments specified
     
    265275
    266276        FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} )
    267         : ParameterizedType(q), returnVals(), parameters(), isVarArgs(va) {}
     277        : ParameterizedType(q), returns(), params(), isVarArgs(va) {}
    268278
    269279        /// true if either the parameters or return values contain a tttype
    270280        bool isTtype() const;
    271281        /// true if function parameters are unconstrained by prototype
    272         bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; }
     282        bool isUnprototyped() const { return isVarArgs && params.size() == 0; }
    273283
    274284        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    275285private:
    276286        FunctionType * clone() const override { return new FunctionType{ *this }; }
     287        MUTATE_FRIEND
    277288};
    278289
     
    280291class ReferenceToType : public ParameterizedType {
    281292public:
    282         std::vector<ptr<Expr>> parameters;
     293        std::vector<ptr<Expr>> params;
    283294        std::vector<ptr<Attribute>> attributes;
    284295        std::string name;
     
    287298        ReferenceToType( const std::string& n, CV::Qualifiers q = {},
    288299                std::vector<ptr<Attribute>> && as = {} )
    289         : ParameterizedType(q), parameters(), attributes(std::move(as)), name(n) {}
     300        : ParameterizedType(q), params(), attributes(std::move(as)), name(n) {}
    290301
    291302        /// Gets aggregate declaration this type refers to
     
    296307private:
    297308        virtual ReferenceToType * clone() const override = 0;
     309        MUTATE_FRIEND
    298310
    299311protected:
     
    320332private:
    321333        StructInstType * clone() const override { return new StructInstType{ *this }; }
     334        MUTATE_FRIEND
    322335
    323336        std::string typeString() const override { return "struct"; }
     
    342355private:
    343356        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
     357        MUTATE_FRIEND
    344358
    345359        std::string typeString() const override { return "union"; }
     
    364378private:
    365379        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
     380        MUTATE_FRIEND
    366381
    367382        std::string typeString() const override { return "enum"; }
     
    387402private:
    388403        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
     404        MUTATE_FRIEND
    389405
    390406        std::string typeString() const override { return "trait"; }
     
    415431private:
    416432        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
     433        MUTATE_FRIEND
    417434
    418435        std::string typeString() const override { return "type"; }
     
    443460private:
    444461        TupleType * clone() const override { return new TupleType{ *this }; }
     462        MUTATE_FRIEND
    445463};
    446464
     
    457475private:
    458476        TypeofType * clone() const override { return new TypeofType{ *this }; }
     477        MUTATE_FRIEND
    459478};
    460479
     
    467486private:
    468487        VarArgsType * clone() const override { return new VarArgsType{ *this }; }
     488        MUTATE_FRIEND
    469489};
    470490
     
    476496        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    477497private:
    478         ZeroType * clone() const override { return new ZeroType{ *this }; }     
     498        ZeroType * clone() const override { return new ZeroType{ *this }; }
     499        MUTATE_FRIEND
    479500};
    480501
     
    487508private:
    488509        OneType * clone() const override { return new OneType{ *this }; }
     510        MUTATE_FRIEND
    489511};
    490512
     
    497519private:
    498520        GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; }
     521        MUTATE_FRIEND
    499522};
    500523
     
    547570}
    548571
     572#undef MUTATE_FRIEND
     573
    549574// Local Variables: //
    550575// tab-width: 4 //
  • src/AST/Visitor.hpp

    r10248ae0 r204358b  
    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;
    7271    virtual const ast::Expr *             visit( const ast::LogicalExpr          * ) = 0;
    7372    virtual const ast::Expr *             visit( const ast::ConditionalExpr      * ) = 0;
  • src/AST/porting.md

    r10248ae0 r204358b  
    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)`
     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
    927
    1028## Visitors ##
     
    106124  * allows `newObject` as just default settings
    107125
     126`NamedTypeDecl`
     127* `parameters` => `params`
     128
    108129`TypeDecl`
    109130* moved `TypeDecl::Kind` to `ast::TypeVar::Kind`
     131
     132`AggregateDecl`
     133* `parameters` => `params`
    110134
    111135`EnumDecl`
     
    115139* Merged `inferParams`/`resnSlots` into union, as suggested by comment in old version
    116140  * 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 `||`
    117167
    118168`Init`
     
    148198`Type`
    149199* `CV::Qualifiers` moved to end of constructor parameter list, defaulted to `{}`
     200  * removed getter, setter in favour of public `qualifiers` field
    150201  * `ReferenceToType` puts a defaulted list of attributes after qualifiers
    151202* `forall` field split off into `ParameterizedType` subclass
     
    160211  * `getAggr()` => `aggr()`
    161212    * also now returns `const AggregateDecl *`
    162 * `genericSubstitution()` moved to own visitor **TODO** write
     213* `genericSubstitution()` moved to own visitor in `AST/GenericSubstitution.hpp` **TODO** write
    163214
    164215`BasicType`
     
    167218`ReferenceToType`
    168219* deleted `get_baseParameters()` from children
    169   * replace with `aggr() ? aggr()->parameters : nullptr`
     220  * replace with `aggr() ? aggr()->params : nullptr`
     221* `parameters` => `params`
    170222* hoisted `lookup` implementation into parent, made non-virtual
    171223  * also changed to return vector rather than filling; change back if any great win for reuse
     
    178230
    179231`FunctionType`
     232* `returnVals` => `returns`
     233* `parameters` => `params`
    180234* `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;`
    181235
  • src/ResolvExpr/Unify.cc

    r10248ae0 r204358b  
    2121#include <string>                 // for string, operator==, operator!=, bas...
    2222#include <utility>                // for pair, move
    23 
     23#include <vector>
     24
     25#include "AST/Node.hpp"
     26#include "AST/Type.hpp"
    2427#include "Common/PassVisitor.h"   // for PassVisitor
    2528#include "FindOpenVars.h"         // for findOpenVars
     
    630633        }
    631634
    632         // xxx - compute once and store in the FunctionType?
    633635        Type * extractResultType( FunctionType * function ) {
    634636                if ( function->get_returnVals().size() == 0 ) {
     
    644646                }
    645647        }
     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        }
    646660} // namespace ResolvExpr
    647661
  • src/ResolvExpr/typeops.h

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