Changeset a085470 for src


Ignore:
Timestamp:
Apr 10, 2023, 12:03:31 PM (2 years ago)
Author:
Mike Brooks <mlbrooks@…>
Branches:
ADT, ast-experimental, master
Children:
6adeb5f
Parents:
2b01f8e (diff), ea2759b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Location:
src
Files:
4 added
24 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r2b01f8e ra085470  
    559559                auto stmt = new SuspendStmt();
    560560                stmt->then   = get<CompoundStmt>().accept1( node->then   );
    561                 switch(node->type) {
     561                switch (node->kind) {
    562562                        case ast::SuspendStmt::None     : stmt->type = SuspendStmt::None     ; break;
    563563                        case ast::SuspendStmt::Coroutine: stmt->type = SuspendStmt::Coroutine; break;
     
    16831683                        GET_ACCEPT_V(attributes, Attribute),
    16841684                        { old->get_funcSpec().val },
    1685                         old->type->isVarArgs
     1685                        (old->type->isVarArgs) ? ast::VariableArgs : ast::FixedArgs
    16861686                };
    16871687
     
    19891989                        GET_ACCEPT_1(else_, Stmt),
    19901990                        GET_ACCEPT_V(initialization, Stmt),
    1991                         old->isDoWhile,
     1991                        (old->isDoWhile) ? ast::DoWhile : ast::While,
    19921992                        GET_LABELS_V(old->labels)
    19931993                );
     
    21312131        virtual void visit( const SuspendStmt * old ) override final {
    21322132                if ( inCache( old ) ) return;
    2133                 ast::SuspendStmt::Type type;
     2133                ast::SuspendStmt::Kind type;
    21342134                switch (old->type) {
    21352135                        case SuspendStmt::Coroutine: type = ast::SuspendStmt::Coroutine; break;
  • src/AST/Decl.cpp

    r2b01f8e ra085470  
    5757        std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    5858        CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
    59         std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
     59        std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, ArgumentFlag isVarArgs )
    6060: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ),
    6161        type_params(std::move(forall)), assertions(),
    6262        params(std::move(params)), returns(std::move(returns)), stmts( stmts ) {
    63         FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs));
     63        FunctionType * ftype = new FunctionType( isVarArgs );
    6464        for (auto & param : this->params) {
    6565                ftype->params.emplace_back(param->get_type());
     
    8181        std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    8282        CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
    83         std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
     83        std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, ArgumentFlag isVarArgs )
    8484: DeclWithType( location, name, storage, linkage, std::move(attrs), fs ),
    8585                type_params( std::move( forall) ), assertions( std::move( assertions ) ),
    8686                params( std::move(params) ), returns( std::move(returns) ),
    8787                type( nullptr ), stmts( stmts ) {
    88         FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs );
     88        FunctionType * type = new FunctionType( isVarArgs );
    8989        for ( auto & param : this->params ) {
    9090                type->params.emplace_back( param->get_type() );
  • src/AST/Decl.hpp

    r2b01f8e ra085470  
    1010// Created On       : Thu May 9 10:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Nov 24  9:44:00 2022
    13 // Update Count     : 34
     12// Last Modified On : Wed Apr  5 10:42:00 2023
     13// Update Count     : 35
    1414//
    1515
     
    122122};
    123123
     124/// Function variable arguments flag
     125enum ArgumentFlag { FixedArgs, VariableArgs };
     126
    124127/// Object declaration `int foo()`
    125128class FunctionDecl : public DeclWithType {
     
    144147                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    145148                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
    146                 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
     149                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, ArgumentFlag isVarArgs = FixedArgs );
    147150
    148151        FunctionDecl( const CodeLocation & location, const std::string & name,
     
    150153                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    151154                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
    152                 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
     155                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, ArgumentFlag isVarArgs = FixedArgs );
    153156
    154157        const Type * get_type() const override;
  • src/AST/Pass.impl.hpp

    r2b01f8e ra085470  
    20422042        if ( __visit_children() ) {
    20432043                maybe_accept( node, &TupleType::types );
    2044                 maybe_accept( node, &TupleType::members );
    20452044        }
    20462045
  • src/AST/Print.cpp

    r2b01f8e ra085470  
    739739        virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final {
    740740                os << "Suspend Statement";
    741                 switch (node->type) {
    742                         case ast::SuspendStmt::None     : os << " with implicit target"; break;
    743                         case ast::SuspendStmt::Generator: os << " for generator"; break;
    744                         case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;
     741                switch (node->kind) {
     742                case ast::SuspendStmt::None     : os << " with implicit target"; break;
     743                case ast::SuspendStmt::Generator: os << " for generator"; break;
     744                case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;
    745745                }
    746746                os << endl;
  • src/AST/Stmt.hpp

    r2b01f8e ra085470  
    1010// Created On       : Wed May  8 13:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Apr 20 14:34:00 2022
    13 // Update Count     : 36
     12// Last Modified On : Wed Apr  5 10:34:00 2023
     13// Update Count     : 37
    1414//
    1515
     
    205205};
    206206
     207// A while loop or a do-while loop:
     208enum WhileDoKind { While, DoWhile };
     209
    207210// While loop: while (...) ... else ... or do ... while (...) else ...;
    208211class WhileDoStmt final : public Stmt {
     
    212215        ptr<Stmt> else_;
    213216        std::vector<ptr<Stmt>> inits;
    214         bool isDoWhile;
     217        WhileDoKind isDoWhile;
    215218
    216219        WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body,
    217                                  const std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, const std::vector<Label> && labels = {} )
     220                                 const std::vector<ptr<Stmt>> && inits, WhileDoKind isDoWhile = While, const std::vector<Label> && labels = {} )
    218221                : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(nullptr), inits(std::move(inits)), isDoWhile(isDoWhile) {}
    219222
    220223        WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, const Stmt * else_,
    221                                  const std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, const std::vector<Label> && labels = {} )
     224                                 const std::vector<ptr<Stmt>> && inits, WhileDoKind isDoWhile = While, const std::vector<Label> && labels = {} )
    222225                : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(else_), inits(std::move(inits)), isDoWhile(isDoWhile) {}
    223226
     
    364367  public:
    365368        ptr<CompoundStmt> then;
    366         enum Type { None, Coroutine, Generator } type = None;
    367 
    368         SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, const std::vector<Label> && labels = {} )
    369                 : Stmt(loc, std::move(labels)), then(then), type(type) {}
     369        enum Kind { None, Coroutine, Generator } kind = None;
     370
     371        SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Kind kind, const std::vector<Label> && labels = {} )
     372                : Stmt(loc, std::move(labels)), then(then), kind(kind) {}
    370373
    371374        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Type.cpp

    r2b01f8e ra085470  
    1010// Created On       : Mon May 13 15:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Nov 24  9:49:00 2022
    13 // Update Count     : 6
     12// Last Modified On : Thu Apr  6 15:59:00 2023
     13// Update Count     : 7
    1414//
    1515
     
    199199
    200200TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q )
    201 : Type( q ), types( std::move(ts) ), members() {
    202         // This constructor is awkward. `TupleType` needs to contain objects so that members can be
    203         // named, but members without initializer nodes end up getting constructors, which breaks
    204         // things. This happens because the object decls have to be visited so that their types are
    205         // kept in sync with the types listed here. Ultimately, the types listed here should perhaps
    206         // be eliminated and replaced with a list-view over members. The temporary solution is to
    207         // make a `ListInit` with `maybeConstructed = false`, so when the object is visited it is not
    208         // constructed. Potential better solutions include:
    209         //   a) Separate `TupleType` from its declarations, into `TupleDecl` and `Tuple{Inst?}Type`,
    210         //      similar to the aggregate types.
    211         //   b) Separate initializer nodes better, e.g. add a `MaybeConstructed` node that is replaced
    212         //      by `genInit`, rather than the current boolean flag.
    213         members.reserve( types.size() );
    214         for ( const Type * ty : types ) {
    215                 members.emplace_back( new ObjectDecl{
    216                         CodeLocation(), "", ty, new ListInit( CodeLocation(), {}, {}, NoConstruct ),
    217                         Storage::Classes{}, Linkage::Cforall } );
    218         }
    219 }
     201: Type( q ), types( std::move(ts) ) {}
    220202
    221203bool isUnboundType(const Type * type) {
  • src/AST/Type.hpp

    r2b01f8e ra085470  
    1010// Created On       : Thu May 9 10:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Nov 24  9:47:00 2022
    13 // Update Count     : 8
     12// Last Modified On : Thu Apr  6 15:58:00 2023
     13// Update Count     : 9
    1414//
    1515
     
    265265};
    266266
    267 /// Function variable arguments flag
    268 enum ArgumentFlag { FixedArgs, VariableArgs };
    269 
    270267/// Type of a function `[R1, R2](*)(P1, P2, P3)`
    271268class FunctionType final : public Type {
     
    460457public:
    461458        std::vector<ptr<Type>> types;
    462         std::vector<ptr<Decl>> members;
    463459
    464460        TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q = {} );
  • src/Concurrency/KeywordsNew.cpp

    r2b01f8e ra085470  
    779779
    780780const ast::Stmt * SuspendKeyword::postvisit( const ast::SuspendStmt * stmt ) {
    781         switch ( stmt->type ) {
     781        switch ( stmt->kind ) {
    782782        case ast::SuspendStmt::None:
    783783                // Use the context to determain the implicit target.
  • src/Parser/DeclarationNode.cc

    r2b01f8e ra085470  
    1414//
    1515
     16#include "DeclarationNode.h"
     17
    1618#include <cassert>                 // for assert, assertf, strict_dynamic_cast
    1719#include <iterator>                // for back_insert_iterator
     
    3436#include "Common/UniqueName.h"     // for UniqueName
    3537#include "Common/utility.h"        // for maybeClone
    36 #include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
     38#include "Parser/ExpressionNode.h" // for ExpressionNode
     39#include "Parser/InitializerNode.h"// for InitializerNode
     40#include "Parser/StatementNode.h"  // for StatementNode
    3741#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    3842#include "TypedefTable.h"          // for TypedefTable
  • src/Parser/ExpressionNode.cc

    r2b01f8e ra085470  
    1313// Update Count     : 1083
    1414//
     15
     16#include "ExpressionNode.h"
    1517
    1618#include <cassert>                 // for assert
     
    2527#include "Common/SemanticError.h"  // for SemanticError
    2628#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild, CodeLo...
    27 #include "ParseNode.h"             // for ExpressionNode, maybeMoveBuildType
     29#include "DeclarationNode.h"       // for DeclarationNode
     30#include "InitializerNode.h"       // for InitializerNode
    2831#include "parserutility.h"         // for notZeroExpr
    2932
  • src/Parser/InitializerNode.cc

    r2b01f8e ra085470  
    1414//
    1515
     16#include "InitializerNode.h"
     17
    1618#include <iostream>                // for operator<<, ostream, basic_ostream
    1719#include <list>                    // for list
    1820#include <string>                  // for operator<<, string
    19 
    20 using namespace std;
    2121
    2222#include "AST/Expr.hpp"            // for Expr
     
    2424#include "Common/SemanticError.h"  // for SemanticError
    2525#include "Common/utility.h"        // for maybeBuild
    26 #include "ParseNode.h"             // for InitializerNode, ExpressionNode
     26#include "ExpressionNode.h"        // for ExpressionNode
     27#include "DeclarationNode.h"       // for buildList
     28
     29using namespace std;
    2730
    2831static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) {
  • src/Parser/ParseNode.h

    r2b01f8e ra085470  
    3838class DeclarationWithType;
    3939class Initializer;
     40class InitializerNode;
    4041class ExpressionNode;
    4142struct StatementNode;
     
    8081}; // ParseNode
    8182
    82 //##############################################################################
    83 
    84 class InitializerNode : public ParseNode {
    85   public:
    86         InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
    87         InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
    88         InitializerNode( bool isDelete );
    89         ~InitializerNode();
    90         virtual InitializerNode * clone() const { assert( false ); return nullptr; }
    91 
    92         ExpressionNode * get_expression() const { return expr; }
    93 
    94         InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
    95         ExpressionNode * get_designators() const { return designator; }
    96 
    97         InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
    98         bool get_maybeConstructed() const { return maybeConstructed; }
    99 
    100         bool get_isDelete() const { return isDelete; }
    101 
    102         InitializerNode * next_init() const { return kids; }
    103 
    104         void print( std::ostream & os, int indent = 0 ) const;
    105         void printOneLine( std::ostream & ) const;
    106 
    107         virtual ast::Init * build() const;
    108   private:
    109         ExpressionNode * expr;
    110         bool aggregate;
    111         ExpressionNode * designator;                                            // may be list
    112         InitializerNode * kids;
    113         bool maybeConstructed;
    114         bool isDelete;
    115 }; // InitializerNode
    116 
    117 //##############################################################################
    118 
    119 class ExpressionNode final : public ParseNode {
    120   public:
    121         ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {}
    122         virtual ~ExpressionNode() {}
    123         virtual ExpressionNode * clone() const override {
    124                 if ( nullptr == expr ) return nullptr;
    125                 return static_cast<ExpressionNode*>(
    126                         (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) ));
    127         }
    128 
    129         bool get_extension() const { return extension; }
    130         ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
    131 
    132         virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
    133                 os << expr.get();
    134         }
    135         void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
    136 
    137         template<typename T>
    138         bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    139 
    140         ast::Expr * build() const {
    141                 ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release();
    142                 node->set_extension( this->get_extension() );
    143                 node->location = this->location;
    144                 return node;
    145         }
    146 
    147         // Public because of lifetime implications (what lifetime implications?)
    148         std::unique_ptr<ast::Expr> expr;
    149   private:
    150         bool extension = false;
    151 }; // ExpressionNode
    152 
    15383// Must harmonize with OperName.
    15484enum class OperKinds {
     
    16999};
    170100
    171 // These 4 routines modify the string:
    172 ast::Expr * build_constantInteger( const CodeLocation &, std::string & );
    173 ast::Expr * build_constantFloat( const CodeLocation &, std::string & );
    174 ast::Expr * build_constantChar( const CodeLocation &, std::string & );
    175 ast::Expr * build_constantStr( const CodeLocation &, std::string & );
    176 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str );
    177 ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str );
    178 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str );
    179 ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts );
    180 
    181 ast::NameExpr * build_varref( const CodeLocation &, const std::string * name );
    182 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name );
    183 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name );
    184 ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name );
    185 
    186 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
    187 ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node );
    188 ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
    189 ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
    190 ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
    191 ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member );
    192 ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    193 ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag );
    194 ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node );
    195 ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    196 ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    197 ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
    198 ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr );
    199 ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node );
    200 ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids );
    201 
    202 //##############################################################################
    203 
    204 struct TypeData;
    205 
    206 struct DeclarationNode : public ParseNode {
    207         // These enumerations must harmonize with their names in DeclarationNode.cc.
    208         enum BasicType {
    209                 Void, Bool, Char, Int, Int128,
    210                 Float, Double, LongDouble, uuFloat80, uuFloat128,
    211                 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x,
    212                 NoBasicType
    213         };
    214         static const char * basicTypeNames[];
    215         enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
    216         static const char * complexTypeNames[];
    217         enum Signedness { Signed, Unsigned, NoSignedness };
    218         static const char * signednessNames[];
    219         enum Length { Short, Long, LongLong, NoLength };
    220         static const char * lengthNames[];
    221         enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
    222         static const char * builtinTypeNames[];
    223 
    224         static DeclarationNode * newStorageClass( ast::Storage::Classes );
    225         static DeclarationNode * newFuncSpecifier( ast::Function::Specs );
    226         static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );
    227         static DeclarationNode * newBasicType( BasicType );
    228         static DeclarationNode * newComplexType( ComplexType );
    229         static DeclarationNode * newSignedNess( Signedness );
    230         static DeclarationNode * newLength( Length );
    231         static DeclarationNode * newBuiltinType( BuiltinType );
    232         static DeclarationNode * newForall( DeclarationNode * );
    233         static DeclarationNode * newFromTypedef( const std::string * );
    234         static DeclarationNode * newFromGlobalScope();
    235         static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
    236         static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    237         static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    238         static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
    239         static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
    240         static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
    241         static DeclarationNode * newEnumInLine( const std::string name );
    242         static DeclarationNode * newName( const std::string * );
    243         static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
    244         static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );
    245         static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
    246         static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
    247         static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
    248         static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
    249         static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
    250         static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
    251         static DeclarationNode * newBitfield( ExpressionNode * size );
    252         static DeclarationNode * newTuple( DeclarationNode * members );
    253         static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    254         static DeclarationNode * newVtableType( DeclarationNode * expr );
    255         static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
    256         static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
    257         static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    258         static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
    259 
    260         DeclarationNode();
    261         ~DeclarationNode();
    262         DeclarationNode * clone() const override;
    263 
    264         DeclarationNode * addQualifiers( DeclarationNode * );
    265         void checkQualifiers( const TypeData *, const TypeData * );
    266         void checkSpecifiers( DeclarationNode * );
    267         DeclarationNode * copySpecifiers( DeclarationNode * );
    268         DeclarationNode * addType( DeclarationNode * );
    269         DeclarationNode * addTypedef();
    270         DeclarationNode * addEnumBase( DeclarationNode * );
    271         DeclarationNode * addAssertions( DeclarationNode * );
    272         DeclarationNode * addName( std::string * );
    273         DeclarationNode * addAsmName( DeclarationNode * );
    274         DeclarationNode * addBitfield( ExpressionNode * size );
    275         DeclarationNode * addVarArgs();
    276         DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
    277         DeclarationNode * addOldDeclList( DeclarationNode * list );
    278         DeclarationNode * setBase( TypeData * newType );
    279         DeclarationNode * copyAttribute( DeclarationNode * attr );
    280         DeclarationNode * addPointer( DeclarationNode * qualifiers );
    281         DeclarationNode * addArray( DeclarationNode * array );
    282         DeclarationNode * addNewPointer( DeclarationNode * pointer );
    283         DeclarationNode * addNewArray( DeclarationNode * array );
    284         DeclarationNode * addParamList( DeclarationNode * list );
    285         DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
    286         DeclarationNode * addInitializer( InitializerNode * init );
    287         DeclarationNode * addTypeInitializer( DeclarationNode * init );
    288 
    289         DeclarationNode * cloneType( std::string * newName );
    290         DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
    291 
    292         DeclarationNode * appendList( DeclarationNode * node ) {
    293                 return (DeclarationNode *)set_last( node );
    294         }
    295 
    296         virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    297         virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    298 
    299         ast::Decl * build() const;
    300         ast::Type * buildType() const;
    301 
    302         ast::Linkage::Spec get_linkage() const { return linkage; }
    303         DeclarationNode * extractAggregate() const;
    304         bool has_enumeratorValue() const { return (bool)enumeratorValue; }
    305         ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
    306 
    307         bool get_extension() const { return extension; }
    308         DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
    309 
    310         bool get_inLine() const { return inLine; }
    311         DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
    312 
    313         DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
    314 
    315         struct Variable_t {
    316 //              const std::string * name;
    317                 ast::TypeDecl::Kind tyClass;
    318                 DeclarationNode * assertions;
    319                 DeclarationNode * initializer;
    320         };
    321         Variable_t variable;
    322 
    323         struct StaticAssert_t {
    324                 ExpressionNode * condition;
    325                 ast::Expr * message;
    326         };
    327         StaticAssert_t assert;
    328 
    329         BuiltinType builtin = NoBuiltinType;
    330 
    331         TypeData * type = nullptr;
    332 
    333         bool inLine = false;
    334         bool enumInLine = false;
    335         ast::Function::Specs funcSpecs;
    336         ast::Storage::Classes storageClasses;
    337 
    338         ExpressionNode * bitfieldWidth = nullptr;
    339         std::unique_ptr<ExpressionNode> enumeratorValue;
    340         bool hasEllipsis = false;
    341         ast::Linkage::Spec linkage;
    342         ast::Expr * asmName = nullptr;
    343         std::vector<ast::ptr<ast::Attribute>> attributes;
    344         InitializerNode * initializer = nullptr;
    345         bool extension = false;
    346         std::string error;
    347         StatementNode * asmStmt = nullptr;
    348         StatementNode * directiveStmt = nullptr;
    349 
    350         static UniqueName anonymous;
    351 }; // DeclarationNode
    352 
    353 ast::Type * buildType( TypeData * type );
    354 
    355 static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {
    356         ast::Type * ret = orig ? orig->buildType() : nullptr;
    357         delete orig;
    358         return ret;
    359 }
    360 
    361 //##############################################################################
    362 
    363 struct StatementNode final : public ParseNode {
    364         StatementNode() :
    365                 stmt( nullptr ), clause( nullptr ) {}
    366         StatementNode( ast::Stmt * stmt ) :
    367                 stmt( stmt ), clause( nullptr ) {}
    368         StatementNode( ast::StmtClause * clause ) :
    369                 stmt( nullptr ), clause( clause ) {}
    370         StatementNode( DeclarationNode * decl );
    371         virtual ~StatementNode() {}
    372 
    373         virtual StatementNode * clone() const final { assert( false ); return nullptr; }
    374         ast::Stmt * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
    375 
    376         virtual StatementNode * add_label(
    377                         const CodeLocation & location,
    378                         const std::string * name,
    379                         DeclarationNode * attr = nullptr ) {
    380                 stmt->labels.emplace_back( location,
    381                         *name,
    382                         attr ? std::move( attr->attributes )
    383                                 : std::vector<ast::ptr<ast::Attribute>>{} );
    384                 delete attr;
    385                 delete name;
    386                 return this;
    387         }
    388 
    389         virtual StatementNode * append_last_case( StatementNode * );
    390 
    391         virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
    392                 os << stmt.get() << std::endl;
    393         }
    394 
    395         std::unique_ptr<ast::Stmt> stmt;
    396         std::unique_ptr<ast::StmtClause> clause;
    397 }; // StatementNode
    398 
    399 ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl );
    400 
    401 struct CondCtl {
    402         CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
    403                 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
    404 
    405         StatementNode * init;
    406         ExpressionNode * condition;
    407 };
    408 
    409 struct ForCtrl {
    410         ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
    411                 init( stmt ), condition( condition ), change( change ) {}
    412 
    413         StatementNode * init;
    414         ExpressionNode * condition;
    415         ExpressionNode * change;
    416 };
    417 
    418 ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ );
    419 ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
    420 ast::CaseClause * build_case( ExpressionNode * ctl );
    421 ast::CaseClause * build_default( const CodeLocation & );
    422 ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    423 ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    424 ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    425 ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind );
    426 ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind );
    427 ast::Stmt * build_computedgoto( ExpressionNode * ctl );
    428 ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl );
    429 ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl );
    430 ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl );
    431 ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
    432 ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
    433 ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
    434 ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt );
    435 ast::Stmt * build_compound( const CodeLocation &, StatementNode * first );
    436 StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first );
    437 ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    438 ast::Stmt * build_directive( const CodeLocation &, std::string * directive );
    439 ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Type );
    440 ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
    441 ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
    442 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
    443 ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
    444 ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
    445 
    446 //##############################################################################
    447 
    448 template<typename AstType, typename NodeType,
    449         template<typename, typename...> class Container, typename... Args>
    450 void buildList( const NodeType * firstNode,
    451                 Container<ast::ptr<AstType>, Args...> & output ) {
    452         SemanticErrorException errors;
    453         std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );
    454         const NodeType * cur = firstNode;
    455 
    456         while ( cur ) {
    457                 try {
    458                         if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) {
    459                                 *out++ = result;
    460                         } else {
    461                                 assertf(false, __PRETTY_FUNCTION__ );
    462                                 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
    463                         } // if
    464                 } catch( SemanticErrorException & e ) {
    465                         errors.append( e );
    466                 } // try
    467                 const ParseNode * temp = cur->get_next();
    468                 // Should not return nullptr, then it is non-homogeneous:
    469                 cur = dynamic_cast<const NodeType *>( temp );
    470                 if ( !cur && temp ) {
    471                         SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
    472                 } // if
    473         } // while
    474         if ( ! errors.isEmpty() ) {
    475                 throw errors;
    476         } // if
    477 }
    478 
    479 // in DeclarationNode.cc
    480 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList );
    481 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList );
    482 void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );
    483 
    484 template<typename AstType, typename NodeType,
    485         template<typename, typename...> class Container, typename... Args>
    486 void buildMoveList( const NodeType * firstNode,
    487                 Container<ast::ptr<AstType>, Args...> & output ) {
    488         buildList<AstType, NodeType, Container, Args...>( firstNode, output );
    489         delete firstNode;
    490 }
    491 
    492 // in ParseNode.cc
    493101std::ostream & operator<<( std::ostream & out, const ParseNode * node );
    494102
  • src/Parser/RunParser.cpp

    r2b01f8e ra085470  
    2020#include "CodeTools/TrackLoc.h"             // for fillLocations
    2121#include "Common/CodeLocationTools.hpp"     // for forceFillCodeLocations
    22 #include "Parser/ParseNode.h"               // for DeclarationNode, buildList
     22#include "Parser/DeclarationNode.h"         // for DeclarationNode, buildList
    2323#include "Parser/TypedefTable.h"            // for TypedefTable
    2424
  • src/Parser/StatementNode.cc

    r2b01f8e ra085470  
    1515//
    1616
     17#include "StatementNode.h"
     18
    1719#include <cassert>                 // for assert, strict_dynamic_cast, assertf
    1820#include <memory>                  // for unique_ptr
     
    2325#include "Common/SemanticError.h"  // for SemanticError
    2426#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
    25 #include "ParseNode.h"             // for StatementNode, ExpressionNode, bui...
     27#include "DeclarationNode.h"       // for DeclarationNode
     28#include "ExpressionNode.h"        // for ExpressionNode
    2629#include "parserutility.h"         // for notZeroExpr
    2730
     
    5255        stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
    5356} // StatementNode::StatementNode
     57
     58StatementNode * StatementNode::add_label(
     59                const CodeLocation & location,
     60                const std::string * name,
     61                DeclarationNode * attr ) {
     62        stmt->labels.emplace_back( location,
     63                *name,
     64                attr ? std::move( attr->attributes )
     65                        : std::vector<ast::ptr<ast::Attribute>>{} );
     66        delete attr;
     67        delete name;
     68        return this;
     69}
    5470
    5571StatementNode * StatementNode::append_last_case( StatementNode * stmt ) {
     
    218234                astelse.empty() ? nullptr : astelse.front().release(),
    219235                std::move( astinit ),
    220                 false
     236                ast::While
    221237        );
    222238} // build_while
     
    237253                astelse.empty() ? nullptr : astelse.front().release(),
    238254                {},
    239                 true
     255                ast::DoWhile
    240256        );
    241257} // build_do_while
     
    362378} // build_finally
    363379
    364 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) {
     380ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) {
    365381        std::vector<ast::ptr<ast::Stmt>> stmts;
    366382        buildMoveList( then, stmts );
     
    370386                then2 = stmts.front().strict_as<ast::CompoundStmt>();
    371387        }
    372         auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None );
    373         node->type = type;
    374         return node;
     388        return new ast::SuspendStmt( location, then2, kind );
    375389} // build_suspend
    376390
  • src/Parser/TypeData.cc

    r2b01f8e ra085470  
    2424#include "Common/SemanticError.h"  // for SemanticError
    2525#include "Common/utility.h"        // for splice, spliceBegin
    26 #include "Parser/parserutility.h"  // for maybeCopy, maybeBuild, maybeMoveB...
    27 #include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
     26#include "Parser/ExpressionNode.h" // for ExpressionNode
     27#include "Parser/StatementNode.h"  // for StatementNode
    2828
    2929class Attribute;
     
    13971397                std::move( attributes ),
    13981398                funcSpec,
    1399                 isVarArgs
     1399                (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
    14001400        );
    14011401        buildList( td->function.withExprs, decl->withExprs );
  • src/Parser/TypeData.h

    r2b01f8e ra085470  
    1616#pragma once
    1717
    18 #include <iosfwd>                                                                               // for ostream
    19 #include <list>                                                                                 // for list
    20 #include <string>                                                                               // for string
     18#include <iosfwd>                                   // for ostream
     19#include <list>                                     // for list
     20#include <string>                                   // for string
    2121
    22 #include "AST/Type.hpp"                                                                 // for Type
    23 #include "ParseNode.h"                                                                  // for DeclarationNode, DeclarationNode::Ag...
     22#include "AST/Type.hpp"                             // for Type
     23#include "DeclarationNode.h"                        // for DeclarationNode
    2424
    2525struct TypeData {
  • src/Parser/TypedefTable.cc

    r2b01f8e ra085470  
    1616
    1717#include "TypedefTable.h"
    18 #include <cassert>                                                                              // for assert
    19 #include <iostream>
     18
     19#include <cassert>                                // for assert
     20#include <string>                                 // for string
     21#include <iostream>                               // for iostream
     22
     23#include "ExpressionNode.h"                       // for LabelNode
     24#include "ParserTypes.h"                          // for Token
     25#include "StatementNode.h"                        // for CondCtl, ForCtrl
     26// This (generated) header must come late as it is missing includes.
     27#include "parser.hh"              // for IDENTIFIER, TYPEDEFname, TYPEGENname
     28
    2029using namespace std;
    2130
    2231#if 0
    2332#define debugPrint( code ) code
     33
     34static const char *kindName( int kind ) {
     35        switch ( kind ) {
     36        case IDENTIFIER: return "identifier";
     37        case TYPEDIMname: return "typedim";
     38        case TYPEDEFname: return "typedef";
     39        case TYPEGENname: return "typegen";
     40        default:
     41                cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
     42                abort();
     43        } // switch
     44} // kindName
    2445#else
    2546#define debugPrint( code )
    2647#endif
    27 
    28 using namespace std;                                                                    // string, iostream
    29 
    30 debugPrint(
    31         static const char *kindName( int kind ) {
    32                 switch ( kind ) {
    33                 case IDENTIFIER: return "identifier";
    34                 case TYPEDIMname: return "typedim";
    35                 case TYPEDEFname: return "typedef";
    36                 case TYPEGENname: return "typegen";
    37                 default:
    38                         cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
    39                         abort();
    40                 } // switch
    41         } // kindName
    42 );
    4348
    4449TypedefTable::~TypedefTable() {
     
    7883                typedefTable.addToEnclosingScope( name, kind, "MTD" );
    7984        } // if
     85} // TypedefTable::makeTypedef
     86
     87void TypedefTable::makeTypedef( const string & name ) {
     88        return makeTypedef( name, TYPEDEFname );
    8089} // TypedefTable::makeTypedef
    8190
  • src/Parser/TypedefTable.h

    r2b01f8e ra085470  
    1919
    2020#include "Common/ScopedMap.h"                                                   // for ScopedMap
    21 #include "ParserTypes.h"
    22 #include "parser.hh"                                                                    // for IDENTIFIER, TYPEDEFname, TYPEGENname
    2321
    2422class TypedefTable {
    2523        struct Note { size_t level; bool forall; };
    2624        typedef ScopedMap< std::string, int, Note > KindTable;
    27         KindTable kindTable;   
     25        KindTable kindTable;
    2826        unsigned int level = 0;
    2927  public:
     
    3331        bool existsCurr( const std::string & identifier ) const;
    3432        int isKind( const std::string & identifier ) const;
    35         void makeTypedef( const std::string & name, int kind = TYPEDEFname );
     33        void makeTypedef( const std::string & name, int kind );
     34        void makeTypedef( const std::string & name );
    3635        void addToScope( const std::string & identifier, int kind, const char * );
    3736        void addToEnclosingScope( const std::string & identifier, int kind, const char * );
  • src/Parser/lex.ll

    r2b01f8e ra085470  
    4444
    4545#include "config.h"                                                                             // configure info
     46#include "DeclarationNode.h"                            // for DeclarationNode
     47#include "ExpressionNode.h"                             // for LabelNode
     48#include "InitializerNode.h"                            // for InitializerNode
    4649#include "ParseNode.h"
     50#include "ParserTypes.h"                                // for Token
     51#include "StatementNode.h"                              // for CondCtl, ForCtrl
    4752#include "TypedefTable.h"
     53// This (generated) header must come late as it is missing includes.
     54#include "parser.hh"                                    // generated info
    4855
    4956string * build_postfix_name( string * name );
  • src/Parser/module.mk

    r2b01f8e ra085470  
    2121SRC += \
    2222       Parser/DeclarationNode.cc \
     23       Parser/DeclarationNode.h \
    2324       Parser/ExpressionNode.cc \
     25       Parser/ExpressionNode.h \
    2426       Parser/InitializerNode.cc \
     27       Parser/InitializerNode.h \
    2528       Parser/lex.ll \
    2629       Parser/ParseNode.cc \
     
    3336       Parser/RunParser.hpp \
    3437       Parser/StatementNode.cc \
     38       Parser/StatementNode.h \
    3539       Parser/TypeData.cc \
    3640       Parser/TypeData.h \
  • src/Parser/parser.yy

    r2b01f8e ra085470  
    4848using namespace std;
    4949
    50 #include "SynTree/Declaration.h"
    51 #include "ParseNode.h"
     50#include "SynTree/Type.h"                               // for Type
     51#include "DeclarationNode.h"                            // for DeclarationNode, ...
     52#include "ExpressionNode.h"                             // for ExpressionNode, ...
     53#include "InitializerNode.h"                            // for InitializerNode, ...
     54#include "ParserTypes.h"
     55#include "StatementNode.h"                              // for build_...
    5256#include "TypedefTable.h"
    5357#include "TypeData.h"
    54 #include "SynTree/LinkageSpec.h"
    5558#include "Common/SemanticError.h"                                               // error_str
    5659#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
  • src/ResolvExpr/CurrentObject.cc

    r2b01f8e ra085470  
    99// Author           : Rob Schluntz
    1010// Created On       : Tue Jun 13 15:28:32 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  1 09:16:01 2022
    13 // Update Count     : 15
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Apr 10  9:40:00 2023
     13// Update Count     : 18
    1414//
    1515
     
    593593
    594594namespace ast {
     595        /// Iterates members of a type by initializer.
     596        class MemberIterator {
     597        public:
     598                virtual ~MemberIterator() {}
     599
     600                /// Internal set position based on iterator ranges.
     601                virtual void setPosition(
     602                        std::deque< ptr< Expr > >::const_iterator it,
     603                        std::deque< ptr< Expr > >::const_iterator end ) = 0;
     604
     605                /// Walks the current object using the given designators as a guide.
     606                void setPosition( const std::deque< ptr< Expr > > & designators ) {
     607                        setPosition( designators.begin(), designators.end() );
     608                }
     609
     610                /// Retrieve the list of possible (Type,Designation) pairs for the
     611                /// current position in the current object.
     612                virtual std::deque< InitAlternative > operator* () const = 0;
     613
     614                /// True if the iterator is not currently at the end.
     615                virtual operator bool() const = 0;
     616
     617                /// Moves the iterator by one member in the current object.
     618                virtual MemberIterator & bigStep() = 0;
     619
     620                /// Moves the iterator by one member in the current subobject.
     621                virtual MemberIterator & smallStep() = 0;
     622
     623                /// The type of the current object.
     624                virtual const Type * getType() = 0;
     625
     626                /// The type of the current subobject.
     627                virtual const Type * getNext() = 0;
     628
     629                /// Helper for operator*; aggregates must add designator to each init
     630                /// alternative, but adding designators in operator* creates duplicates.
     631                virtual std::deque< InitAlternative > first() const = 0;
     632        };
     633
    595634        /// create a new MemberIterator that traverses a type correctly
    596635        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type );
     
    684723
    685724                void setPosition(
    686                         std::deque< ptr< Expr > >::const_iterator begin,
    687                         std::deque< ptr< Expr > >::const_iterator end
     725                        std::deque<ast::ptr<ast::Expr>>::const_iterator begin,
     726                        std::deque<ast::ptr<ast::Expr>>::const_iterator end
    688727                ) override {
    689728                        if ( begin == end ) return;
     
    898937        };
    899938
    900         class TupleIterator final : public AggregateIterator {
    901         public:
    902                 TupleIterator( const CodeLocation & loc, const TupleType * inst )
    903                 : AggregateIterator(
    904                         loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members
    905                 ) {}
     939        /// Iterates across the positions in a tuple:
     940        class TupleIterator final : public MemberIterator {
     941                CodeLocation location;
     942                ast::TupleType const * const tuple;
     943                size_t index = 0;
     944                size_t size = 0;
     945                std::unique_ptr<MemberIterator> sub_iter;
     946
     947                const ast::Type * typeAtIndex() const {
     948                        assert( index < size );
     949                        return tuple->types[ index ].get();
     950                }
     951
     952        public:
     953                TupleIterator( const CodeLocation & loc, const TupleType * type )
     954                : location( loc ), tuple( type ), size( type->size() ) {
     955                        PRINT( std::cerr << "Creating tuple iterator: " << type << std::endl; )
     956                        sub_iter.reset( createMemberIterator( loc, typeAtIndex() ) );
     957                }
     958
     959                void setPosition( const ast::Expr * expr ) {
     960                        auto arg = eval( expr );
     961                        index = arg.first;
     962                }
     963
     964                void setPosition(
     965                                std::deque< ptr< Expr > >::const_iterator begin,
     966                                std::deque< ptr< Expr > >::const_iterator end ) {
     967                        if ( begin == end ) return;
     968
     969                        setPosition( *begin );
     970                        sub_iter->setPosition( ++begin, end );
     971                }
     972
     973                std::deque< InitAlternative > operator*() const override {
     974                        return first();
     975                }
    906976
    907977                operator bool() const override {
    908                         return curMember != members.end() || (memberIter && *memberIter);
     978                        return index < size;
    909979                }
    910980
    911981                TupleIterator & bigStep() override {
    912                         PRINT( std::cerr << "bigStep in " << kind << std::endl; )
    913                         atbegin = false;
    914                         memberIter = nullptr;
    915                         curType = nullptr;
    916                         while ( curMember != members.end() ) {
    917                                 ++curMember;
    918                                 if ( init() ) return *this;
    919                         }
     982                        ++index;
     983                        sub_iter.reset( index < size ?
     984                                createMemberIterator( location, typeAtIndex() ) : nullptr );
    920985                        return *this;
     986                }
     987
     988                TupleIterator & smallStep() override {
     989                        if ( sub_iter ) {
     990                                PRINT( std::cerr << "has member iter: " << *sub_iter << std::endl; )
     991                                sub_iter->smallStep();
     992                                if ( !sub_iter ) {
     993                                        PRINT( std::cerr << "has valid member iter" << std::endl; )
     994                                        return *this;
     995                                }
     996                        }
     997                        return bigStep();
     998                }
     999
     1000                const ast::Type * getType() override {
     1001                        return tuple;
     1002                }
     1003
     1004                const ast::Type * getNext() override {
     1005                        return ( sub_iter && *sub_iter ) ? sub_iter->getType() : nullptr;
     1006                }
     1007
     1008                std::deque< InitAlternative > first() const override {
     1009                        PRINT( std::cerr << "first in TupleIterator (" << index << "/" << size << ")" << std::endl; )
     1010                        if ( sub_iter && *sub_iter ) {
     1011                                std::deque< InitAlternative > ret = sub_iter->first();
     1012                                for ( InitAlternative & alt : ret ) {
     1013                                        alt.designation.get_and_mutate()->designators.emplace_front(
     1014                                                ConstantExpr::from_ulong( location, index ) );
     1015                                }
     1016                                return ret;
     1017                        }
     1018                        return {};
    9211019                }
    9221020        };
  • src/ResolvExpr/CurrentObject.h

    r2b01f8e ra085470  
    99// Author           : Rob Schluntz
    1010// Created On       : Thu Jun  8 11:07:25 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:36:48 2017
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Apr  6 16:14:00 2023
     13// Update Count     : 4
    1414//
    1515
     
    6565
    6666        /// Iterates members of a type by initializer
    67         class MemberIterator {
    68         public:
    69                 virtual ~MemberIterator() {}
    70 
    71                 /// Internal set position based on iterator ranges
    72                 virtual void setPosition(
    73                         std::deque< ptr< Expr > >::const_iterator it,
    74                         std::deque< ptr< Expr > >::const_iterator end ) = 0;
    75 
    76                 /// walks the current object using the given designators as a guide
    77                 void setPosition( const std::deque< ptr< Expr > > & designators ) {
    78                         setPosition( designators.begin(), designators.end() );
    79                 }
    80 
    81                 /// retrieve the list of possible (Type,Designation) pairs for the current position in the
    82                 /// current object
    83                 virtual std::deque< InitAlternative > operator* () const = 0;
    84 
    85                 /// true if the iterator is not currently at the end
    86                 virtual operator bool() const = 0;
    87 
    88                 /// moves the iterator by one member in the current object
    89                 virtual MemberIterator & bigStep() = 0;
    90 
    91                 /// moves the iterator by one member in the current subobject
    92                 virtual MemberIterator & smallStep() = 0;
    93 
    94                 /// the type of the current object
    95                 virtual const Type * getType() = 0;
    96 
    97                 /// the type of the current subobject
    98                 virtual const Type * getNext() = 0;
    99        
    100                 /// helper for operator*; aggregates must add designator to each init alternative, but
    101                 /// adding designators in operator* creates duplicates
    102                 virtual std::deque< InitAlternative > first() const = 0;
    103         };
     67        class MemberIterator;
    10468
    10569        /// Builds initializer lists in resolution
Note: See TracChangeset for help on using the changeset viewer.