Changeset 69bafd2


Ignore:
Timestamp:
May 15, 2019, 3:57:26 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
3648d98
Parents:
9e1d485 (diff), be567e9 (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

Files:
4 added
1 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/vtable.md

    r9e1d485 r69bafd2  
    11Proposal For Use of Virtual Tables
    22==================================
    3 
    4 This is an adaptation of the earlier virtual proposal, updating it with new
    5 ideas, re-framing it and laying out more design decisions. It should
    6 eventually replace the earlier proposal, but not all features and syntax have
    7 been converted to the new design.
    83
    94The basic concept of a virtual table (vtable) is the same here as in most
     
    9388        }
    9489    }
     90
     91With a more complete widget trait you could, for example, construct a UI tool
     92kit that can declare containers that hold widgets without knowing about the
     93widget types. Making it reasonable to extend the tool kit.
    9594
    9695The trait types can also be used in the types of assertions on traits as well.
     
    244243We would also like to implement hierarchical relations between types.
    245244
    246     AstNode
    247     |-ParseNode
    248     | |-Declaration
    249     | | |-DeclarationWithType
    250     | | |-StructureDeclaration
    251     | |-Statement
    252     | | |-CompoundStatement
    253     | |-Expression
    254     |-Type
     245    ast_node
     246    |-expression_node
     247    | |-operator_expression
     248    |
     249    |-statement_node
     250    | |-goto_statement
     251    |
     252    |-declaration_node
     253      |-using_declaration
     254      |-variable_declaration
    255255
    256256Virtual tables by themselves are not quite enough to implement this system.
     
    315315    }
    316316
     317This system does not support multiple inheritance. The system could be
     318extended to support it or a limited form (ex. you may have multiple parents
     319but they may not have a common ancestor). However this proposal focuses just
     320on using hierachy as organization. Other uses for reusable/genaric code or
     321shared interfaces is left for other features of the language.
     322
    317323### Extension: Structural Inheritance
    318324An extension would be allow structures to be used as internal nodes on the
     
    354360solution but only works if we have exactly 1 vtable for each type. The second
    355361is to put a pointer to the type id in each vtable. This has more overhead but
    356 allows multiple vtables.
     362allows multiple vtables per type.
    357363
    358364    struct <trait>_vtable {
     
    367373        // Trait dependent list of vtable members.
    368374    };
     375
     376One important restriction is that only one instance of each typeid in memory.
     377There is a ".gnu.linkonce" feature in the linker that might solve the issue.
    369378
    370379### Virtual Casts
     
    423432    io_error * error = (virtual)exc;
    424433
     434#### Sample Implementation
     435This cast implementation assumes a type id layout similar to the one given
     436above. Also this code is definitely in the underlying C. Functions that give
     437this functionality could exist in the standard library but these are meant to
     438be produced by code translation of the virtual cast.
     439
     440    bool is_in_subtree(typeid const * root, typeid const * id) {
     441        if (root == id) {
     442            return true
     443        } else if (NULL == id->parent) {
     444            return false;
     445        } else {
     446            return is_in_subtree(root, id->parent);
     447        }
     448    }
     449
     450    void * virtual_cast(typeid const * target, void * value) {
     451        return is_in_subtree(target, *(typeid const **)value) ? value : NULL;
     452    }
     453
     454The virtual cast function might have to be wrapped with some casts to make it
     455compile without warning.
     456
     457For the implicate target type we may be able to lean on the type resolution
     458system that already exists. If the casting to ancestor type is built into
     459the resolution then the impicate target could be decided by picking an
     460overload, generated for each hierarchial type (here io_error and its root
     461type exception).
     462
     463    io_error * virtual_cast(exception * value) {
     464        return virtual_cast(io_error_typeid, value);
     465    }
     466
    425467### Extension: Inline vtables
    426468Since the structures here are usually made to be turned into trait objects
     
    436478to allow access to all three options.
    437479
     480The pointer to virtual table field on structures might implicately added (the
     481types have to declare they are a child here) or created with a declaration,
     482possibly like the one used to create the assertion.
     483
    438484### Virtual Tables as Types
    439485Here we consider encoding plus the implementation of functions on it to be a
     
    442488and implementation.
    443489
     490### Question: Wrapping Structures
     491One issue is what to do with concrete types at the base of the type tree.
     492When we are working with the concrete type generally it would like them to be
     493regular structures with direct calls. On the other hand for interactions with
     494other types in the hierarchy it is more convenent for the type already to be
     495cast.
     496
     497Which of these two should we use? Should we support both and if so how do we
     498choose which one is being used at any given time.
     499
     500On a related note I have been using pointers two trait types here, as that
     501is how many existing languages handle it. However the generic objects might
     502be only one or two pointers wide passing the objects as a whole would not
     503be very expensive and all operations on the generic objects probably have
     504to be defined anyways.
     505
    444506Resolution Scope
    445507----------------
     
    534596Stack allocated functions interact badly with this because they are not
    535597static. There are several ways to try to resolve this, however without a
    536 general solution most can only buy time.
     598general solution most can keep vtables from making the existing thunk problem
     599worse, they don't do anything to solve it.
    537600
    538601Filling in some fields of a static vtable could cause issues on a recursive
     
    549612shortest lifetime of a function assigned to it. However this still limits the
    550613lifetime "implicitly" and returns to the original problem with thunks.
     614
     615Odds And Ends
     616-------------
     617
     618In addition to the main design there are a few extras that should be
     619considered. They are not part of the core design but make the new uses fully
     620featured.
     621
     622### Extension: Parent-Child Assertion
     623For hierarchy types in regular traits, generic functions or generic structures
     624we may want to be able to check parent-child relationships between two types
     625given. For this we might have to add another primitive assertion. It would
     626have the following form if declared in code:
     627
     628    trait is_parent_child(dtype Parent, dtype Child) { <built-in magic> }
     629
     630This assertion is satified if Parent is an ancestor of Child in a hierarchy.
     631In other words Child can be statically cast to Parent. The cast from Parent
     632to child would be dynamically checked as usual.
     633
     634However in this form there are two concerns. The first that Parent will
     635usually be consistent for a given use, it will not be a variable. Second is
     636that we may also need the assertion functions. To do any casting/conversions
     637anyways.
     638TODO: Talk about when we wrap a concrete type and how that leads to "may".
     639
     640To this end it may be better that the parent trait combines the usual
     641assertions plus this new primitive assertion. There may or may not be use
     642cases for accessing just one half and providing easy access to them may be
     643required depending on how that turns out.
     644
     645    trait Parent(dtype T | interface(T)) virtual(<grand-parent?>) { }
     646
     647### Extension: sizeof Compatablity
     648Trait types are always sized, it may even be a fixed size like how pointers
     649have the same size regardless of what they point at. However their contents
     650may or may not be of a known size (if the `sized(...)` assertion is used).
     651
     652Currently there is no way to access this information. If it is needed a
     653special syntax would have to be added. Here a special case of `sizeof` is
     654used.
     655
     656    struct line aLine;
     657    trait drawable widget = aLine;
     658
     659    size_t x = sizeof(widget);
     660    size_t y = sizeof(trait drawable);
     661
     662As usual `y`, size of the type, is the size of the local storage used to put
     663the value into. The other case `x` checks the saved stored value in the
     664virtual table and returns that.
  • src/AST/Attribute.hpp

    r9e1d485 r69bafd2  
    1919#include <vector>
    2020
     21#include "Fwd.hpp"
    2122#include "Node.hpp"     // for ptr
    2223#include "Visitor.hpp"
     
    3132        std::vector<ptr<Expr>> parameters;
    3233
    33         Attribute( const std::string& name = "", std::vector<ptr<Expr>>&& params = {})
     34        Attribute( const std::string & name = "", std::vector<ptr<Expr>> && params = {})
    3435        : name( name ), parameters( params ) {}
     36        virtual ~Attribute() = default;
    3537
    3638        bool empty() const { return name.empty(); }
     
    4244        bool isValidOnFuncParam() const;
    4345
    44         Attribute* accept( Visitor& v ) override { return v.visit( this ); }
     46        const Attribute * accept( Visitor & v ) const override { return v.visit( this ); }
    4547private:
    46         Attribute* clone() const override { return new Attribute{ *this }; }
     48        Attribute * clone() const override { return new Attribute{ *this }; }
     49
     50        /// Must be copied in ALL derived classes
     51        template<typename node_t>
     52        friend auto mutate(const node_t * node);
    4753};
    4854
  • src/AST/Decl.hpp

    r9e1d485 r69bafd2  
    5757        static readonly<Decl> fromId( UniqueId id );
    5858
    59         virtual Decl* accept( Visitor& v ) override = 0;
    60 private:
    61         virtual Decl* clone() const override = 0;
     59        virtual const Decl * accept( Visitor & v ) const override = 0;
     60private:
     61        virtual Decl * clone() const override = 0;
    6262};
    6363
     
    8585
    8686        /// Get type of this declaration. May be generated by subclass
    87         virtual const Type* get_type() const = 0;
     87        virtual const Type * get_type() const = 0;
    8888        /// Set type of this declaration. May be verified by subclass
    8989        virtual void set_type(Type*) = 0;
    9090
    91         virtual DeclWithType* accept( Visitor& v ) override = 0;
    92 private:
    93         virtual DeclWithType* clone() const override = 0;
     91        virtual const DeclWithType * accept( Visitor & v ) const override = 0;
     92private:
     93        virtual DeclWithType * clone() const override = 0;
    9494};
    9595
     
    110110        void set_type( Type* ty ) override { type = ty; }
    111111
    112         DeclWithType* accept( Visitor& v ) override { return v.visit( this ); }
    113 private:
    114         ObjectDecl* clone() const override { return new ObjectDecl{ *this }; }
     112        virtual const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); }
     113private:
     114        virtual 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);
    115119};
    116120
     
    169173        bool isComplete() { return sized; }
    170174
    171         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    172 private:
    173         TypeDecl* clone() const override { return new TypeDecl{ *this }; }
     175        virtual const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     176private:
     177        virtual TypeDecl * clone() const override { return new TypeDecl{ *this }; }
    174178};
    175179
     
    183187        std::string typeString() const override { return "typedef"; }
    184188
    185         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    186 private:
    187         TypedefDecl* clone() const override { return new TypedefDecl{ *this }; }
     189        virtual const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     190private:
     191        virtual TypedefDecl * clone() const override { return new TypedefDecl{ *this }; }
    188192};
    189193
     
    223227        bool is_thread() { return kind == DeclarationNode::Thread; }
    224228
    225         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    226 private:
    227         StructDecl* clone() const override { return new StructDecl{ *this }; }
     229        virtual const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     230private:
     231        virtual StructDecl * clone() const override { return new StructDecl{ *this }; }
    228232
    229233        std::string typeString() const override { return "struct"; }
     
    237241        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
    238242
    239         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    240 private:
    241         UnionDecl* clone() const override { return new UnionDecl{ *this }; }
     243        virtual const Decl * accept( Visitor& v ) const override { return v.visit( this ); }
     244private:
     245        virtual UnionDecl * clone() const override { return new UnionDecl{ *this }; }
    242246
    243247        std::string typeString() const override { return "union"; }
     
    254258        bool valueOf( Decl* enumerator, long long& value ) const;
    255259
    256         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    257 private:
    258         EnumDecl* clone() const override { return new EnumDecl{ *this }; }
     260        virtual const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     261private:
     262        virtual EnumDecl * clone() const override { return new EnumDecl{ *this }; }
    259263
    260264        std::string typeString() const override { return "enum"; }
     
    271275        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
    272276
    273         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    274 private:
    275         TraitDecl* clone() const override { return new TraitDecl{ *this }; }
     277        virtual const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     278private:
     279        virtual TraitDecl * clone() const override { return new TraitDecl{ *this }; }
    276280
    277281        std::string typeString() const override { return "trait"; }
     
    290294inline void increment( const class ObjectDecl * node, Node::ref_type ref ) { node->increment(ref); }
    291295inline void decrement( const class ObjectDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    292 inline void increment( const class FunctionDecl * node, Node::ref_type ref ) { node->increment(ref); }
    293 inline void decrement( const class FunctionDecl * node, Node::ref_type ref ) { node->decrement(ref); }
     296// inline void increment( const class FunctionDecl * node, Node::ref_type ref ) { node->increment(ref); }
     297// inline void decrement( const class FunctionDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    294298inline void increment( const class AggregateDecl * node, Node::ref_type ref ) { node->increment(ref); }
    295299inline void decrement( const class AggregateDecl * node, Node::ref_type ref ) { node->decrement(ref); }
     
    306310inline void increment( const class TypeDecl * node, Node::ref_type ref ) { node->increment(ref); }
    307311inline void decrement( const class TypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    308 inline void increment( const class FtypeDecl * node, Node::ref_type ref ) { node->increment(ref); }
    309 inline void decrement( const class FtypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    310 inline void increment( const class DtypeDecl * node, Node::ref_type ref ) { node->increment(ref); }
    311 inline void decrement( const class DtypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }
     312// inline void increment( const class FtypeDecl * node, Node::ref_type ref ) { node->increment(ref); }
     313// inline void decrement( const class FtypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }
     314// inline void increment( const class DtypeDecl * node, Node::ref_type ref ) { node->increment(ref); }
     315// inline void decrement( const class DtypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    312316inline void increment( const class TypedefDecl * node, Node::ref_type ref ) { node->increment(ref); }
    313317inline void decrement( const class TypedefDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    314 inline void increment( const class AsmDecl * node, Node::ref_type ref ) { node->increment(ref); }
    315 inline void decrement( const class AsmDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    316 inline void increment( const class StaticAssertDecl * node, Node::ref_type ref ) { node->increment(ref); }
    317 inline void decrement( const class StaticAssertDecl * node, Node::ref_type ref ) { node->decrement(ref); }
     318// inline void increment( const class AsmDecl * node, Node::ref_type ref ) { node->increment(ref); }
     319// inline void decrement( const class AsmDecl * node, Node::ref_type ref ) { node->decrement(ref); }
     320// inline void increment( const class StaticAssertDecl * node, Node::ref_type ref ) { node->increment(ref); }
     321// inline void decrement( const class StaticAssertDecl * node, Node::ref_type ref ) { node->decrement(ref); }
    318322
    319323}
  • src/AST/Expr.hpp

    r9e1d485 r69bafd2  
    2727namespace ast {
    2828
    29 /// Contains the ID of a declaration and a type that is derived from that declaration, 
     29/// Contains the ID of a declaration and a type that is derived from that declaration,
    3030/// but subject to decay-to-pointer and type parameter renaming
    3131struct ParamEntry {
     
    7474                        case Empty:  return;
    7575                        case Slots:  new(&data.resnSlots) ResnSlots{ std::move(o.data.resnSlots) }; return;
    76                         case Params: 
     76                        case Params:
    7777                                new(&data.inferParams) InferredParams{ std::move(o.data.inferParams) }; return;
    7878                        }
     
    121121        Expr * set_extension( bool ex ) { extension = ex; return this; }
    122122
    123         virtual Expr * accept( Visitor & v ) override = 0;
     123        virtual const Expr * accept( Visitor & v ) const override = 0;
    124124private:
    125125        virtual Expr * clone() const override = 0;
     
    133133        TypeExpr( const CodeLocation & loc, const Type * t ) : Expr(loc), type(t) {}
    134134
    135         Expr * accept( Visitor & v ) override { return v.visit( this ); }
     135        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    136136private:
    137137        TypeExpr * clone() const override { return new TypeExpr{ *this }; }
    138138};
    139139
     140
     141//=================================================================================================
     142/// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency
     143/// remove only if there is a better solution
     144/// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with
     145/// forward declarations
     146inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); }
     147inline 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); }
     194// inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); }
     195// inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     196// inline void increment( const class ConstructorExpr * node, Node::ref_type ref ) { node->increment(ref); }
     197// inline void decrement( const class ConstructorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     198// inline void increment( const class CompoundLiteralExpr * node, Node::ref_type ref ) { node->increment(ref); }
     199// inline void decrement( const class CompoundLiteralExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     200// inline void increment( const class UntypedValofExpr * node, Node::ref_type ref ) { node->increment(ref); }
     201// inline void decrement( const class UntypedValofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     202// inline void increment( const class RangeExpr * node, Node::ref_type ref ) { node->increment(ref); }
     203// inline void decrement( const class RangeExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     204// inline void increment( const class UntypedTupleExpr * node, Node::ref_type ref ) { node->increment(ref); }
     205// inline void decrement( const class UntypedTupleExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     206// inline void increment( const class TupleExpr * node, Node::ref_type ref ) { node->increment(ref); }
     207// inline void decrement( const class TupleExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     208// inline void increment( const class TupleIndexExpr * node, Node::ref_type ref ) { node->increment(ref); }
     209// inline void decrement( const class TupleIndexExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     210// inline void increment( const class TupleAssignExpr * node, Node::ref_type ref ) { node->increment(ref); }
     211// inline void decrement( const class TupleAssignExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     212// inline void increment( const class StmtExpr * node, Node::ref_type ref ) { node->increment(ref); }
     213// inline void decrement( const class StmtExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     214// inline void increment( const class UniqueExpr * node, Node::ref_type ref ) { node->increment(ref); }
     215// inline void decrement( const class UniqueExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     216// inline void increment( const class UntypedInitExpr * node, Node::ref_type ref ) { node->increment(ref); }
     217// inline void decrement( const class UntypedInitExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     218// inline void increment( const class InitExpr * node, Node::ref_type ref ) { node->increment(ref); }
     219// inline void decrement( const class InitExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     220// inline void increment( const class DeletedExpr * node, Node::ref_type ref ) { node->increment(ref); }
     221// inline void decrement( const class DeletedExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     222// inline void increment( const class DefaultArgExpr * node, Node::ref_type ref ) { node->increment(ref); }
     223// inline void decrement( const class DefaultArgExpr * node, Node::ref_type ref ) { node->decrement(ref); }
     224// inline void increment( const class GenericExpr * node, Node::ref_type ref ) { node->increment(ref); }
     225// inline void decrement( const class GenericExpr * node, Node::ref_type ref ) { node->decrement(ref); }
    140226}
    141227
  • src/AST/Fwd.hpp

    r9e1d485 r69bafd2  
    136136
    137137class TypeSubstitution;
     138
     139std::string toString( const Node * );
    138140
    139141//=================================================================================================
     
    352354inline void increment( const class Constant *, Node::ref_type );
    353355inline void decrement( const class Constant *, Node::ref_type );
    354 inline void increment( const class Label *, Node::ref_type );
    355 inline void decrement( const class Label *, Node::ref_type );
    356356inline void increment( const class Attribute *, Node::ref_type );
    357357inline void decrement( const class Attribute *, Node::ref_type );
  • src/AST/Init.hpp

    r9e1d485 r69bafd2  
    3737        : ParseNode( loc ), designators( std::move(ds) ) {}
    3838
    39         Designation* accept( Visitor& v ) override { return v.visit( this ); }
     39        virtual const Designation* accept( Visitor& v ) const override { return v.visit( this ); }
    4040private:
    41         Designation* clone() const override { return new Designation{ *this }; }
     41        virtual Designation* clone() const override { return new Designation{ *this }; }
    4242};
    4343
     
    5252        Init( const CodeLocation& loc, ConstructFlag mc ) : ParseNode( loc ), maybeConstructed( mc ) {}
    5353
    54         virtual Init* accept( Visitor& v ) override = 0;
     54        virtual const Init * accept( Visitor& v ) const override = 0;
    5555private:
    56         virtual Init* clone() const override = 0;
     56        virtual const Init * clone() const override = 0;
    5757};
    5858
     
    6666        : Init( loc, mc ), value( val ) {}
    6767
    68         Init* accept( Visitor& v ) override { return v.visit( this ); }
     68        virtual const Init * accept( Visitor & v ) const override { return v.visit( this ); }
    6969private:
    70         SingleInit* clone() const override { return new SingleInit{ *this }; }
     70        virtual 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);
    7175};
    7276
     
    9094        const_iterator end() const { return initializers.end(); }
    9195
    92         Init* accept( Visitor& v ) override { return v.visit( this ); }
     96        virtual const Init * accept( Visitor & v ) const override { return v.visit( this ); }
    9397private:
    94         ListInit* clone() const override { return new ListInit{ *this }; }
     98        virtual 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);
    95103};
    96104
     
    109117        : Init( loc, DoConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
    110118
    111         Init* accept( Visitor& v ) override { return v.visit( this ); }
     119        virtual const Init * accept( Visitor & v ) const override { return v.visit( this ); }
    112120private:
    113         ConstructorInit* clone() const override { return new ConstructorInit{ *this }; }
     121        virtual 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);
    114126};
    115127
  • src/AST/Label.hpp

    r9e1d485 r69bafd2  
    3535
    3636        Label( CodeLocation loc, const std::string& name = "",
    37                 const std::vector<ptr<Attribute>>& attrs = std::vector<ptr<Attribute>>{} )
     37                std::vector<ptr<Attribute>> && attrs = std::vector<ptr<Attribute>>{} )
    3838        : location( loc ), name( name ), attributes( attrs ) {}
    3939
     
    4848inline std::ostream& operator<< ( std::ostream& out, const Label& l ) { return out << l.name; }
    4949
    50 
    51 //=================================================================================================
    52 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency
    53 /// remove only if there is a better solution
    54 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with
    55 /// forward declarations
    56 inline void increment( const class Label * node, Node::ref_type ref ) { node->increment( ref ); }
    57 inline void decrement( const class Label * node, Node::ref_type ref ) { node->decrement( ref ); }
    58 
    5950}
    6051
  • src/AST/Node.hpp

    r9e1d485 r69bafd2  
    3030        // change/share reference counts
    3131        Node() = default;
    32         Node(const Node&) : strong_ref(0), weak_ref(0) {}
    33         Node(Node&&) : strong_ref(0), weak_ref(0) {}
     32        Node(const Node&) : strong_count(0), weak_count(0) {}
     33        Node(Node&&) : strong_count(0), weak_count(0) {}
    3434        Node& operator= (const Node&) = delete;
    3535        Node& operator= (Node&&) = delete;
    3636        virtual ~Node() = default;
    3737
    38         virtual Node* accept( Visitor& v ) = 0;
     38        virtual const Node * accept( Visitor & v ) const = 0;
    3939
    4040        /// Types of node references
     
    4646        inline void increment(ref_type ref) const {
    4747                switch (ref) {
    48                         case ref_type::strong: strong_ref++; break;
    49                         case ref_type::weak  : weak_ref  ++; break;
     48                        case ref_type::strong: strong_count++; break;
     49                        case ref_type::weak  : weak_count  ++; break;
    5050                }
    5151        }
     
    5353        inline void decrement(ref_type ref) const {
    5454                switch (ref) {
    55                         case ref_type::strong: strong_ref--; break;
    56                         case ref_type::weak  : weak_ref  --; break;
     55                        case ref_type::strong: strong_count--; break;
     56                        case ref_type::weak  : weak_count  --; break;
    5757                }
    5858
    59                 if(!strong_ref && !weak_ref) {
     59                if(!strong_count && !weak_count) {
    6060                        delete this;
    6161                }
    6262        }
     63private:
     64        /// Make a copy of this node; should be overridden in subclass with more precise return type
     65        virtual const Node * clone() const = 0;
    6366
     67        /// Must be copied in ALL derived classes
    6468        template<typename node_t>
    6569        friend auto mutate(const node_t * node);
    6670
    67 private:
    68         /// Make a copy of this node; should be overridden in subclass with more precise return type
    69         virtual Node* clone() const = 0;
    70 
    71         mutable size_t strong_ref = 0;
    72         mutable size_t weak_ref = 0;
     71        mutable size_t strong_count = 0;
     72        mutable size_t weak_count = 0;
    7373};
    7474
     
    100100public:
    101101        ptr_base() : node(nullptr) {}
    102         ptr_base( const node_t * n ) : node(n) { if( node ) node->increment(ref_t); }
    103         ~ptr_base() { if( node ) node->decrement(ref_t); }
     102        ptr_base( const node_t * n ) : node(n) { if( node ) increment(node, ref_t); }
     103        ~ptr_base() { if( node ) decrement(node, ref_t); }
    104104
    105105        template< enum Node::ref_type o_ref_t >
    106106        ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) {
    107                 if( node ) node->increment(ref_t);
     107                if( node ) increment(node, ref_t);
    108108        }
    109109
    110110        template< enum Node::ref_type o_ref_t >
    111111        ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {
    112                 if( node ) node->increment(ref_t);
     112                if( node ) increment(node, ref_t);
     113        }
     114
     115        template<typename o_node_t>
     116        ptr_base & operator=( const o_node_t * node ) {
     117                assign(strict_dynamic_cast<const node_t *>(node));
     118                return *this;
    113119        }
    114120
     
    138144private:
    139145        void assign( const node_t * other ) {
    140                 if( other ) other->increment(ref_t);
    141                 if( node  ) node ->decrement(ref_t);
     146                if( other ) increment(other, ref_t);
     147                if( node  ) decrement(node , ref_t);
    142148                node = other;
    143149        }
  • src/AST/Pass.hpp

    r9e1d485 r69bafd2  
    2323#include "AST/Fwd.hpp"
    2424#include "AST/Node.hpp"
     25
     26#include "AST/Attribute.hpp"
    2527#include "AST/Decl.hpp"
     28#include "AST/Expr.hpp"
     29#include "AST/Init.hpp"
     30#include "AST/Stmt.hpp"
     31
    2632#include "AST/Visitor.hpp"
    2733
     
    7985
    8086        /// Visit function declarations
    81         virtual DeclWithType *     visit( const ObjectDecl           * ) override final;
    82         virtual DeclWithType *     visit( const FunctionDecl         * ) override final;
    83         virtual Decl *             visit( const StructDecl           * ) override final;
    84         virtual Decl *             visit( const UnionDecl            * ) override final;
    85         virtual Decl *             visit( const EnumDecl             * ) override final;
    86         virtual Decl *             visit( const TraitDecl            * ) override final;
    87         virtual Decl *             visit( const TypeDecl             * ) override final;
    88         virtual Decl *             visit( const TypedefDecl          * ) override final;
    89         virtual AsmDecl *          visit( const AsmDecl              * ) override final;
    90         virtual StaticAssertDecl * visit( const StaticAssertDecl     * ) override final;
    91         virtual CompoundStmt *     visit( const CompoundStmt         * ) override final;
    92         virtual Stmt *             visit( const ExprStmt             * ) override final;
    93         virtual Stmt *             visit( const AsmStmt              * ) override final;
    94         virtual Stmt *             visit( const DirectiveStmt        * ) override final;
    95         virtual Stmt *             visit( const IfStmt               * ) override final;
    96         virtual Stmt *             visit( const WhileStmt            * ) override final;
    97         virtual Stmt *             visit( const ForStmt              * ) override final;
    98         virtual Stmt *             visit( const SwitchStmt           * ) override final;
    99         virtual Stmt *             visit( const CaseStmt             * ) override final;
    100         virtual Stmt *             visit( const BranchStmt           * ) override final;
    101         virtual Stmt *             visit( const ReturnStmt           * ) override final;
    102         virtual Stmt *             visit( const ThrowStmt            * ) override final;
    103         virtual Stmt *             visit( const TryStmt              * ) override final;
    104         virtual Stmt *             visit( const CatchStmt            * ) override final;
    105         virtual Stmt *             visit( const FinallyStmt          * ) override final;
    106         virtual Stmt *             visit( const WaitForStmt          * ) override final;
    107         virtual Stmt *             visit( const WithStmt             * ) override final;
    108         virtual NullStmt *         visit( const NullStmt             * ) override final;
    109         virtual Stmt *             visit( const DeclStmt             * ) override final;
    110         virtual Stmt *             visit( const ImplicitCtorDtorStmt * ) override final;
    111         virtual Expr *             visit( const ApplicationExpr      * ) override final;
    112         virtual Expr *             visit( const UntypedExpr          * ) override final;
    113         virtual Expr *             visit( const NameExpr             * ) override final;
    114         virtual Expr *             visit( const AddressExpr          * ) override final;
    115         virtual Expr *             visit( const LabelAddressExpr     * ) override final;
    116         virtual Expr *             visit( const CastExpr             * ) override final;
    117         virtual Expr *             visit( const KeywordCastExpr      * ) override final;
    118         virtual Expr *             visit( const VirtualCastExpr      * ) override final;
    119         virtual Expr *             visit( const UntypedMemberExpr    * ) override final;
    120         virtual Expr *             visit( const MemberExpr           * ) override final;
    121         virtual Expr *             visit( const VariableExpr         * ) override final;
    122         virtual Expr *             visit( const ConstantExpr         * ) override final;
    123         virtual Expr *             visit( const SizeofExpr           * ) override final;
    124         virtual Expr *             visit( const AlignofExpr          * ) override final;
    125         virtual Expr *             visit( const UntypedOffsetofExpr  * ) override final;
    126         virtual Expr *             visit( const OffsetofExpr         * ) override final;
    127         virtual Expr *             visit( const OffsetPackExpr       * ) override final;
    128         virtual Expr *             visit( const AttrExpr             * ) override final;
    129         virtual Expr *             visit( const LogicalExpr          * ) override final;
    130         virtual Expr *             visit( const ConditionalExpr      * ) override final;
    131         virtual Expr *             visit( const CommaExpr            * ) override final;
    132         virtual Expr *             visit( const TypeExpr             * ) override final;
    133         virtual Expr *             visit( const AsmExpr              * ) override final;
    134         virtual Expr *             visit( const ImplicitCopyCtorExpr * ) override final;
    135         virtual Expr *             visit( const ConstructorExpr      * ) override final;
    136         virtual Expr *             visit( const CompoundLiteralExpr  * ) override final;
    137         virtual Expr *             visit( const RangeExpr            * ) override final;
    138         virtual Expr *             visit( const UntypedTupleExpr     * ) override final;
    139         virtual Expr *             visit( const TupleExpr            * ) override final;
    140         virtual Expr *             visit( const TupleIndexExpr       * ) override final;
    141         virtual Expr *             visit( const TupleAssignExpr      * ) override final;
    142         virtual Expr *             visit( const StmtExpr             * ) override final;
    143         virtual Expr *             visit( const UniqueExpr           * ) override final;
    144         virtual Expr *             visit( const UntypedInitExpr      * ) override final;
    145         virtual Expr *             visit( const InitExpr             * ) override final;
    146         virtual Expr *             visit( const DeletedExpr          * ) override final;
    147         virtual Expr *             visit( const DefaultArgExpr       * ) override final;
    148         virtual Expr *             visit( const GenericExpr          * ) override final;
    149         virtual Type *             visit( const VoidType             * ) override final;
    150         virtual Type *             visit( const BasicType            * ) override final;
    151         virtual Type *             visit( const PointerType          * ) override final;
    152         virtual Type *             visit( const ArrayType            * ) override final;
    153         virtual Type *             visit( const ReferenceType        * ) override final;
    154         virtual Type *             visit( const QualifiedType        * ) override final;
    155         virtual Type *             visit( const FunctionType         * ) override final;
    156         virtual Type *             visit( const StructInstType       * ) override final;
    157         virtual Type *             visit( const UnionInstType        * ) override final;
    158         virtual Type *             visit( const EnumInstType         * ) override final;
    159         virtual Type *             visit( const TraitInstType        * ) override final;
    160         virtual Type *             visit( const TypeInstType         * ) override final;
    161         virtual Type *             visit( const TupleType            * ) override final;
    162         virtual Type *             visit( const TypeofType           * ) override final;
    163         virtual Type *             visit( const VarArgsType          * ) override final;
    164         virtual Type *             visit( const ZeroType             * ) override final;
    165         virtual Type *             visit( const OneType              * ) override final;
    166         virtual Type *             visit( const GlobalScopeType      * ) override final;
    167         virtual Designation *      visit( const Designation          * ) override final;
    168         virtual Init *             visit( const SingleInit           * ) override final;
    169         virtual Init *             visit( const ListInit             * ) override final;
    170         virtual Init *             visit( const ConstructorInit      * ) override final;
    171         virtual Constant *         visit( const Constant             * ) override final;
    172         virtual Attribute *        visit( const Attribute            * ) override final;
    173         virtual TypeSubstitution * visit( const TypeSubstitution     * ) override final;
     87        virtual const ast::DeclWithType *     visit( const ast::ObjectDecl           * ) override final;
     88        virtual const ast::DeclWithType *     visit( const ast::FunctionDecl         * ) override final;
     89        virtual const ast::Decl *             visit( const ast::StructDecl           * ) override final;
     90        virtual const ast::Decl *             visit( const ast::UnionDecl            * ) override final;
     91        virtual const ast::Decl *             visit( const ast::EnumDecl             * ) override final;
     92        virtual const ast::Decl *             visit( const ast::TraitDecl            * ) override final;
     93        virtual const ast::Decl *             visit( const ast::TypeDecl             * ) override final;
     94        virtual const ast::Decl *             visit( const ast::TypedefDecl          * ) override final;
     95        virtual const ast::AsmDecl *          visit( const ast::AsmDecl              * ) override final;
     96        virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) override final;
     97        virtual const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) override final;
     98        virtual const ast::Stmt *             visit( const ast::ExprStmt             * ) override final;
     99        virtual const ast::Stmt *             visit( const ast::AsmStmt              * ) override final;
     100        virtual const ast::Stmt *             visit( const ast::DirectiveStmt        * ) override final;
     101        virtual const ast::Stmt *             visit( const ast::IfStmt               * ) override final;
     102        virtual const ast::Stmt *             visit( const ast::WhileStmt            * ) override final;
     103        virtual const ast::Stmt *             visit( const ast::ForStmt              * ) override final;
     104        virtual const ast::Stmt *             visit( const ast::SwitchStmt           * ) override final;
     105        virtual const ast::Stmt *             visit( const ast::CaseStmt             * ) override final;
     106        virtual const ast::Stmt *             visit( const ast::BranchStmt           * ) override final;
     107        virtual const ast::Stmt *             visit( const ast::ReturnStmt           * ) override final;
     108        virtual const ast::Stmt *             visit( const ast::ThrowStmt            * ) override final;
     109        virtual const ast::Stmt *             visit( const ast::TryStmt              * ) override final;
     110        virtual const ast::Stmt *             visit( const ast::CatchStmt            * ) override final;
     111        virtual const ast::Stmt *             visit( const ast::FinallyStmt          * ) override final;
     112        virtual const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
     113        virtual const ast::Stmt *             visit( const ast::WithStmt             * ) override final;
     114        virtual const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
     115        virtual const ast::Stmt *             visit( const ast::DeclStmt             * ) override final;
     116        virtual const ast::Stmt *             visit( const ast::ImplicitCtorDtorStmt * ) override final;
     117        virtual const ast::Expr *             visit( const ast::ApplicationExpr      * ) override final;
     118        virtual const ast::Expr *             visit( const ast::UntypedExpr          * ) override final;
     119        virtual const ast::Expr *             visit( const ast::NameExpr             * ) override final;
     120        virtual const ast::Expr *             visit( const ast::AddressExpr          * ) override final;
     121        virtual const ast::Expr *             visit( const ast::LabelAddressExpr     * ) override final;
     122        virtual const ast::Expr *             visit( const ast::CastExpr             * ) override final;
     123        virtual const ast::Expr *             visit( const ast::KeywordCastExpr      * ) override final;
     124        virtual const ast::Expr *             visit( const ast::VirtualCastExpr      * ) override final;
     125        virtual const ast::Expr *             visit( const ast::UntypedMemberExpr    * ) override final;
     126        virtual const ast::Expr *             visit( const ast::MemberExpr           * ) override final;
     127        virtual const ast::Expr *             visit( const ast::VariableExpr         * ) override final;
     128        virtual const ast::Expr *             visit( const ast::ConstantExpr         * ) override final;
     129        virtual const ast::Expr *             visit( const ast::SizeofExpr           * ) override final;
     130        virtual const ast::Expr *             visit( const ast::AlignofExpr          * ) override final;
     131        virtual const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * ) override final;
     132        virtual const ast::Expr *             visit( const ast::OffsetofExpr         * ) override final;
     133        virtual const ast::Expr *             visit( const ast::OffsetPackExpr       * ) override final;
     134        virtual const ast::Expr *             visit( const ast::AttrExpr             * ) override final;
     135        virtual const ast::Expr *             visit( const ast::LogicalExpr          * ) override final;
     136        virtual const ast::Expr *             visit( const ast::ConditionalExpr      * ) override final;
     137        virtual const ast::Expr *             visit( const ast::CommaExpr            * ) override final;
     138        virtual const ast::Expr *             visit( const ast::TypeExpr             * ) override final;
     139        virtual const ast::Expr *             visit( const ast::AsmExpr              * ) override final;
     140        virtual const ast::Expr *             visit( const ast::ImplicitCopyCtorExpr * ) override final;
     141        virtual const ast::Expr *             visit( const ast::ConstructorExpr      * ) override final;
     142        virtual const ast::Expr *             visit( const ast::CompoundLiteralExpr  * ) override final;
     143        virtual const ast::Expr *             visit( const ast::RangeExpr            * ) override final;
     144        virtual const ast::Expr *             visit( const ast::UntypedTupleExpr     * ) override final;
     145        virtual const ast::Expr *             visit( const ast::TupleExpr            * ) override final;
     146        virtual const ast::Expr *             visit( const ast::TupleIndexExpr       * ) override final;
     147        virtual const ast::Expr *             visit( const ast::TupleAssignExpr      * ) override final;
     148        virtual const ast::Expr *             visit( const ast::StmtExpr             * ) override final;
     149        virtual const ast::Expr *             visit( const ast::UniqueExpr           * ) override final;
     150        virtual const ast::Expr *             visit( const ast::UntypedInitExpr      * ) override final;
     151        virtual const ast::Expr *             visit( const ast::InitExpr             * ) override final;
     152        virtual const ast::Expr *             visit( const ast::DeletedExpr          * ) override final;
     153        virtual const ast::Expr *             visit( const ast::DefaultArgExpr       * ) override final;
     154        virtual const ast::Expr *             visit( const ast::GenericExpr          * ) override final;
     155        virtual const ast::Type *             visit( const ast::VoidType             * ) override final;
     156        virtual const ast::Type *             visit( const ast::BasicType            * ) override final;
     157        virtual const ast::Type *             visit( const ast::PointerType          * ) override final;
     158        virtual const ast::Type *             visit( const ast::ArrayType            * ) override final;
     159        virtual const ast::Type *             visit( const ast::ReferenceType        * ) override final;
     160        virtual const ast::Type *             visit( const ast::QualifiedType        * ) override final;
     161        virtual const ast::Type *             visit( const ast::FunctionType         * ) override final;
     162        virtual const ast::Type *             visit( const ast::StructInstType       * ) override final;
     163        virtual const ast::Type *             visit( const ast::UnionInstType        * ) override final;
     164        virtual const ast::Type *             visit( const ast::EnumInstType         * ) override final;
     165        virtual const ast::Type *             visit( const ast::TraitInstType        * ) override final;
     166        virtual const ast::Type *             visit( const ast::TypeInstType         * ) override final;
     167        virtual const ast::Type *             visit( const ast::TupleType            * ) override final;
     168        virtual const ast::Type *             visit( const ast::TypeofType           * ) override final;
     169        virtual const ast::Type *             visit( const ast::VarArgsType          * ) override final;
     170        virtual const ast::Type *             visit( const ast::ZeroType             * ) override final;
     171        virtual const ast::Type *             visit( const ast::OneType              * ) override final;
     172        virtual const ast::Type *             visit( const ast::GlobalScopeType      * ) override final;
     173        virtual const ast::Designation *      visit( const ast::Designation          * ) override final;
     174        virtual const ast::Init *             visit( const ast::SingleInit           * ) override final;
     175        virtual const ast::Init *             visit( const ast::ListInit             * ) override final;
     176        virtual const ast::Init *             visit( const ast::ConstructorInit      * ) override final;
     177        virtual const ast::Constant *         visit( const ast::Constant             * ) override final;
     178        virtual const ast::Attribute *        visit( const ast::Attribute            * ) override final;
     179        virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution     * ) override final;
    174180
    175181        friend void acceptAll( std::list< ptr<Decl> > & decls, Pass<pass_t>& visitor );
     
    179185
    180186private:
     187        const ast::Stmt * call_accept( const ast::Stmt * );
     188        const ast::Expr * call_accept( const ast::Expr * );
     189
     190        template< typename node_t >
     191        auto call_accept( const node_t * node ) -> decltype( node->accept(*this) );
     192
     193        template< template <class...> class container_t >
     194        container_t< ptr<Stmt> > call_accept( const container_t< ptr<Stmt> > & );
     195
     196        template< template <class...> class container_t, typename node_t >
     197        container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container );
     198
    181199        /// Logic to call the accept and mutate the parent if needed, delegates call to accept
    182         template<typename parent_t, typename child_t>
    183         void maybe_accept(parent_t * & , typename parent_t::child_t *);
    184 
    185         Stmt * call_accept( const Stmt * );
    186         Expr * call_accept( const Expr * );
    187 
    188         template< template <class> class container_t >
    189         container_t< ptr<Stmt> > call_accept( const container_t< ptr<Stmt> > & );
    190 
    191         template< template <class> class container_t, typename node_t >
    192         container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container );
     200        template<typename node_t, typename parent_t, typename child_t>
     201        void maybe_accept(const node_t * &, child_t parent_t::* child);
    193202
    194203private:
     
    209218
    210219template<typename pass_t>
    211 void acceptAll( std::list< ptr<Decl> >, Pass<pass_t>& visitor );
     220void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<pass_t> & visitor );
    212221
    213222//-------------------------------------------------------------------------------------------------
     
    215224//-------------------------------------------------------------------------------------------------
    216225
    217 template<typename T>
    218 using std_list = std::list<T>;
    219 
    220226/// Keep track of the polymorphic const TypeSubstitution * env for the current expression
    221227struct WithConstTypeSubstitution {
     
    225231/// Used if visitor requires added statements before or after the current node.
    226232/// The Pass template handles what *before* and *after* means automatically
    227 template< template<class> class container_t = std_list >
     233template< template<class...> class container_t = std::list >
    228234struct WithStmtsToAdd {
    229235        container_t< ptr<Stmt> > stmtsToAddBefore;
     
    233239/// Used if visitor requires added declarations before or after the current node.
    234240/// The Pass template handles what *before* and *after* means automatically
    235 template< template<class> class container_t = std_list >
     241template< template<class...> class container_t = std::list >
    236242struct WithDeclsToAdd {
    237243        container_t< ptr<Decl> > declsToAddBefore;
     
    285291};
    286292}
     293
     294#include "Common/Stats.h"
     295
     296extern struct PassVisitorStats {
     297        size_t depth = 0;
     298        Stats::Counters::MaxCounter<double> * max = nullptr;
     299        Stats::Counters::AverageCounter<double> * avg = nullptr;
     300} pass_visitor_stats;
     301
     302#include "AST/Pass.impl.hpp"
  • src/AST/Pass.impl.hpp

    r9e1d485 r69bafd2  
    1616#pragma once
    1717// IWYU pragma: private, include "AST/Pass.hpp"
     18
     19#include <type_traits>
     20#include <unordered_map>
    1821
    1922#define VISIT_START( node ) \
     
    2629        __pass::previsit( pass, node, 0 );
    2730
    28 #define VISIT( code ) \
     31#define VISIT( code... ) \
    2932        /* if this node should visit its children */ \
    3033        if ( __visit_children() ) { \
     
    3538#define VISIT_END( type, node ) \
    3639        /* call the implementation of the postvisit of this pass */ \
    37         auto __return = __pass::postvisit< type * >( node ); \
     40        auto __return = __pass::postvisit( pass, node, 0 ); \
    3841        assertf(__return, "post visit should never return null"); \
    3942        return __return;
    4043
    4144#ifdef PEDANTIC_PASS_ASSERT
    42 #define __pedantic_pass_assert (...) assert (__VAR_ARGS__)
    43 #define __pedantic_pass_assertf(...) assertf(__VAR_ARGS__)
     45#define __pedantic_pass_assert(...) assert (__VA_ARGS__)
     46#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
    4447#else
    45 #define __pedantic_pass_assert (...)
     48#define __pedantic_pass_assert(...)
    4649#define __pedantic_pass_assertf(...)
    4750#endif
     
    5558                }
    5659
    57                 template<typename it_t, template <class> class container_t>
    58                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Declaration>> * decls, bool * mutated = nullptr ) {
     60                //------------------------------
     61                template<typename it_t, template <class...> class container_t>
     62                static inline void take_all( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) {
    5963                        if(empty(decls)) return;
    6064
    61                         std::transform(decls->begin(), decls->end(), it, [](Declaration * decl) -> auto {
     65                        std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
    6266                                        return new DeclStmt( decl );
    6367                                });
     
    6670                }
    6771
    68                 template<typename it_t, template <class> class container_t>
    69                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Statement>> * decls, bool * mutated = nullptr ) {
     72                template<typename it_t, template <class...> class container_t>
     73                static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * decls, bool * mutated = nullptr ) {
    7074                        if(empty(decls)) return;
    7175
     
    7579                }
    7680
     81                //------------------------------
     82                /// Check if should be skipped, different for pointers and containers
    7783                template<typename node_t>
    78                 bool differs( const node_t * old_val, const node_t * new_val ) {
     84                bool skip( const ast::ptr<node_t> & val) {
     85                        return !val;
     86                }
     87
     88                template< template <class...> class container_t, typename node_t >
     89                bool skip( const container_t<ast::ptr< node_t >> & val ) {
     90                        return val.empty();
     91                }
     92
     93                //------------------------------
     94                /// Get the value to visit, different for pointers and containers
     95                template<typename node_t>
     96                auto get( const ast::ptr<node_t> & val, int ) -> decltype(val.get()) {
     97                        return val.get();
     98                }
     99
     100                template<typename node_t>
     101                const node_t & get( const node_t & val, long) {
     102                        return val;
     103                }
     104
     105
     106                //------------------------------
     107                /// Check if value was mutated, different for pointers and containers
     108                template<typename lhs_t, typename rhs_t>
     109                bool differs( const lhs_t * old_val, const rhs_t * new_val ) {
    79110                        return old_val != new_val;
    80111                }
    81112
    82                 template< template <class> class container_t >
    83                 bool differs( const container_t<ast::ptr< ast::Statement >> &, const container_t<ast::ptr< ast::Statement >> & new_val ) {
     113                template< template <class...> class container_t, typename node_t >
     114                bool differs( const container_t<ast::ptr< node_t >> &, const container_t<ast::ptr< node_t >> & new_val ) {
    84115                        return !new_val.empty();
    85                 }
    86         }
    87 
    88         template<typename parent_t, typename child_t>
    89         template< typename pass_t >
    90         void Pass< pass_t >::maybe_accept(
    91                 const parent_t * & parent,
    92                 const typename parent_t::child_t * child
    93         ) {
    94                 const auto & old_val = parent->*child;
    95                 if(!old_val) return;
    96 
    97                 auto new_val = call_accept(old_val);
    98 
    99                 if( __pass::differs(old_val, new_val) ) {
    100                         auto new_parent = mutate(parent);
    101                         new_parent->*child = new_val;
    102                         parent = new_parent;
    103116                }
    104117        }
     
    106119        template< typename pass_t >
    107120        template< typename node_t >
    108         auto Pass< pass_t >::call_accept( const node_t * node ) {
     121        auto Pass< pass_t >::call_accept( const node_t * node ) -> decltype( node->accept(*this) ) {
    109122                __pedantic_pass_assert( __visit_children() );
    110123                __pedantic_pass_assert( expr );
    111124
     125                static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");
     126                static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR");
     127
    112128                return node->accept( *this );
    113129        }
    114130
    115131        template< typename pass_t >
    116         ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
     132        const ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
    117133                __pedantic_pass_assert( __visit_children() );
    118134                __pedantic_pass_assert( expr );
     
    127143
    128144        template< typename pass_t >
    129         Stmt * Pass< pass_t >::call_accept( const Stmt * stmt ) {
     145        const ast::Stmt * Pass< pass_t >::call_accept( const ast::Stmt * stmt ) {
    130146                __pedantic_pass_assert( __visit_children() );
    131147                __pedantic_pass_assert( stmt );
     
    141157
    142158                // These may be modified by subnode but most be restored once we exit this statemnet.
    143                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0); );
    144                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
    145                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
    146                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
    147                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
     159                ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0) );
     160                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > > __old_decls_before( stmts_before );
     161                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > > __old_decls_after ( stmts_after  );
     162                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > > __old_stmts_before( decls_before );
     163                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > > __old_stmts_after ( decls_after  );
    148164
    149165                // Now is the time to actually visit the node
    150                 ast::Statement * nstmt = stmt->accept( *this );
     166                const ast::Stmt * nstmt = stmt->accept( *this );
    151167
    152168                // If the pass doesn't want to add anything then we are done
     
    161177
    162178                // Create a new Compound Statement to hold the new decls/stmts
    163                 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );
     179                ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
    164180
    165181                // Take all the declarations that go before
     
    168184
    169185                // Insert the original declaration
    170                 compound->kids.push_back( nstmt );
     186                compound->kids.emplace_back( nstmt );
    171187
    172188                // Insert all the declarations that go before
     
    178194
    179195        template< typename pass_t >
    180         template< template <class> class container_t >
     196        template< template <class...> class container_t >
    181197        container_t< ptr<Stmt> > Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    182198                __pedantic_pass_assert( __visit_children() );
     
    196212
    197213                // These may be modified by subnode but most be restored once we exit this statemnet.
    198                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
    199                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
    200                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
    201                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
     214                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > > __old_decls_before( stmts_before );
     215                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > > __old_decls_after ( stmts_after  );
     216                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > > __old_stmts_before( decls_before );
     217                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > > __old_stmts_after ( decls_after  );
    202218
    203219                // update pass statitistics
     
    211227                        try {
    212228                                __pedantic_pass_assert( stmt );
    213                                 const ast::Statment * new_stmt = stmt->accept( visitor );
     229                                const ast::Stmt * new_stmt = stmt->accept( *this );
    214230                                assert( new_stmt );
    215231                                if(new_stmt != stmt ) mutated = true;
     
    240256                if ( !errors.isEmpty() ) { throw errors; }
    241257
    242                 return mutated ? new_kids : {};
     258                return mutated ? new_kids : container_t< ptr<Stmt> >();
    243259        }
    244260
    245261        template< typename pass_t >
    246         template< template <class> class container_t, typename node_t >
     262        template< template <class...> class container_t, typename node_t >
    247263        container_t< ast::ptr<node_t> > Pass< pass_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    248264                __pedantic_pass_assert( __visit_children() );
     
    259275                        try {
    260276                                __pedantic_pass_assert( node );
    261                                 const node_t * new_node = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
    262                                 if(new_stmt != stmt ) mutated = true;
     277                                const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
     278                                if(new_stmt != node ) mutated = true;
    263279
    264280                                new_kids.emplace_back( new_stmt );
     
    271287                if ( ! errors.isEmpty() ) { throw errors; }
    272288
    273                 return mutated ? new_kids : {};
    274         }
     289                return mutated ? new_kids : container_t< ast::ptr<node_t> >();
     290        }
     291
     292        template< typename pass_t >
     293        template<typename node_t, typename parent_t, typename child_t>
     294        void Pass< pass_t >::maybe_accept(
     295                const node_t * & parent,
     296                child_t parent_t::*child
     297        ) {
     298                static_assert( std::is_base_of<parent_t, node_t>::value, "Error deductiing member object" );
     299
     300                if(__pass::skip(parent->*child)) return;
     301                const auto & old_val = __pass::get(parent->*child, 0);
     302
     303                static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");
     304
     305                auto new_val = call_accept( old_val );
     306
     307                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     308
     309                if( __pass::differs(old_val, new_val) ) {
     310                        auto new_parent = mutate(parent);
     311                        new_parent->*child = new_val;
     312                        parent = new_parent;
     313                }
     314        }
     315
    275316}
    276317
     
    284325
    285326template< typename pass_t >
    286 inline void ast::acceptAll( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
     327inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
    287328        // We are going to aggregate errors for all these statements
    288329        SemanticErrorException errors;
     
    292333
    293334        // get the stmts/decls that will need to be spliced in
    294         auto decls_before = __pass::declsToAddBefore( pass, 0);
    295         auto decls_after  = __pass::declsToAddAfter ( pass, 0);
     335        auto decls_before = __pass::declsToAddBefore( visitor.pass, 0);
     336        auto decls_after  = __pass::declsToAddAfter ( visitor.pass, 0);
    296337
    297338        // update pass statitistics
     
    343384// ObjectDecl
    344385template< typename pass_t >
    345 ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
     386const ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
    346387        VISIT_START( node );
    347388
    348389        VISIT(
    349390                {
    350                         indexer_guard guard { *this };
    351                         maybe_accept( node, ObjectDecl::type );
    352                 }
    353                 maybe_accept( node, ObjectDecl::init          );
    354                 maybe_accept( node, ObjectDecl::bitfieldWidth );
    355                 maybe_accept( node, ObjectDecl::attributes    );
     391                        guard_indexer guard { *this };
     392                        maybe_accept( node, &ast::ObjectDecl::type );
     393                }
     394                maybe_accept( node, &ast::ObjectDecl::init          );
     395                maybe_accept( node, &ast::ObjectDecl::bitfieldWidth );
     396                maybe_accept( node, &ast::ObjectDecl::attributes    );
    356397        )
    357398
    358         __pass::indexer::AddId( pass, 0, node );
     399        __pass::indexer::addId( pass, 0, node );
    359400
    360401        VISIT_END( DeclWithType, node );
     402}
     403
     404//--------------------------------------------------------------------------
     405// SingleInit
     406template< typename pass_t >
     407const ast::Init * ast::Pass< pass_t >::visit( const ast::SingleInit * node ) {
     408        VISIT_START( node );
     409
     410        VISIT(
     411                maybe_accept( node, &SingleInit::value );
     412        )
     413
     414        VISIT_END( Init, node );
     415}
     416
     417//--------------------------------------------------------------------------
     418// ListInit
     419template< typename pass_t >
     420const ast::Init * ast::Pass< pass_t >::visit( const ast::ListInit * node ) {
     421        VISIT_START( node );
     422
     423        VISIT(
     424                maybe_accept( node, &ListInit::designations );
     425                maybe_accept( node, &ListInit::initializers );
     426        )
     427
     428        VISIT_END( Init, node );
     429}
     430
     431//--------------------------------------------------------------------------
     432// ConstructorInit
     433template< typename pass_t >
     434const ast::Init * ast::Pass< pass_t >::visit( const ast::ConstructorInit * node ) {
     435        VISIT_START( node );
     436
     437        VISIT(
     438                maybe_accept( node, &ConstructorInit::ctor );
     439                maybe_accept( node, &ConstructorInit::dtor );
     440                maybe_accept( node, &ConstructorInit::init );
     441        )
     442
     443        VISIT_END( Init, node );
    361444}
    362445
    363446//--------------------------------------------------------------------------
    364447// Attribute
    365 template< typename pass_type >
    366 ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute * node  )  {
    367         VISIT_START(node);
     448template< typename pass_t >
     449const ast::Attribute * ast::Pass< pass_t >::visit( const ast::Attribute * node  )  {
     450        VISIT_START( node );
    368451
    369452        VISIT(
    370                 maybe_accept( node, ast::Attribute::parameters );
     453                maybe_accept( node, &Attribute::parameters );
    371454        )
    372455
    373         VISIT_END(ast::Attribute *, node );
     456        VISIT_END( Attribute *, node );
    374457}
    375458
    376459//--------------------------------------------------------------------------
    377460// TypeSubstitution
    378 template< typename pass_type >
    379 TypeSubstitution * PassVisitor< pass_type >::mutate( const TypeSubstitution * node ) {
    380         MUTATE_START( node );
    381 
    382         #error this is broken
    383 
    384         for ( auto & p : node->typeEnv ) {
    385                 indexerScopedMutate( p.second, *this );
    386         }
    387         for ( auto & p : node->varEnv ) {
    388                 indexerScopedMutate( p.second, *this );
    389         }
    390 
    391         MUTATE_END( TypeSubstitution, node );
     461template< typename pass_t >
     462const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) {
     463        VISIT_START( node );
     464
     465        VISIT(
     466                {
     467                        bool mutated = false;
     468                        std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
     469                        for ( const auto & p : node->typeEnv ) {
     470                                guard_indexer guard { *this };
     471                                auto new_node = p.second->accept( *this );
     472                                if (new_node != p.second) mutated = false;
     473                                new_map.insert({ p.first, new_node });
     474                        }
     475                        if (mutated) {
     476                                auto new_node = mutate( node );
     477                                new_node->typeEnv.swap( new_map );
     478                                node = new_node;
     479                        }
     480                }
     481
     482                {
     483                        bool mutated = false;
     484                        std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
     485                        for ( const auto & p : node->varEnv ) {
     486                                guard_indexer guard { *this };
     487                                auto new_node = p.second->accept( *this );
     488                                if (new_node != p.second) mutated = false;
     489                                new_map.insert({ p.first, new_node });
     490                        }
     491                        if (mutated) {
     492                                auto new_node = mutate( node );
     493                                new_node->varEnv.swap( new_map );
     494                                node = new_node;
     495                        }
     496                }
     497        )
     498
     499        VISIT_END( TypeSubstitution, node );
    392500}
    393501
  • src/AST/Pass.proto.hpp

    r9e1d485 r69bafd2  
    162162
    163163        // List of fields and their expected types
    164         FIELD_PTR( env, const ast::TypeSubstitution )
     164        FIELD_PTR( env, const ast::TypeSubstitution * )
    165165        FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > )
    166166        FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > )
     
    235235                static inline void func( pass_t &, long, type1, type2 ) {}
    236236
    237                 INDEXER_FUNC1( addId     , DeclWithType *  );
    238                 INDEXER_FUNC1( addType   , NamedTypeDecl * );
    239                 INDEXER_FUNC1( addStruct , StructDecl *    );
    240                 INDEXER_FUNC1( addEnum   , EnumDecl *      );
    241                 INDEXER_FUNC1( addUnion  , UnionDecl *     );
    242                 INDEXER_FUNC1( addTrait  , TraitDecl *     );
    243                 INDEXER_FUNC2( addWith   , std::list< Expression * > &, Node * );
     237                INDEXER_FUNC1( addId     , const DeclWithType *  );
     238                INDEXER_FUNC1( addType   , const NamedTypeDecl * );
     239                INDEXER_FUNC1( addStruct , const StructDecl *    );
     240                INDEXER_FUNC1( addEnum   , const EnumDecl *      );
     241                INDEXER_FUNC1( addUnion  , const UnionDecl *     );
     242                INDEXER_FUNC1( addTrait  , const TraitDecl *     );
     243                INDEXER_FUNC2( addWith   , const std::list< Expression * > &, const Node * );
    244244
    245245                // A few extra functions have more complicated behaviour, they are hand written
    246                 // template<typename pass_t>
    247                 // static inline auto addStructFwd( pass_t & pass, int, ast::StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
    248                 //      ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    249                 //      fwd->parameters = decl->parameters;
    250                 //      pass.indexer.addStruct( fwd );
    251                 // }
    252 
    253                 // template<typename pass_t>
    254                 // static inline void addStructFwd( pass_t &, long, ast::StructDecl * ) {}
    255 
    256                 // template<typename pass_t>
    257                 // static inline auto addUnionFwd( pass_t & pass, int, ast::UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
    258                 //      UnionDecl * fwd = new UnionDecl( decl->name );
    259                 //      fwd->parameters = decl->parameters;
    260                 //      pass.indexer.addUnion( fwd );
    261                 // }
    262 
    263                 // template<typename pass_t>
    264                 // static inline void addUnionFwd( pass_t &, long, ast::UnionDecl * ) {}
    265 
    266                 // template<typename pass_t>
    267                 // static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) {
    268                 //      if ( ! pass.indexer.lookupStruct( str ) ) {
    269                 //              pass.indexer.addStruct( str );
    270                 //      }
    271                 // }
    272 
    273                 // template<typename pass_t>
    274                 // static inline void addStruct( pass_t &, long, const std::string & ) {}
    275 
    276                 // template<typename pass_t>
    277                 // static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
    278                 //      if ( ! pass.indexer.lookupUnion( str ) ) {
    279                 //              pass.indexer.addUnion( str );
    280                 //      }
    281                 // }
    282 
    283                 // template<typename pass_t>
    284                 // static inline void addUnion( pass_t &, long, const std::string & ) {}
     246                template<typename pass_t>
     247                static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
     248                        ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
     249                        fwd->parameters = decl->parameters;
     250                        pass.indexer.addStruct( fwd );
     251                }
     252
     253                template<typename pass_t>
     254                static inline void addStructFwd( pass_t &, long, const ast::StructDecl * ) {}
     255
     256                template<typename pass_t>
     257                static inline auto addUnionFwd( pass_t & pass, int, const ast::UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
     258                        UnionDecl * fwd = new UnionDecl( decl->location, decl->name );
     259                        fwd->parameters = decl->parameters;
     260                        pass.indexer.addUnion( fwd );
     261                }
     262
     263                template<typename pass_t>
     264                static inline void addUnionFwd( pass_t &, long, const ast::UnionDecl * ) {}
     265
     266                template<typename pass_t>
     267                static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) {
     268                        if ( ! pass.indexer.lookupStruct( str ) ) {
     269                                pass.indexer.addStruct( str );
     270                        }
     271                }
     272
     273                template<typename pass_t>
     274                static inline void addStruct( pass_t &, long, const std::string & ) {}
     275
     276                template<typename pass_t>
     277                static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
     278                        if ( ! pass.indexer.lookupUnion( str ) ) {
     279                                pass.indexer.addUnion( str );
     280                        }
     281                }
     282
     283                template<typename pass_t>
     284                static inline void addUnion( pass_t &, long, const std::string & ) {}
    285285
    286286                #undef INDEXER_FUNC1
  • src/AST/Stmt.hpp

    r9e1d485 r69bafd2  
    4040        Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {}
    4141
    42         virtual Stmt* accept( Visitor& v ) override = 0;
     42        virtual const Stmt* accept( Visitor& v ) const override = 0;
    4343private:
    4444        virtual Stmt* clone() const override = 0;
     
    5959        void push_front( Stmt* s ) { kids.emplace_front( s ); }
    6060
    61         CompoundStmt* accept( Visitor& v ) override { return v.visit( this ); }
     61        virtual const CompoundStmt* accept( Visitor& v ) const override { return v.visit( this ); }
    6262private:
    63         CompoundStmt* clone() const override { return new CompoundStmt{ *this }; }
     63        virtual CompoundStmt* clone() const override { return new CompoundStmt{ *this }; }
    6464};
    6565
     
    7070        : Stmt(loc, std::move(labels)) {}
    7171
    72         NullStmt* accept( Visitor& v ) override { return v.visit( this ); }
     72        virtual const NullStmt * accept( Visitor& v ) const override { return v.visit( this ); }
    7373private:
    74         NullStmt* clone() const override { return new NullStmt{ *this }; }
     74        virtual NullStmt * clone() const override { return new NullStmt{ *this }; }
    7575};
    7676
     
    8282        ExprStmt( const CodeLocation& loc, Expr* e ) : Stmt(loc), expr(e) {}
    8383
    84         Stmt* accept( Visitor& v ) override { return v.visit( this ); }
     84        virtual const Stmt * accept( Visitor& v ) const override { return v.visit( this ); }
    8585private:
    86         ExprStmt* clone() const override { return new ExprStmt{ *this }; }
     86        virtual ExprStmt * clone() const override { return new ExprStmt{ *this }; }
    8787};
    8888
     
    100100inline void increment( const class ExprStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    101101inline void decrement( const class ExprStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    102 inline void increment( const class AsmStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    103 inline void decrement( const class AsmStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    104 inline void increment( const class DirectiveStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    105 inline void decrement( const class DirectiveStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    106 inline void increment( const class IfStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    107 inline void decrement( const class IfStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    108 inline void increment( const class WhileStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    109 inline void decrement( const class WhileStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    110 inline void increment( const class ForStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    111 inline void decrement( const class ForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    112 inline void increment( const class SwitchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    113 inline void decrement( const class SwitchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    114 inline void increment( const class CaseStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    115 inline void decrement( const class CaseStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    116 inline void increment( const class BranchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    117 inline void decrement( const class BranchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    118 inline void increment( const class ReturnStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    119 inline void decrement( const class ReturnStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    120 inline void increment( const class ThrowStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    121 inline void decrement( const class ThrowStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    122 inline void increment( const class TryStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    123 inline void decrement( const class TryStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    124 inline void increment( const class CatchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    125 inline void decrement( const class CatchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    126 inline void increment( const class FinallyStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    127 inline void decrement( const class FinallyStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    128 inline void increment( const class WaitForStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    129 inline void decrement( const class WaitForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    130 inline void increment( const class WithStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    131 inline void decrement( const class WithStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    132 inline void increment( const class DeclStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    133 inline void decrement( const class DeclStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     102// inline void increment( const class AsmStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     103// inline void decrement( const class AsmStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     104// inline void increment( const class DirectiveStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     105// inline void decrement( const class DirectiveStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     106// inline void increment( const class IfStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     107// inline void decrement( const class IfStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     108// inline void increment( const class WhileStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     109// inline void decrement( const class WhileStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     110// inline void increment( const class ForStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     111// inline void decrement( const class ForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     112// inline void increment( const class SwitchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     113// inline void decrement( const class SwitchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     114// inline void increment( const class CaseStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     115// inline void decrement( const class CaseStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     116// inline void increment( const class BranchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     117// inline void decrement( const class BranchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     118// inline void increment( const class ReturnStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     119// inline void decrement( const class ReturnStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     120// inline void increment( const class ThrowStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     121// inline void decrement( const class ThrowStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     122// inline void increment( const class TryStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     123// inline void decrement( const class TryStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     124// inline void increment( const class CatchStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     125// inline void decrement( const class CatchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     126// inline void increment( const class FinallyStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     127// inline void decrement( const class FinallyStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     128// inline void increment( const class WaitForStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     129// inline void decrement( const class WaitForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     130// inline void increment( const class WithStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     131// inline void decrement( const class WithStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     132// inline void increment( const class DeclStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     133// inline void decrement( const class DeclStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    134134inline void increment( const class NullStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    135135inline void decrement( const class NullStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    136 inline void increment( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->increment( ref ); }
    137 inline void decrement( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
     136// inline void increment( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->increment( ref ); }
     137// inline void decrement( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->decrement( ref ); }
    138138
    139139}
  • src/AST/Type.hpp

    r9e1d485 r69bafd2  
    6767        virtual bool isComplete() const { return true; }
    6868
    69         virtual Type * accept( Visitor & v ) override = 0;
     69        virtual const Type * accept( Visitor & v ) const override = 0;
    7070private:
    7171        virtual Type * clone() const override = 0;
     
    8181        bool isComplete() const override { return false; }
    8282
    83         Type * accept( Visitor & v ) override { return v.visit( this ); }
     83        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    8484private:
    8585        VoidType * clone() const override { return new VoidType{ *this }; }
     
    143143        bool isInteger() const { return kind <= MAX_INTEGER_TYPE; }
    144144
    145         Type * accept( Visitor & v ) override { return v.visit( this ); }
     145        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    146146private:
    147147        BasicType * clone() const override { return new BasicType{ *this }; }
     
    173173        bool isComplete() const override { return ! isVarLen; }
    174174
    175         Type * accept( Visitor & v ) override { return v.visit( this ); }
     175        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    176176private:
    177177        PointerType * clone() const override { return new PointerType{ *this }; }
     
    194194        bool isComplete() const override { return dimension || isVarLen; }
    195195
    196         Type * accept( Visitor & v ) override { return v.visit( this ); }
     196        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    197197private:
    198198        ArrayType * clone() const override { return new ArrayType{ *this }; }
     
    213213        unsigned size() const override { return base->size(); }
    214214
    215         Type * accept( Visitor & v ) override { return v.visit( this ); }
     215        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    216216private:
    217217        ReferenceType * clone() const override { return new ReferenceType{ *this }; }
     
    227227        : Type(q), parent(p), child(c) {}
    228228
    229         Type * accept( Visitor & v ) override { return v.visit( this ); }
     229        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    230230private:
    231231        QualifiedType * clone() const override { return new QualifiedType{ *this }; }
     
    271271        bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; }
    272272
    273         Type * accept( Visitor & v ) override { return v.visit( this ); }
     273        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    274274private:
    275275        FunctionType * clone() const override { return new FunctionType{ *this }; }
     
    316316        const StructDecl * aggr() const override { return base; }
    317317
    318         Type * accept( Visitor & v ) override { return v.visit( this ); }
     318        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    319319private:
    320320        StructInstType * clone() const override { return new StructInstType{ *this }; }
     
    338338        const UnionDecl * aggr() const override { return base; }
    339339
    340         Type * accept( Visitor & v ) override { return v.visit( this ); }
     340        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    341341private:
    342342        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
     
    360360        const EnumDecl * aggr() const override { return base; }
    361361
    362         Type * accept( Visitor & v ) override { return v.visit( this ); }
     362        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    363363private:
    364364        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
     
    383383        const TraitDecl * aggr() const override { return base; }
    384384
    385         Type * accept( Visitor & v ) override { return v.visit( this ); }
     385        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    386386private:
    387387        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
     
    411411        const AggregateDecl * aggr() const override { assert(false); }
    412412
    413         Type * accept( Visitor & v ) override { return v.visit( this ); }
     413        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    414414private:
    415415        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
     
    439439        }
    440440
    441         Type * accept( Visitor & v ) override { return v.visit( this ); }
     441        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    442442private:
    443443        TupleType * clone() const override { return new TupleType{ *this }; }
     
    453453        : Type(q), expr(e), kind(k) {}
    454454
    455         Type * accept( Visitor & v ) override { return v.visit( this ); }
     455        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    456456private:
    457457        TypeofType * clone() const override { return new TypeofType{ *this }; }
     
    463463        VarArgsType( CV::Qualifiers q = {} ) : Type( q ) {}
    464464       
    465         Type * accept( Visitor & v ) override { return v.visit( this ); }
     465        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    466466private:
    467467        VarArgsType * clone() const override { return new VarArgsType{ *this }; }
     
    473473        ZeroType( CV::Qualifiers q = {} ) : Type( q ) {}
    474474       
    475         Type * accept( Visitor & v ) override { return v.visit( this ); }
     475        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    476476private:
    477477        ZeroType * clone() const override { return new ZeroType{ *this }; }     
     
    483483        OneType( CV::Qualifiers q = {} ) : Type( q ) {}
    484484
    485         Type * accept( Visitor & v ) override { return v.visit( this ); }
     485        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    486486private:
    487487        OneType * clone() const override { return new OneType{ *this }; }
     
    493493        GlobalScopeType( CV::Qualifiers q = {} ) : Type( q ) {}
    494494
    495         Type * accept( Visitor & v ) override { return v.visit( this ); }
     495        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    496496private:
    497497        GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; }
  • src/AST/Visitor.hpp

    r9e1d485 r69bafd2  
    2222class Visitor {
    2323public:
    24     virtual DeclWithType *     visit( const ObjectDecl           * ) = 0;
    25     virtual DeclWithType *     visit( const FunctionDecl         * ) = 0;
    26     virtual Decl *             visit( const StructDecl           * ) = 0;
    27     virtual Decl *             visit( const UnionDecl            * ) = 0;
    28     virtual Decl *             visit( const EnumDecl             * ) = 0;
    29     virtual Decl *             visit( const TraitDecl            * ) = 0;
    30     virtual Decl *             visit( const TypeDecl             * ) = 0;
    31     virtual Decl *             visit( const TypedefDecl          * ) = 0;
    32     virtual AsmDecl *          visit( const AsmDecl              * ) = 0;
    33     virtual StaticAssertDecl * visit( const StaticAssertDecl     * ) = 0;
    34     virtual CompoundStmt *     visit( const CompoundStmt         * ) = 0;
    35     virtual Stmt *             visit( const ExprStmt             * ) = 0;
    36     virtual Stmt *             visit( const AsmStmt              * ) = 0;
    37     virtual Stmt *             visit( const DirectiveStmt        * ) = 0;
    38     virtual Stmt *             visit( const IfStmt               * ) = 0;
    39     virtual Stmt *             visit( const WhileStmt            * ) = 0;
    40     virtual Stmt *             visit( const ForStmt              * ) = 0;
    41     virtual Stmt *             visit( const SwitchStmt           * ) = 0;
    42     virtual Stmt *             visit( const CaseStmt             * ) = 0;
    43     virtual Stmt *             visit( const BranchStmt           * ) = 0;
    44     virtual Stmt *             visit( const ReturnStmt           * ) = 0;
    45     virtual Stmt *             visit( const ThrowStmt            * ) = 0;
    46     virtual Stmt *             visit( const TryStmt              * ) = 0;
    47     virtual Stmt *             visit( const CatchStmt            * ) = 0;
    48     virtual Stmt *             visit( const FinallyStmt          * ) = 0;
    49     virtual Stmt *             visit( const WaitForStmt          * ) = 0;
    50     virtual Stmt *             visit( const WithStmt             * ) = 0;
    51     virtual NullStmt *         visit( const NullStmt             * ) = 0;
    52     virtual Stmt *             visit( const DeclStmt             * ) = 0;
    53     virtual Stmt *             visit( const ImplicitCtorDtorStmt * ) = 0;
    54     virtual Expr *             visit( const ApplicationExpr      * ) = 0;
    55     virtual Expr *             visit( const UntypedExpr          * ) = 0;
    56     virtual Expr *             visit( const NameExpr             * ) = 0;
    57     virtual Expr *             visit( const AddressExpr          * ) = 0;
    58     virtual Expr *             visit( const LabelAddressExpr     * ) = 0;
    59     virtual Expr *             visit( const CastExpr             * ) = 0;
    60     virtual Expr *             visit( const KeywordCastExpr      * ) = 0;
    61     virtual Expr *             visit( const VirtualCastExpr      * ) = 0;
    62     virtual Expr *             visit( const UntypedMemberExpr    * ) = 0;
    63     virtual Expr *             visit( const MemberExpr           * ) = 0;
    64     virtual Expr *             visit( const VariableExpr         * ) = 0;
    65     virtual Expr *             visit( const ConstantExpr         * ) = 0;
    66     virtual Expr *             visit( const SizeofExpr           * ) = 0;
    67     virtual Expr *             visit( const AlignofExpr          * ) = 0;
    68     virtual Expr *             visit( const UntypedOffsetofExpr  * ) = 0;
    69     virtual Expr *             visit( const OffsetofExpr         * ) = 0;
    70     virtual Expr *             visit( const OffsetPackExpr       * ) = 0;
    71     virtual Expr *             visit( const AttrExpr             * ) = 0;
    72     virtual Expr *             visit( const LogicalExpr          * ) = 0;
    73     virtual Expr *             visit( const ConditionalExpr      * ) = 0;
    74     virtual Expr *             visit( const CommaExpr            * ) = 0;
    75     virtual Expr *             visit( const TypeExpr             * ) = 0;
    76     virtual Expr *             visit( const AsmExpr              * ) = 0;
    77     virtual Expr *             visit( const ImplicitCopyCtorExpr * ) = 0;
    78     virtual Expr *             visit( const ConstructorExpr      * ) = 0;
    79     virtual Expr *             visit( const CompoundLiteralExpr  * ) = 0;
    80     virtual Expr *             visit( const RangeExpr            * ) = 0;
    81     virtual Expr *             visit( const UntypedTupleExpr     * ) = 0;
    82     virtual Expr *             visit( const TupleExpr            * ) = 0;
    83     virtual Expr *             visit( const TupleIndexExpr       * ) = 0;
    84     virtual Expr *             visit( const TupleAssignExpr      * ) = 0;
    85     virtual Expr *             visit( const StmtExpr             * ) = 0;
    86     virtual Expr *             visit( const UniqueExpr           * ) = 0;
    87     virtual Expr *             visit( const UntypedInitExpr      * ) = 0;
    88     virtual Expr *             visit( const InitExpr             * ) = 0;
    89     virtual Expr *             visit( const DeletedExpr          * ) = 0;
    90     virtual Expr *             visit( const DefaultArgExpr       * ) = 0;
    91     virtual Expr *             visit( const GenericExpr          * ) = 0;
    92     virtual Type *             visit( const VoidType             * ) = 0;
    93     virtual Type *             visit( const BasicType            * ) = 0;
    94     virtual Type *             visit( const PointerType          * ) = 0;
    95     virtual Type *             visit( const ArrayType            * ) = 0;
    96     virtual Type *             visit( const ReferenceType        * ) = 0;
    97     virtual Type *             visit( const QualifiedType        * ) = 0;
    98     virtual Type *             visit( const FunctionType         * ) = 0;
    99     virtual Type *             visit( const StructInstType       * ) = 0;
    100     virtual Type *             visit( const UnionInstType        * ) = 0;
    101     virtual Type *             visit( const EnumInstType         * ) = 0;
    102     virtual Type *             visit( const TraitInstType        * ) = 0;
    103     virtual Type *             visit( const TypeInstType         * ) = 0;
    104     virtual Type *             visit( const TupleType            * ) = 0;
    105     virtual Type *             visit( const TypeofType           * ) = 0;
    106     virtual Type *             visit( const VarArgsType          * ) = 0;
    107     virtual Type *             visit( const ZeroType             * ) = 0;
    108     virtual Type *             visit( const OneType              * ) = 0;
    109     virtual Type *             visit( const GlobalScopeType      * ) = 0;
    110     virtual Designation *      visit( const Designation          * ) = 0;
    111     virtual Init *             visit( const SingleInit           * ) = 0;
    112     virtual Init *             visit( const ListInit             * ) = 0;
    113     virtual Init *             visit( const ConstructorInit      * ) = 0;
    114     virtual Constant *         visit( const Constant             * ) = 0;
    115     virtual Attribute *        visit( const Attribute            * ) = 0;
    116     virtual TypeSubstitution * visit( const TypeSubstitution     * ) = 0;
     24    virtual const ast::DeclWithType *     visit( const ast::ObjectDecl           * ) = 0;
     25    virtual const ast::DeclWithType *     visit( const ast::FunctionDecl         * ) = 0;
     26    virtual const ast::Decl *             visit( const ast::StructDecl           * ) = 0;
     27    virtual const ast::Decl *             visit( const ast::UnionDecl            * ) = 0;
     28    virtual const ast::Decl *             visit( const ast::EnumDecl             * ) = 0;
     29    virtual const ast::Decl *             visit( const ast::TraitDecl            * ) = 0;
     30    virtual const ast::Decl *             visit( const ast::TypeDecl             * ) = 0;
     31    virtual const ast::Decl *             visit( const ast::TypedefDecl          * ) = 0;
     32    virtual const ast::AsmDecl *          visit( const ast::AsmDecl              * ) = 0;
     33    virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) = 0;
     34    virtual const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) = 0;
     35    virtual const ast::Stmt *             visit( const ast::ExprStmt             * ) = 0;
     36    virtual const ast::Stmt *             visit( const ast::AsmStmt              * ) = 0;
     37    virtual const ast::Stmt *             visit( const ast::DirectiveStmt        * ) = 0;
     38    virtual const ast::Stmt *             visit( const ast::IfStmt               * ) = 0;
     39    virtual const ast::Stmt *             visit( const ast::WhileStmt            * ) = 0;
     40    virtual const ast::Stmt *             visit( const ast::ForStmt              * ) = 0;
     41    virtual const ast::Stmt *             visit( const ast::SwitchStmt           * ) = 0;
     42    virtual const ast::Stmt *             visit( const ast::CaseStmt             * ) = 0;
     43    virtual const ast::Stmt *             visit( const ast::BranchStmt           * ) = 0;
     44    virtual const ast::Stmt *             visit( const ast::ReturnStmt           * ) = 0;
     45    virtual const ast::Stmt *             visit( const ast::ThrowStmt            * ) = 0;
     46    virtual const ast::Stmt *             visit( const ast::TryStmt              * ) = 0;
     47    virtual const ast::Stmt *             visit( const ast::CatchStmt            * ) = 0;
     48    virtual const ast::Stmt *             visit( const ast::FinallyStmt          * ) = 0;
     49    virtual const ast::Stmt *             visit( const ast::WaitForStmt          * ) = 0;
     50    virtual const ast::Stmt *             visit( const ast::WithStmt             * ) = 0;
     51    virtual const ast::NullStmt *         visit( const ast::NullStmt             * ) = 0;
     52    virtual const ast::Stmt *             visit( const ast::DeclStmt             * ) = 0;
     53    virtual const ast::Stmt *             visit( const ast::ImplicitCtorDtorStmt * ) = 0;
     54    virtual const ast::Expr *             visit( const ast::ApplicationExpr      * ) = 0;
     55    virtual const ast::Expr *             visit( const ast::UntypedExpr          * ) = 0;
     56    virtual const ast::Expr *             visit( const ast::NameExpr             * ) = 0;
     57    virtual const ast::Expr *             visit( const ast::AddressExpr          * ) = 0;
     58    virtual const ast::Expr *             visit( const ast::LabelAddressExpr     * ) = 0;
     59    virtual const ast::Expr *             visit( const ast::CastExpr             * ) = 0;
     60    virtual const ast::Expr *             visit( const ast::KeywordCastExpr      * ) = 0;
     61    virtual const ast::Expr *             visit( const ast::VirtualCastExpr      * ) = 0;
     62    virtual const ast::Expr *             visit( const ast::UntypedMemberExpr    * ) = 0;
     63    virtual const ast::Expr *             visit( const ast::MemberExpr           * ) = 0;
     64    virtual const ast::Expr *             visit( const ast::VariableExpr         * ) = 0;
     65    virtual const ast::Expr *             visit( const ast::ConstantExpr         * ) = 0;
     66    virtual const ast::Expr *             visit( const ast::SizeofExpr           * ) = 0;
     67    virtual const ast::Expr *             visit( const ast::AlignofExpr          * ) = 0;
     68    virtual const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * ) = 0;
     69    virtual const ast::Expr *             visit( const ast::OffsetofExpr         * ) = 0;
     70    virtual const ast::Expr *             visit( const ast::OffsetPackExpr       * ) = 0;
     71    virtual const ast::Expr *             visit( const ast::AttrExpr             * ) = 0;
     72    virtual const ast::Expr *             visit( const ast::LogicalExpr          * ) = 0;
     73    virtual const ast::Expr *             visit( const ast::ConditionalExpr      * ) = 0;
     74    virtual const ast::Expr *             visit( const ast::CommaExpr            * ) = 0;
     75    virtual const ast::Expr *             visit( const ast::TypeExpr             * ) = 0;
     76    virtual const ast::Expr *             visit( const ast::AsmExpr              * ) = 0;
     77    virtual const ast::Expr *             visit( const ast::ImplicitCopyCtorExpr * ) = 0;
     78    virtual const ast::Expr *             visit( const ast::ConstructorExpr      * ) = 0;
     79    virtual const ast::Expr *             visit( const ast::CompoundLiteralExpr  * ) = 0;
     80    virtual const ast::Expr *             visit( const ast::RangeExpr            * ) = 0;
     81    virtual const ast::Expr *             visit( const ast::UntypedTupleExpr     * ) = 0;
     82    virtual const ast::Expr *             visit( const ast::TupleExpr            * ) = 0;
     83    virtual const ast::Expr *             visit( const ast::TupleIndexExpr       * ) = 0;
     84    virtual const ast::Expr *             visit( const ast::TupleAssignExpr      * ) = 0;
     85    virtual const ast::Expr *             visit( const ast::StmtExpr             * ) = 0;
     86    virtual const ast::Expr *             visit( const ast::UniqueExpr           * ) = 0;
     87    virtual const ast::Expr *             visit( const ast::UntypedInitExpr      * ) = 0;
     88    virtual const ast::Expr *             visit( const ast::InitExpr             * ) = 0;
     89    virtual const ast::Expr *             visit( const ast::DeletedExpr          * ) = 0;
     90    virtual const ast::Expr *             visit( const ast::DefaultArgExpr       * ) = 0;
     91    virtual const ast::Expr *             visit( const ast::GenericExpr          * ) = 0;
     92    virtual const ast::Type *             visit( const ast::VoidType             * ) = 0;
     93    virtual const ast::Type *             visit( const ast::BasicType            * ) = 0;
     94    virtual const ast::Type *             visit( const ast::PointerType          * ) = 0;
     95    virtual const ast::Type *             visit( const ast::ArrayType            * ) = 0;
     96    virtual const ast::Type *             visit( const ast::ReferenceType        * ) = 0;
     97    virtual const ast::Type *             visit( const ast::QualifiedType        * ) = 0;
     98    virtual const ast::Type *             visit( const ast::FunctionType         * ) = 0;
     99    virtual const ast::Type *             visit( const ast::StructInstType       * ) = 0;
     100    virtual const ast::Type *             visit( const ast::UnionInstType        * ) = 0;
     101    virtual const ast::Type *             visit( const ast::EnumInstType         * ) = 0;
     102    virtual const ast::Type *             visit( const ast::TraitInstType        * ) = 0;
     103    virtual const ast::Type *             visit( const ast::TypeInstType         * ) = 0;
     104    virtual const ast::Type *             visit( const ast::TupleType            * ) = 0;
     105    virtual const ast::Type *             visit( const ast::TypeofType           * ) = 0;
     106    virtual const ast::Type *             visit( const ast::VarArgsType          * ) = 0;
     107    virtual const ast::Type *             visit( const ast::ZeroType             * ) = 0;
     108    virtual const ast::Type *             visit( const ast::OneType              * ) = 0;
     109    virtual const ast::Type *             visit( const ast::GlobalScopeType      * ) = 0;
     110    virtual const ast::Designation *      visit( const ast::Designation          * ) = 0;
     111    virtual const ast::Init *             visit( const ast::SingleInit           * ) = 0;
     112    virtual const ast::Init *             visit( const ast::ListInit             * ) = 0;
     113    virtual const ast::Init *             visit( const ast::ConstructorInit      * ) = 0;
     114    virtual const ast::Constant *         visit( const ast::Constant             * ) = 0;
     115    virtual const ast::Attribute *        visit( const ast::Attribute            * ) = 0;
     116    virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution     * ) = 0;
    117117};
    118118
  • src/AST/porting.md

    r9e1d485 r69bafd2  
    1010## Visitors ##
    1111* `Visitor` and `Mutator` are combined into a single `ast::Visitor` class
    12   * Base nodes now override `Node* accept( Visitor& v ) = 0` with, e.g. `Stmt* accept( Visitor& v ) override = 0`
     12  * Base nodes now override `const Node * accept( Visitor & v ) const = 0` with, e.g. `const Stmt * accept( Visitor & v ) const override = 0`
    1313* `PassVisitor` is replaced with `ast::Pass`
    1414
     
    2626`clone` is private to `Node` now
    2727* still needs to be overriden to return appropriate type
    28   * e.g. `private: virtual Stmt* clone() const override = 0;`
     28  * e.g. `private: virtual Stmt * clone() const override = 0;`
     29  * because friendship is not inherited, all implementations of clone need
     30      /// Must be copied in ALL derived classes
     31      template<typename node_t>
     32      friend auto mutate(const node_t * node);
    2933
    3034All leaves of the `Node` inheritance tree are now declared `final`
     
    170174
    171175`AttrType`
    172 * did not port due to (likely) disuse
    173   * best guess at use (from printing code) is deprecated handling for attributes
     176* did not port due to deprecation of feature
     177  * feature is `type@thing` e.g. `int@MAX`
    174178
    175179[1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes
  • src/Common/PassVisitor.h

    r9e1d485 r69bafd2  
    155155        virtual void visit( ConstructorInit * ctorInit ) override final;
    156156
    157         virtual void visit( Subrange * subrange ) override final;
    158 
    159157        virtual void visit( Constant * constant ) override final;
    160158
     
    257255        virtual Initializer * mutate( ConstructorInit * ctorInit ) override final;
    258256
    259         virtual Subrange * mutate( Subrange * subrange ) override final;
    260 
    261257        virtual Constant * mutate( Constant * constant ) override final;
    262258
  • src/Common/PassVisitor.impl.h

    r9e1d485 r69bafd2  
    27122712
    27132713//--------------------------------------------------------------------------
    2714 // Subrange
    2715 template< typename pass_type >
    2716 void PassVisitor< pass_type >::visit( Subrange * node ) {
    2717         VISIT_START( node );
    2718 
    2719         VISIT_END( node );
    2720 }
    2721 
    2722 template< typename pass_type >
    2723 Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
    2724         MUTATE_START( node );
    2725 
    2726         MUTATE_END( Subrange, node );
    2727 }
    2728 
    2729 //--------------------------------------------------------------------------
    27302714// Attribute
    27312715template< typename pass_type >
  • src/SynTree/Declaration.h

    r9e1d485 r69bafd2  
    245245        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    246246
    247   private:
    248247        Kind kind;
    249248};
     
    306305        virtual void accept( Visitor &v ) override { v.visit( this ); }
    307306        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    308   private:
    309307        DeclarationNode::Aggregate kind;
     308  private:
    310309        virtual std::string typeString() const override;
    311310};
  • src/SynTree/Label.h

    r9e1d485 r69bafd2  
    3535        operator std::string() const { return name; }
    3636        bool empty() { return name.empty(); }
    37   private:
     37
    3838        std::string name;
    3939        Statement * labelled;
  • src/SynTree/Mutator.h

    r9e1d485 r69bafd2  
    121121        virtual Initializer * mutate( ConstructorInit * ctorInit ) = 0 ;
    122122
    123         virtual Subrange * mutate( Subrange * subrange ) = 0;
    124 
    125123        virtual Constant * mutate( Constant * constant ) = 0;
    126124
  • src/SynTree/SynTree.h

    r9e1d485 r69bafd2  
    132132class ConstructorInit;
    133133
    134 class Subrange;
    135 
    136134//template <class T>    // emulate a union with templates?
    137135class Constant;
  • src/SynTree/Visitor.h

    r9e1d485 r69bafd2  
    123123        virtual void visit( ConstructorInit * ctorInit ) = 0;
    124124
    125         virtual void visit( Subrange * subrange ) = 0;
    126 
    127125        virtual void visit( Constant * constant ) = 0;
    128126
Note: See TracChangeset for help on using the changeset viewer.