Changeset df6cc9d for src


Ignore:
Timestamp:
Oct 19, 2022, 4:43:26 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master
Children:
1a45263
Parents:
9cd5bd2 (diff), 135143ba (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' into pthread-emulation

Location:
src
Files:
1 added
48 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r9cd5bd2 rdf6cc9d  
    310310                        node->name,
    311311                        get<Attribute>().acceptL( node->attributes ),
    312                         false, // Temporary
     312                        node->isTyped,
    313313                        LinkageSpec::Spec( node->linkage.val ),
    314314                        get<Type>().accept1(node->base)
    315315                );
    316                 return aggregatePostamble( decl, node ); // Node info, including members, processed in aggregatePostamble
     316                return aggregatePostamble( decl, node );
    317317        }
    318318
     
    737737                                node->name
    738738                );
    739                 temp->var = get<DeclarationWithType>().accept1(node->var);
    740739                auto expr = visitBaseExpr( node,
    741740                        temp
     
    16151614                        { old->get_funcSpec().val }
    16161615                );
     1616                decl->enumInLine = old->enumInLine;
    16171617                cache.emplace(old, decl);
    16181618                assert(cache.find( old ) != cache.end());
     
    22812281        }
    22822282
    2283         /// xxx - type_decl should be DeclWithType in the final design
    2284         /// type_decl is set to EnumDecl as a temporary fix
    22852283        virtual void visit( const QualifiedNameExpr * old ) override final {
    22862284                this->node = visitBaseExpr( old,
     
    22882286                                old->location,
    22892287                                GET_ACCEPT_1(type_decl, Decl),
    2290                                 GET_ACCEPT_1(var, DeclWithType),
    22912288                                old->name
    22922289                        )
  • src/AST/Decl.cpp

    r9cd5bd2 rdf6cc9d  
    5858        CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
    5959        std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
    60 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
    61         type_params(std::move(forall)), stmts( stmts ) {
     60: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ),
     61        type_params(std::move(forall)), assertions(),
     62        params(std::move(params)), returns(std::move(returns)), stmts( stmts ) {
    6263        FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs));
    6364        for (auto & param : this->params) {
     
    8283        std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
    8384: DeclWithType( location, name, storage, linkage, std::move(attrs), fs ),
     85                type_params( std::move( forall) ), assertions( std::move( assertions ) ),
    8486                params( std::move(params) ), returns( std::move(returns) ),
    85                 type_params( std::move( forall) ), assertions( std::move( assertions ) ),
    8687                type( nullptr ), stmts( stmts ) {
    8788        FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs );
     
    162163
    163164        auto it = enumValues.find( enumerator->name );
    164        
     165
    165166        if ( it != enumValues.end() ) {
    166                        
     167
    167168                // Handle typed enum by casting the value in (C++) compiler
    168169                // if ( base ) { // A typed enum
     
    179180                //                      case BasicType::Kind::LongUnsignedInt: value = (long unsigned int) it->second; break;
    180181                //                      case BasicType::Kind::LongLongSignedInt: value = (long long signed int) it->second; break;
    181                 //                      case BasicType::Kind::LongLongUnsignedInt: value = (long long unsigned int) it->second; break; 
     182                //                      case BasicType::Kind::LongLongUnsignedInt: value = (long long unsigned int) it->second; break;
    182183                //                      // TODO: value should be able to handle long long unsigned int
    183184
  • src/AST/Decl.hpp

    r9cd5bd2 rdf6cc9d  
    105105        ptr<Init> init;
    106106        ptr<Expr> bitfieldWidth;
     107        bool enumInLine = false; // enum inline is not a real object declaration.
     108        // It is a place holder for a set of enum value (ObjectDecl)
     109        bool importValue = false; // if the value copied from somewhere else
    107110
    108111        ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
     
    125128class FunctionDecl : public DeclWithType {
    126129public:
     130        std::vector<ptr<TypeDecl>> type_params;
     131        std::vector<ptr<DeclWithType>> assertions;
    127132        std::vector<ptr<DeclWithType>> params;
    128133        std::vector<ptr<DeclWithType>> returns;
    129         std::vector<ptr<TypeDecl>> type_params;
    130         std::vector<ptr<DeclWithType>> assertions;
    131134        // declared type, derived from parameter declarations
    132135        ptr<FunctionType> type;
     
    312315class EnumDecl final : public AggregateDecl {
    313316public:
    314         bool isTyped;
    315         ptr<Type> base;
     317        bool isTyped; // isTyped indicated if the enum has a declaration like:
     318        // enum (type_optional) Name {...}
     319        ptr<Type> base; // if isTyped == true && base.get() == nullptr, it is a "void" type enum
    316320
    317321        EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
  • src/AST/Expr.cpp

    r9cd5bd2 rdf6cc9d  
    2222#include "Copy.hpp"                // for shallowCopy
    2323#include "GenericSubstitution.hpp"
     24#include "Inspect.hpp"
    2425#include "LinkageSpec.hpp"
    2526#include "Stmt.hpp"
     
    2930#include "Common/SemanticError.h"
    3031#include "GenPoly/Lvalue.h"        // for referencesPermissable
    31 #include "InitTweak/InitTweak.h"   // for getFunction, getPointerBase
    3232#include "ResolvExpr/typeops.h"    // for extractResultType
    3333#include "Tuples/Tuples.h"         // for makeTupleType
     
    5858
    5959bool ApplicationExpr::get_lvalue() const {
    60         if ( const DeclWithType * func = InitTweak::getFunction( this ) ) {
     60        if ( const DeclWithType * func = getFunction( this ) ) {
    6161                return func->linkage == Linkage::Intrinsic && lvalueFunctionNames.count( func->name );
    6262        }
     
    6767
    6868bool UntypedExpr::get_lvalue() const {
    69         std::string fname = InitTweak::getFunctionName( this );
     69        std::string fname = getFunctionName( this );
    7070        return lvalueFunctionNames.count( fname );
    7171}
     
    7676        UntypedExpr * ret = createCall( loc, "*?", { arg } );
    7777        if ( const Type * ty = arg->result ) {
    78                 const Type * base = InitTweak::getPointerBase( ty );
     78                const Type * base = getPointerBase( ty );
    7979                assertf( base, "expected pointer type in dereference (type was %s)", toString( ty ).c_str() );
    8080
     
    335335        // first argument
    336336        assert( callExpr );
    337         const Expr * arg = InitTweak::getCallArg( callExpr, 0 );
     337        const Expr * arg = getCallArg( callExpr, 0 );
    338338        assert( arg );
    339339        result = arg->result;
  • src/AST/Expr.hpp

    r9cd5bd2 rdf6cc9d  
    257257public:
    258258        ptr<Decl> type_decl;
    259         ptr<DeclWithType> var;
    260259        std::string name;
    261260
    262         QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const DeclWithType * r, const std::string & n )
    263         : Expr( loc ), type_decl( d ), var(r), name( n ) {}
     261        QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const std::string & n )
     262        : Expr( loc ), type_decl( d ), name( n ) {}
    264263
    265264        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Inspect.cpp

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Fri Jun 24 13:16:31 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 27 15:35:00 2022
    13 // Update Count     : 1
     12// Last Modified On : Mon Oct  3 11:04:00 2022
     13// Update Count     : 3
    1414//
    1515
    16 #include "AST/Decl.hpp"
    17 #include "AST/Type.hpp"
     16#include "Inspect.hpp"
    1817
    1918#include <iostream>
    20 #include <AST/Print.hpp>
     19#include <iterator>
     20
     21#include "AST/Decl.hpp"
     22#include "AST/Expr.hpp"
     23#include "AST/Print.hpp"
     24#include "AST/Stmt.hpp"
     25#include "AST/Type.hpp"
     26#include "CodeGen/OperatorTable.h"
    2127
    2228namespace ast {
     29
     30const Type * getPointerBase( const Type * type ) {
     31        if ( const auto * p = dynamic_cast< const PointerType * >( type ) ) {
     32                return p->base;
     33        } else if ( auto a = dynamic_cast< const ArrayType * >( type ) ) {
     34                return a->base;
     35        } else if ( auto r = dynamic_cast< const ReferenceType * >( type ) ) {
     36                return r->base;
     37        } else {
     38                return nullptr;
     39        }
     40}
     41
     42template<typename CallExpr, typename Ret>
     43static Ret throughDeref( const CallExpr * expr, Ret(*func)( const Expr * ) ) {
     44        // In `(*f)(x)` the function we want is `f`.
     45        std::string name = getFunctionName( expr );
     46        assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
     47        assertf( !expr->args.empty(), "Cannot pass through dereference with no arguments." );
     48        return func( expr->args.front() );
     49}
     50
     51static const DeclWithType * getCalledFunction( const Expr * expr ) {
     52        assert( expr );
     53        if ( const auto * varExpr = dynamic_cast< const VariableExpr * >( expr ) ) {
     54                return varExpr->var;
     55        } else if ( auto memberExpr = dynamic_cast< const MemberExpr * >( expr ) ) {
     56                return memberExpr->member;
     57        } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) {
     58                return getCalledFunction( castExpr->arg );
     59        } else if ( auto untypedExpr = dynamic_cast< const UntypedExpr * >( expr ) ) {
     60                return throughDeref( untypedExpr, getCalledFunction );
     61        } else if ( auto appExpr = dynamic_cast< const ApplicationExpr * > ( expr ) ) {
     62                return throughDeref( appExpr, getCalledFunction );
     63        } else if ( auto addrExpr = dynamic_cast< const AddressExpr * >( expr ) ) {
     64                return getCalledFunction( addrExpr->arg );
     65        } else if ( auto commaExpr = dynamic_cast< const CommaExpr * >( expr ) ) {
     66                return getCalledFunction( commaExpr->arg2 );
     67        } else {
     68                return nullptr;
     69        }
     70}
     71
     72const DeclWithType * getFunction( const Expr * expr ) {
     73        if ( auto app = dynamic_cast< const ApplicationExpr * >( expr ) ) {
     74                return getCalledFunction( app->func );
     75        } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( expr ) ) {
     76                return getCalledFunction( untyped->func );
     77        } else {
     78                assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
     79        }
     80}
     81
     82// There is a lot of overlap with getCalledFunction. Ideally it would use
     83// it as a helper function and return the name of the DeclWithType. But the
     84// NameExpr and UntypedMemberExpr only work on this version.
     85static std::string funcName( const Expr * func ) {
     86        assert( func );
     87        if ( const auto * nameExpr = dynamic_cast< const NameExpr * >( func ) ) {
     88                return nameExpr->name;
     89        } else if ( auto varExpr = dynamic_cast< const VariableExpr * >( func ) ) {
     90                return varExpr->var->name;
     91        } else if ( auto castExpr = dynamic_cast< const CastExpr * >( func ) ) {
     92                return funcName( castExpr->arg );
     93        } else if ( auto memberExpr = dynamic_cast< const MemberExpr * >( func ) ) {
     94                return memberExpr->member->name;
     95        } else if ( auto memberExpr = dynamic_cast< const UntypedMemberExpr * >( func ) ) {
     96                return funcName( memberExpr->member );
     97        } else if ( auto untypedExpr = dynamic_cast< const UntypedExpr * >( func ) ) {
     98                return throughDeref( untypedExpr, funcName );
     99        } else if ( auto appExpr = dynamic_cast< const ApplicationExpr * >( func ) ) {
     100                return throughDeref( appExpr, funcName );
     101        } else if ( auto ctorExpr = dynamic_cast< const ConstructorExpr * >( func ) ) {
     102                return funcName( getCallArg( ctorExpr->callExpr, 0 ) );
     103        } else {
     104                assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );
     105        }
     106}
     107
     108std::string getFunctionName( const Expr * expr ) {
     109        // There's some unforunate overlap here with getFunction. See above.
     110        if ( auto app = dynamic_cast< const ApplicationExpr * >( expr ) ) {
     111                return funcName( app->func );
     112        } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( expr ) ) {
     113                return funcName( untyped->func );
     114        } else {
     115                assertf( false, "getFunctionName received unknown expression: %s", toString( expr ).c_str() );
     116        }
     117}
     118
     119template<typename CallExpr>
     120static const Expr * callArg( const CallExpr * call, unsigned int pos ) {
     121        assertf( pos < call->args.size(),
     122                "callArg for argument that doesn't exist: (%u); %s.",
     123                pos, toString( call ).c_str() );
     124        auto it = call->args.begin();
     125        std::advance( it, pos );
     126        return *it;
     127}
     128
     129const Expr * getCallArg( const Expr * call, unsigned int pos ) {
     130        if ( auto app = dynamic_cast< const ApplicationExpr * >( call ) ) {
     131                return callArg( app, pos );
     132        } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( call ) ) {
     133                return callArg( untyped, pos );
     134        } else if ( auto tupleAssn = dynamic_cast< const TupleAssignExpr * >( call ) ) {
     135                const std::list<ptr<Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids;
     136                assertf( !stmts.empty(), "TupleAssignExpr missing statements." );
     137                auto stmt  = stmts.back().strict_as< ExprStmt >();
     138                auto tuple = stmt->expr.strict_as< TupleExpr >();
     139                assertf( !tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr." );
     140                return getCallArg( tuple->exprs.front(), pos );
     141        } else if ( auto ctor = dynamic_cast< const ImplicitCopyCtorExpr * >( call ) ) {
     142                return getCallArg( ctor->callExpr, pos );
     143        } else {
     144                assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( call ).c_str() );
     145        }
     146}
    23147
    24148bool structHasFlexibleArray( const ast::StructDecl * decl ) {
     
    33157}
    34158
     159const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr ) {
     160        auto appExpr = dynamic_cast< const ApplicationExpr * >( expr );
     161        if ( !appExpr ) return nullptr;
     162
     163        const DeclWithType * func = getCalledFunction( appExpr->func );
     164        assertf( func, "getCalledFunction returned nullptr: %s",
     165                toString( appExpr->func ).c_str() );
     166
     167        return func->linkage == Linkage::Intrinsic ? appExpr : nullptr;
     168}
     169
    35170} // namespace ast
  • src/AST/Inspect.hpp

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Fri Jun 24 13:16:31 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 27 15:35:00 2022
    13 // Update Count     : 1
     12// Last Modified On : Thr Sep 22 13:44:00 2022
     13// Update Count     : 2
    1414//
    1515
     
    1818namespace ast {
    1919
    20 // Does the structure end in a flexable array declaration?
    21 bool structHasFlexibleArray( const ast::StructDecl * );
     20/// Returns the base type of an pointer/array/reference type,
     21/// if the argument is not one of those types, return null.
     22const Type * getPointerBase( const Type * );
     23
     24/// Get the declaration of the function called (ApplicationExpr or UntypedExpr).
     25const DeclWithType * getFunction( const Expr * expr );
     26
     27/// Get the name of the function being called.
     28std::string getFunctionName( const Expr * expr );
     29
     30/// Returns the argument to a call expression in position N, indexed from 0.
     31const Expr * getCallArg( const Expr * call, unsigned pos );
     32
     33/// Does the structure end in a flexable array declaration?
     34bool structHasFlexibleArray( const StructDecl * );
     35
     36/// If the expression is an application whose target function is an
     37/// intrinsic, then returns a pointer to that application.
     38const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr );
    2239
    2340}
  • src/AST/Pass.hpp

    r9cd5bd2 rdf6cc9d  
    167167        const ast::Expr *             visit( const ast::UntypedExpr          * ) override final;
    168168        const ast::Expr *             visit( const ast::NameExpr             * ) override final;
    169         const ast::Expr *                         visit( const ast::QualifiedNameExpr    * ) override final;
     169        const ast::Expr *             visit( const ast::QualifiedNameExpr        * ) override final;
    170170        const ast::Expr *             visit( const ast::AddressExpr          * ) override final;
    171171        const ast::Expr *             visit( const ast::LabelAddressExpr     * ) override final;
     
    395395                at_cleanup( [func](void *) { func(); }, nullptr );
    396396        }
    397 
    398         /// When this node is finished being visited, call a member of an object.
    399         template<typename T>
    400         void GuardMethod( T * obj, void (T::*method)() ) {
    401                 at_cleanup( [ method ]( void * object ) {
    402                         static_cast< T * >( object )->method();
    403                 }, static_cast< void * >( obj ) );
    404         }
    405397};
    406398
  • src/AST/Pass.impl.hpp

    r9cd5bd2 rdf6cc9d  
    12051205        if ( __visit_children() ) {
    12061206                guard_symtab guard { *this };
    1207                 maybe_accept( node, &QualifiedNameExpr::var );
    12081207                maybe_accept( node, &QualifiedNameExpr::type_decl );
    12091208        }
  • src/AST/SymbolTable.cpp

    r9cd5bd2 rdf6cc9d  
    2020#include "Decl.hpp"
    2121#include "Expr.hpp"
     22#include "Inspect.hpp"
    2223#include "Type.hpp"
    2324#include "CodeGen/OperatorTable.h"  // for isCtorDtorAssign
     
    315316
    316317void SymbolTable::addStruct( const std::string &id ) {
    317         addStruct( new StructDecl( CodeLocation{}, id ) );
     318        addStruct( new StructDecl( CodeLocation(), id ) );
    318319}
    319320
     
    357358
    358359void SymbolTable::addUnion( const std::string &id ) {
    359         addUnion( new UnionDecl( CodeLocation{}, id ) );
     360        addUnion( new UnionDecl( CodeLocation(), id ) );
    360361}
    361362
     
    466467                assert( ! params.empty() );
    467468                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    468                 const Type * base = InitTweak::getPointerBase( params.front() );
     469                const Type * base = ast::getPointerBase( params.front() );
    469470                assert( base );
    470471                if (stripParams) {
  • src/AST/Type.cpp

    r9cd5bd2 rdf6cc9d  
    2222#include "Decl.hpp"
    2323#include "Init.hpp"
     24#include "Inspect.hpp"
    2425#include "Common/utility.h"      // for copy, move
    25 #include "InitTweak/InitTweak.h" // for getPointerBase
    2626#include "Tuples/Tuples.h"       // for isTtype
    2727
     
    3636        const Type * t;
    3737        const Type * a;
    38         for ( t = this; (a = InitTweak::getPointerBase( t )); t = a );
     38        for ( t = this; (a = ast::getPointerBase( t )); t = a );
    3939        return t;
    4040}
     
    176176        for ( const Type * ty : types ) {
    177177                members.emplace_back( new ObjectDecl{
    178                         CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ),
     178                        CodeLocation(), "", ty, new ListInit( CodeLocation(), {}, {}, NoConstruct ),
    179179                        Storage::Classes{}, Linkage::Cforall } );
    180180        }
  • src/CodeGen/CodeGenerator.cc

    r9cd5bd2 rdf6cc9d  
    912912                }
    913913                output << ")";
    914         }
    915 
    916         // QualifiedNameExpr should not reach to CodeGen.
    917         // FixQualifiedName Convert QualifiedNameExpr to VariableExpr
    918         void CodeGenerator::postvisit( QualifiedNameExpr * expr ) {
    919                 output << "/* label */" << mangleName(expr->var);
    920914        }
    921915
  • src/CodeGen/CodeGenerator.h

    r9cd5bd2 rdf6cc9d  
    103103                void postvisit( DefaultArgExpr * );
    104104                void postvisit( GenericExpr * );
    105                 void postvisit( QualifiedNameExpr *);
    106105
    107106                //*** Statements
  • src/CodeGen/GenType.cc

    r9cd5bd2 rdf6cc9d  
    169169
    170170        void GenType::postvisit( ReferenceType * refType ) {
    171                 assert( refType->base != 0);
     171                assert( 0 != refType->base );
    172172                assertf( ! options.genC, "Reference types should not reach code generation." );
    173173                handleQualifiers( refType );
  • src/Common/Eval.cc

    r9cd5bd2 rdf6cc9d  
    1616#include <utility> // for pair
    1717
     18#include "AST/Inspect.hpp"
    1819#include "Common/PassVisitor.h"
    1920#include "CodeGen/OperatorTable.h"                                              // access: OperatorInfo
     
    177178
    178179        void postvisit( const ast::ApplicationExpr * expr ) {
    179                 const ast::DeclWithType * function = InitTweak::getFunction(expr);
     180                const ast::DeclWithType * function = ast::getFunction(expr);
    180181                if ( ! function || function->linkage != ast::Linkage::Intrinsic ) { valid = false; return; }
    181182                const std::string & fname = function->name;
  • src/Common/PassVisitor.impl.h

    r9cd5bd2 rdf6cc9d  
    19341934        indexerScopedAccept( node->result, *this );
    19351935        maybeAccept_impl( node->type_decl, *this );
    1936         maybeAccept_impl( node->var, *this );
    19371936
    19381937        VISIT_END( node );
     
    19451944        indexerScopedAccept( node->result, *this );
    19461945        maybeAccept_impl( node->type_decl, *this );
    1947         maybeAccept_impl( node->var, *this );
    19481946
    19491947        VISIT_END( node );
     
    19571955    indexerScopedMutate( node->result, *this );
    19581956        maybeMutate_impl( node->type_decl, *this );
    1959         maybeAccept_impl( node->var, *this );
    19601957
    19611958        MUTATE_END( Expression, node );
  • src/Concurrency/KeywordsNew.cpp

    r9cd5bd2 rdf6cc9d  
    2121#include "AST/Decl.hpp"
    2222#include "AST/Expr.hpp"
     23#include "AST/Inspect.hpp"
    2324#include "AST/Pass.hpp"
    2425#include "AST/Stmt.hpp"
     
    15281529        const ast::ptr<ast::DeclWithType> & param = decl->params.front();
    15291530        auto type = dynamic_cast<const ast::StructInstType *>(
    1530                 InitTweak::getPointerBase( param->get_type() ) );
     1531                ast::getPointerBase( param->get_type() ) );
    15311532        if ( nullptr == type ) return decl;
    15321533        if ( !type->base->is_thread() ) return decl;
  • src/GenPoly/Box.cc

    r9cd5bd2 rdf6cc9d  
    6666                };
    6767
    68                 /// Adds layout-generation functions to polymorphic types
     68                /// Adds layout-generation functions to polymorphic types.
    6969                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
    70                         unsigned int functionNesting = 0;  // current level of nested functions
     70                        // Current level of nested functions:
     71                        unsigned int functionNesting = 0;
    7172                public:
    7273                        void previsit( FunctionDecl *functionDecl );
     
    7576                };
    7677
    77                 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
     78                /// Replaces polymorphic return types with out-parameters,
     79                /// replaces calls to polymorphic functions with adapter calls,
     80                /// and adds appropriate type variables to the function call.
    7881                class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7982                  public:
     
    146149                };
    147150
    148                 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.
     151                /// * Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.
    149152                /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    150153                /// * Calculates polymorphic offsetof expressions from offset array
     
    199202                };
    200203
    201                 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
     204                /// Replaces initialization of polymorphic values with alloca,
     205                /// declaration of dtype/ftype with appropriate void expression,
     206                /// sizeof expressions of polymorphic types with the proper variable,
     207                /// and strips fields from generic struct declarations.
    202208                struct Pass3 final : public BoxPass, public WithGuards {
    203209                        template< typename DeclClass >
  • src/GenPoly/GenPoly.cc

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep 14  9:24:00 2022
    13 // Update Count     : 15
     12// Last Modified On : Fri Oct  7 15:25:00 2022
     13// Update Count     : 16
    1414//
    1515
     
    6464                }
    6565
    66                 __attribute__((unused))
    67                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    68                         for (auto &param : params) {
    69                                 auto paramType = param.strict_as<ast::TypeExpr>();
    70                                 if (isPolyType(paramType->type, tyVars, env)) return true;
    71                         }
    72                         return false;
    73                 }
    74 
    7566                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
    7667                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    8374                }
    8475
    85                 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    86                         for ( ast::ptr<ast::Expr> const & param : params ) {
    87                                 auto paramType = param.as<ast::TypeExpr>();
    88                                 assertf( paramType, "Aggregate parameters should be type expressions." );
    89                                 if ( isDynType( paramType->type, tyVars, typeSubs ) ) {
     76                bool hasDynParams(
     77                                const std::vector<ast::ptr<ast::Expr>> & params,
     78                                const TypeVarMap & typeVars,
     79                                const ast::TypeSubstitution * subst ) {
     80                        for ( ast::ptr<ast::Expr> const & paramExpr : params ) {
     81                                auto param = paramExpr.as<ast::TypeExpr>();
     82                                assertf( param, "Aggregate parameters should be type expressions." );
     83                                if ( isDynType( param->type.get(), typeVars, subst ) ) {
    9084                                        return true;
    9185                                }
     
    195189        }
    196190
     191const ast::Type * isPolyType( const ast::Type * type,
     192                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     193        type = replaceTypeInst( type, subst );
     194
     195        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
     196                if ( typeVars.find( inst->typeString() ) != typeVars.end() ) return type;
     197        } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) {
     198                return isPolyType( array->base, subst );
     199        } else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) {
     200                if ( hasPolyParams( sue->params, subst ) ) return type;
     201        } else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) {
     202                if ( hasPolyParams( sue->params, subst ) ) return type;
     203        }
     204        return nullptr;
     205}
     206
    197207        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    198208                type = replaceTypeInst( type, env );
     
    211221        }
    212222
    213         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    214                 type = replaceTypeInst( type, typeSubs );
    215 
    216                 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
    217                         auto var = tyVars.find( inst->name );
    218                         if ( var != tyVars.end() && var->second.isComplete ) {
    219                                 return inst;
    220                         }
    221                 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
    222                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    223                                 return inst;
    224                         }
    225                 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
    226                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    227                                 return inst;
    228                         }
    229                 }
    230                 return nullptr;
    231         }
     223const ast::BaseInstType * isDynType(
     224                const ast::Type * type, const TypeVarMap & typeVars,
     225                const ast::TypeSubstitution * subst ) {
     226        type = replaceTypeInst( type, subst );
     227
     228        if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
     229                auto var = typeVars.find( inst->name );
     230                if ( var != typeVars.end() && var->second.isComplete ) {
     231
     232                }
     233        } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
     234                if ( hasDynParams( inst->params, typeVars, subst ) ) {
     235                        return inst;
     236                }
     237        } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
     238                if ( hasDynParams( inst->params, typeVars, subst ) ) {
     239                        return inst;
     240                }
     241        }
     242        return nullptr;
     243}
    232244
    233245        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
     
    236248                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
    237249        }
     250
     251const ast::BaseInstType *isDynRet(
     252                const ast::FunctionType * type, const TypeVarMap & typeVars ) {
     253        if ( type->returns.empty() ) return nullptr;
     254
     255        return isDynType( type->returns.front(), typeVars );
     256}
    238257
    239258        ReferenceToType *isDynRet( FunctionType *function ) {
     
    260279        }
    261280
     281bool needsAdapter(
     282                ast::FunctionType const * adaptee, const TypeVarMap & typeVars ) {
     283        if ( isDynRet( adaptee, typeVars ) ) return true;
     284
     285        for ( auto param : adaptee->params ) {
     286                if ( isDynType( param, typeVars ) ) {
     287                        return true;
     288                }
     289        }
     290        return false;
     291}
     292
    262293        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
    263294                type = replaceTypeInst( type, env );
     
    311342                return isPolyType( type, tyVars, env );
    312343        }
     344
     345ast::Type const * hasPolyBase(
     346                ast::Type const * type, const TypeVarMap & typeVars,
     347                int * levels, const ast::TypeSubstitution * subst ) {
     348        int level_count = 0;
     349
     350        while ( true ) {
     351                type = replaceTypeInst( type, subst );
     352
     353                if ( auto ptr = dynamic_cast<ast::PointerType const *>( type ) ) {
     354                        type = ptr->base;
     355                        ++level_count;
     356                } else {
     357                        break;
     358                }
     359        }
     360
     361        if ( nullptr != levels ) { *levels = level_count; }
     362        return isPolyType( type, typeVars, subst );
     363}
    313364
    314365        bool includesPolyType( Type *type, const TypeSubstitution *env ) {
     
    685736}
    686737
    687         namespace {
    688                 // temporary hack to avoid re-implementing anything related to TyVarMap
    689                 // does this work? these two structs have identical definitions.
    690                 inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {
    691                         return *reinterpret_cast<const TypeDecl::Data *>(&data);
    692                 }
    693         }
    694 
    695738        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    696739                // is parameter is not polymorphic, don't need to box
     
    703746        }
    704747
    705         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) {
    706                 // is parameter is not polymorphic, don't need to box
    707                 if ( ! isPolyType( param, exprTyVars ) ) return false;
    708                 ast::ptr<ast::Type> newType = arg;
    709                 if ( env ) env->apply( newType );
    710                 // if the argument's type is polymorphic, we don't need to box again!
    711                 return ! isPolyType( newType );
    712         }
     748bool needsBoxing( const ast::Type * param, const ast::Type * arg,
     749                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     750        // Don't need to box if the parameter is not polymorphic.
     751        if ( !isPolyType( param, typeVars ) ) return false;
     752
     753        ast::ptr<ast::Type> newType = arg;
     754        if ( subst ) {
     755                int count = subst->apply( newType );
     756                (void)count;
     757        }
     758        // Only need to box if the argument is not also polymorphic.
     759        return !isPolyType( newType );
     760}
    713761
    714762        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
     
    720768        }
    721769
    722         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) {
    723                 const ast::FunctionType * function = getFunctionType(appExpr->func->result);
    724                 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() );
    725                 TyVarMap exprTyVars(TypeDecl::Data{});
    726                 makeTyVarMap(function, exprTyVars);
    727                 return needsBoxing(param, arg, exprTyVars, env);
    728 
    729         }
     770bool needsBoxing(
     771                const ast::Type * param, const ast::Type * arg,
     772                const ast::ApplicationExpr * expr,
     773                const ast::TypeSubstitution * subst ) {
     774        const ast::FunctionType * function = getFunctionType( expr->func->result );
     775        assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
     776        TypeVarMap exprTyVars = { ast::TypeDecl::Data() };
     777        makeTypeVarMap( function, exprTyVars );
     778        return needsBoxing( param, arg, exprTyVars, subst );
     779}
    730780
    731781        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
     
    733783        }
    734784
    735         void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {
    736                 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));
    737         }
     785void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) {
     786        typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) );
     787}
    738788
    739789        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
     
    747797        }
    748798
    749         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {
    750                 if (auto ptype = dynamic_cast<const ast::FunctionType *>(type)) {
    751                         for (auto & tyVar : ptype->forall) {
    752                                 assert (tyVar);
    753                                 addToTyVarMap(tyVar, tyVarMap);
    754                         }
    755                 }
    756                 if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {
    757                         makeTyVarMap(pointer->base, tyVarMap);
    758                 }
    759         }
     799void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ) {
     800        if ( auto func = dynamic_cast<ast::FunctionType const *>( type ) ) {
     801                for ( auto & typeVar : func->forall ) {
     802                        assert( typeVar );
     803                        addToTypeVarMap( typeVar, typeVars );
     804                }
     805        }
     806        if ( auto pointer = dynamic_cast<ast::PointerType const *>( type ) ) {
     807                makeTypeVarMap( pointer->base, typeVars );
     808        }
     809}
    760810
    761811        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
     
    766816        }
    767817
     818void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ) {
     819        for ( auto const & pair : typeVars ) {
     820                os << pair.first << " (" << pair.second << ") ";
     821        } // for
     822        os << std::endl;
     823}
     824
    768825} // namespace GenPoly
    769826
  • src/GenPoly/GenPoly.h

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 16:03:00 2022
    13 // Update Count     : 8
     12// Last Modified On : Fri Oct  7 15:06:00 2022
     13// Update Count     : 9
    1414//
    1515
     
    2020
    2121#include "ErasableScopedMap.h"    // for ErasableScopedMap
    22 #include "AST/Fwd.hpp"
     22#include "AST/Decl.hpp"           // for TypeDecl::Data
     23#include "AST/Fwd.hpp"            // for ApplicationExpr, BaseInstType, Func...
    2324#include "SymTab/Mangler.h"       // for Mangler
    2425#include "SynTree/Declaration.h"  // for TypeDecl::Data, AggregateDecl, Type...
     
    2930        // TODO Via some tricks this works for ast::TypeDecl::Data as well.
    3031        typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap;
     32        using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >;
    3133
    3234        /// Replaces a TypeInstType by its referrent in the environment, if applicable
     
    3941        /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    4042        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    41         const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env = nullptr);
     43        const ast::Type * isPolyType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = nullptr );
    4244
    4345        /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided
    4446        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    45         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs = 0 );
     47        const ast::BaseInstType *isDynType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = 0 );
    4648
    4749        /// true iff function has dynamic-layout return type under the given type variable map
    4850        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &tyVars );
     51        const ast::BaseInstType *isDynRet( const ast::FunctionType * type, const TypeVarMap & typeVars );
    4952
    5053        /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters
     
    5356        /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type
    5457        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
     58        bool needsAdapter( ast::FunctionType const * adaptee, const TypeVarMap & typeVars );
    5559
    5660        /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
     
    5963        /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    6064        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     65        const ast::Type * isPolyPtr( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * env = 0 );
    6166
    6267        /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise;
     
    6772        /// N will be stored in levels, if provided, will look up substitution in env if provided
    6873        Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 );
     74        const ast::Type * hasPolyBase( const ast::Type * type, const TypeVarMap & typeVars, int * levels = 0, const ast::TypeSubstitution * env = 0 );
    6975
    7076        /// true iff this type or some base of this type after dereferencing pointers is either polymorphic or a generic type with at least one
     
    9096        /// true if arg requires boxing given exprTyVars
    9197        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env );
    92         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env);
     98        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst );
    9399
    94100        /// true if arg requires boxing in the call to appExpr
    95101        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env );
    96         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env);
     102        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * expr, const ast::TypeSubstitution * subst );
    97103
    98104        /// Adds the type variable `tyVar` to `tyVarMap`
    99105        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
     106        void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars );
    100107
    101108        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
    102109        void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    103         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap);
     110        void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars );
    104111
    105112        /// Prints type variable map
    106113        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     114        void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars );
    107115
    108116        /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType().
  • src/GenPoly/InstantiateGenericNew.cpp

    r9cd5bd2 rdf6cc9d  
    2323#include "AST/Copy.hpp"                // for deepCopy
    2424#include "AST/Create.hpp"              // for asForward
     25#include "AST/Inspect.hpp"             // for getFunction
    2526#include "AST/Pass.hpp"                // for Pass, WithGuard, WithShortCi...
    2627#include "AST/TranslationUnit.hpp"     // for TranslationUnit
     
    3031#include "GenPoly/GenPoly.h"           // for isPolyType, typesPolyCompatible
    3132#include "GenPoly/ScrubTyVars.h"       // for scrubAll
    32 #include "InitTweak/InitTweak.h"       // for getFunction
    3333#include "ResolvExpr/typeops.h"        // for typesCompatible
    3434
     
    294294                ast::ApplicationExpr const * expr ) {
    295295        GuardValue( isLValueArg ) = false;
    296         ast::Decl const * function = InitTweak::getFunction( expr );
     296        ast::Decl const * function = ast::getFunction( expr );
    297297        if ( ast::Linkage::Intrinsic != function->linkage
    298298                        || !CodeGen::isAssignment( function->name ) ) {
  • src/GenPoly/Lvalue.h

    r9cd5bd2 rdf6cc9d  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:21:59 2017
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Sep 15 14:13:00 2022
     13// Update Count     : 3
    1414//
    1515
     
    2020class Declaration;
    2121class Expression;
     22namespace ast {
     23        class Expr;
     24        class TranslationUnit;
     25}
    2226
    2327namespace GenPoly {
    2428        /// replaces return type of `lvalue T` with `T*`, along with appropriate address-of and dereference operators
    2529        void convertLvalue( std::list< Declaration* >& translationUnit );
     30        void convertLvalue( ast::TranslationUnit & translationUnit );
    2631
    2732        /// true after reference types have been eliminated from the source code. After this point, reference types should not be added to the AST.
     
    3035        /// applies transformations that allow GCC to accept more complicated lvalue expressions, e.g. &(a, b)
    3136        Expression * generalizedLvalue( Expression * expr );
     37        ast::Expr const * generalizedLvalue( ast::Expr const * expr );
    3238} // namespace GenPoly
    3339
  • src/GenPoly/ScrubTyVars.cc

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 16:10:00 2022
    13 // Update Count     : 4
     12// Last Modified On : Fri Oct  7 15:42:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    128128        public ast::WithVisitorRef<ScrubTypeVars> {
    129129
    130         ScrubTypeVars( ScrubMode m, TyVarMap const * tv ) :
     130        ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
    131131                        mode ( m ), typeVars( tv ) {}
    132132
     
    148148        ScrubMode const mode;
    149149        /// Type varriables to scrub.
    150         TyVarMap const * const typeVars;
     150        TypeVarMap const * const typeVars;
    151151        /// Value cached by primeBaseScrub.
    152152        ast::Type const * dynType = nullptr;
     
    255255const ast::Node * scrubTypeVarsBase(
    256256                const ast::Node * target,
    257                 ScrubMode mode, const TyVarMap * typeVars ) {
     257                ScrubMode mode, const TypeVarMap * typeVars ) {
    258258        if ( ScrubMode::All == mode ) {
    259259                assert( nullptr == typeVars );
     
    266266
    267267} // namespace
     268
     269template<>
     270ast::Node const * scrubTypeVars<ast::Node>(
     271        const ast::Node * target, const TypeVarMap & typeVars ) {
     272        return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars );
     273}
     274
     275template<>
     276ast::Node const * scrubTypeVarsDynamic<ast::Node>(
     277        ast::Node const * target, const TypeVarMap & typeVars ) {
     278        return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars );
     279}
    268280
    269281template<>
  • src/GenPoly/ScrubTyVars.h

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 14:14:00 2022
    13 // Update Count     : 3
     12// Last Modified On : Fri Oct  7 15:51:00 2022
     13// Update Count     : 4
    1414//
    1515
     
    109109        }
    110110
     111/// For all polymorphic types with type variables in `typeVars`,
     112/// replaces generic types, dtypes, and ftypes with the appropriate void type,
     113/// and sizeof/alignof expressions with the proper variable.
     114template<typename node_t>
     115node_t const * scrubTypeVars(
     116                node_t const * target, const TypeVarMap & typeVars ) {
     117        return strict_dynamic_cast<node_t const *>(
     118                        scrubTypeVars<ast::Node>( target, typeVars ) );
     119}
     120
     121/// For all dynamic-layout types with type variables in `typeVars`,
     122/// replaces generic types, dtypes, and ftypes with the appropriate void type,
     123/// and sizeof/alignof expressions with the proper variable.
     124template<typename node_t>
     125ast::Node const * scrubTypeVarsDynamic(
     126                node_t const * target, const TypeVarMap & typeVars ) {
     127        return strict_dynamic_cast<node_t const *>(
     128                        scrubTypeVarsDynamic<ast::Node>( target, typeVars ) );
     129}
     130
    111131/// For all polymorphic types, replaces generic types, with the appropriate
    112132/// void type, and sizeof/alignof expressions with the proper variable.
    113133template<typename node_t>
    114134node_t const * scrubAllTypeVars( node_t const * target ) {
    115         return strict_dynamic_cast<node_t const *>( scrubAllTypeVars<ast::Node>( target ) );
     135        return strict_dynamic_cast<node_t const *>(
     136                        scrubAllTypeVars<ast::Node>( target ) );
    116137}
     138
     139// We specialize for Node as a base case.
     140template<>
     141ast::Node const * scrubTypeVars<ast::Node>(
     142                const ast::Node * target, const TypeVarMap & typeVars );
     143
     144template<>
     145ast::Node const * scrubTypeVarsDynamic<ast::Node>(
     146                ast::Node const * target, const TypeVarMap & typeVars );
    117147
    118148template<>
  • src/GenPoly/SpecializeNew.cpp

    r9cd5bd2 rdf6cc9d  
    1616#include "Specialize.h"
    1717
    18 #include "AST/Pass.hpp"
     18#include "AST/Inspect.hpp"               // for isIntrinsicCallExpr
     19#include "AST/Pass.hpp"                  // for Pass
    1920#include "AST/TypeEnvironment.hpp"       // for OpenVarSet, AssertionSet
    2021#include "Common/UniqueName.h"           // for UniqueName
    2122#include "GenPoly/GenPoly.h"             // for getFunctionType
    22 #include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    2323#include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    2424#include "ResolvExpr/TypeEnvironment.h"  // for FirstOpen, FirstClosed
    25 
    26 #include "AST/Print.hpp"
    2725
    2826namespace GenPoly {
     
    425423const ast::Expr * SpecializeCore::postvisit(
    426424                const ast::ApplicationExpr * expr ) {
    427         if ( InitTweak::isIntrinsicCallExpr( expr ) ) {
     425        if ( ast::isIntrinsicCallExpr( expr ) ) {
    428426                return expr;
    429427        }
  • src/GenPoly/module.mk

    r9cd5bd2 rdf6cc9d  
    3030        GenPoly/InstantiateGeneric.cc \
    3131        GenPoly/InstantiateGeneric.h \
     32        GenPoly/LvalueNew.cpp \
    3233        GenPoly/Lvalue.cc \
    3334        GenPoly/ScopedSet.h \
  • src/InitTweak/FixInitNew.cpp

    r9cd5bd2 rdf6cc9d  
    1414#include <utility>                     // for pair
    1515
     16#include "AST/Inspect.hpp"             // for getFunction, getPointerBase, g...
    1617#include "CodeGen/GenType.h"           // for genPrettyType
    1718#include "CodeGen/OperatorTable.h"
     
    2425#include "GenInit.h"                   // for genCtorDtor
    2526#include "GenPoly/GenPoly.h"           // for getFunctionType
    26 #include "InitTweak.h"                 // for getFunctionName, getCallArg
    2727#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    2828#include "ResolvExpr/typeops.h"        // for typesCompatible
  • src/InitTweak/InitTweak.cc

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Fri May 13 11:26:36 2016
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Dec  6 13:21:00 2021
    13 // Update Count     : 20
     12// Last Modified On : Wed Sep 22  9:50:00 2022
     13// Update Count     : 21
    1414//
    1515
     
    2323#include "AST/Expr.hpp"
    2424#include "AST/Init.hpp"
     25#include "AST/Inspect.hpp"
    2526#include "AST/Node.hpp"
    2627#include "AST/Pass.hpp"
     
    654655        namespace {
    655656                DeclarationWithType * getCalledFunction( Expression * expr );
    656                 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );
    657657
    658658                template<typename CallExpr>
     
    664664                        return getCalledFunction( expr->get_args().front() );
    665665                }
    666 
    667                 template<typename CallExpr>
    668                 const ast::DeclWithType * handleDerefCalledFunction( const CallExpr * expr ) {
    669                         // (*f)(x) => should get "f"
    670                         std::string name = getFunctionName( expr );
    671                         assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
    672                         assertf( ! expr->args.empty(), "Cannot get called function from dereference with no arguments" );
    673                         return getCalledFunction( expr->args.front() );
    674                 }
    675 
    676666
    677667                DeclarationWithType * getCalledFunction( Expression * expr ) {
     
    695685                }
    696686
    697                 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ) {
    698                         assert( expr );
    699                         if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) {
    700                                 return varExpr->var;
    701                         } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) {
    702                                 return memberExpr->member;
    703                         } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) {
    704                                 return getCalledFunction( castExpr->arg );
    705                         } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) {
    706                                 return handleDerefCalledFunction( untypedExpr );
    707                         } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) {
    708                                 return handleDerefCalledFunction( appExpr );
    709                         } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) {
    710                                 return getCalledFunction( addrExpr->arg );
    711                         } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) {
    712                                 return getCalledFunction( commaExpr->arg2 );
    713                         }
    714                         return nullptr;
    715                 }
    716 
    717687                DeclarationWithType * getFunctionCore( const Expression * expr ) {
    718688                        if ( const auto * appExpr = dynamic_cast< const ApplicationExpr * >( expr ) ) {
     
    731701        const DeclarationWithType * getFunction( const Expression * expr ) {
    732702                return getFunctionCore( expr );
    733         }
    734 
    735         const ast::DeclWithType * getFunction( const ast::Expr * expr ) {
    736                 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {
    737                         return getCalledFunction( appExpr->func );
    738                 } else if ( const ast::UntypedExpr * untyped = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {
    739                         return getCalledFunction( untyped->func );
    740                 }
    741                 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
    742703        }
    743704
     
    752713        }
    753714
    754         const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr ) {
    755                 auto appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr );
    756                 if ( ! appExpr ) return nullptr;
    757 
    758                 const ast::DeclWithType * func = getCalledFunction( appExpr->func );
    759                 assertf( func,
    760                         "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );
    761 
    762                 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because
    763                 // autogenerated ctor/dtor will call all member dtors, and some members may have a
    764                 // user-defined dtor
    765                 return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;
    766         }
    767 
    768715        namespace {
    769716                template <typename Predicate>
     
    817764                                if ( pos == 0 ) return arg;
    818765                                pos--;
    819                         }
    820                         assert( false );
    821                 }
    822 
    823                 template<typename CallExpr>
    824                 const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) {
    825                         if( pos >= call->args.size() ) {
    826                                 assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.",
    827                                         pos, toString( call ).c_str() );
    828                         }
    829                         for ( const ast::Expr * arg : call->args ) {
    830                                 if ( pos == 0 ) return arg;
    831                                 --pos;
    832766                        }
    833767                        assert( false );
     
    854788        }
    855789
    856         const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) {
    857                 if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) {
    858                         return callArg( app, pos );
    859                 } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) {
    860                         return callArg( untyped, pos );
    861                 } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) {
    862                         const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids;
    863                         assertf( ! stmts.empty(), "TupleAssignExpr missing statements." );
    864                         auto stmt  = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back().get() );
    865                         auto tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr.get() );
    866                         assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr.");
    867                         return getCallArg( tuple->exprs.front(), pos );
    868                 } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) {
    869                         return getCallArg( ctor->callExpr, pos );
    870                 } else {
    871                         assertf( false, "Unexpected expression type passed to getCallArg: %s",
    872                                 toString( call ).c_str() );
    873                 }
    874         }
    875 
    876790        namespace {
    877791                std::string funcName( Expression * func );
    878                 std::string funcName( const ast::Expr * func );
    879792
    880793                template<typename CallExpr>
     
    885798                        assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
    886799                        return funcName( expr->get_args().front() );
    887                 }
    888 
    889                 template<typename CallExpr>
    890                 std::string handleDerefName( const CallExpr * expr ) {
    891                         // (*f)(x) => should get name "f"
    892                         std::string name = getFunctionName( expr );
    893                         assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
    894                         assertf( ! expr->args.empty(), "Cannot get function name from dereference with no arguments" );
    895                         return funcName( expr->args.front() );
    896800                }
    897801
     
    917821                        }
    918822                }
    919 
    920                 std::string funcName( const ast::Expr * func ) {
    921                         if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) {
    922                                 return nameExpr->name;
    923                         } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) {
    924                                 return varExpr->var->name;
    925                         } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {
    926                                 return funcName( castExpr->arg );
    927                         } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) {
    928                                 return memberExpr->member->name;
    929                         } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) {
    930                                 return funcName( memberExpr->member );
    931                         } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) {
    932                                 return handleDerefName( untypedExpr );
    933                         } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) {
    934                                 return handleDerefName( appExpr );
    935                         } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) {
    936                                 return funcName( getCallArg( ctorExpr->callExpr, 0 ) );
    937                         } else {
    938                                 assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );
    939                         }
    940                 }
    941823        }
    942824
     
    955837        }
    956838
    957         std::string getFunctionName( const ast::Expr * expr ) {
    958                 // there's some unforunate overlap here with getCalledFunction. Ideally this would be able to use getCalledFunction and
    959                 // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction
    960                 // can't possibly do anything reasonable.
    961                 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {
    962                         return funcName( appExpr->func );
    963                 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {
    964                         return funcName( untypedExpr->func );
    965                 } else {
    966                         std::cerr << expr << std::endl;
    967                         assertf( false, "Unexpected expression type passed to getFunctionName" );
    968                 }
    969         }
    970 
    971839        Type * getPointerBase( Type * type ) {
    972840                if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
     
    980848                }
    981849        }
    982         const ast::Type* getPointerBase( const ast::Type* t ) {
    983                 if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) {
    984                         return p->base;
    985                 } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) {
    986                         return a->base;
    987                 } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) {
    988                         return r->base;
    989                 } else return nullptr;
    990         }
    991850
    992851        Type * isPointerType( Type * type ) {
     
    1022881                static ast::ptr<ast::FunctionDecl> assign = nullptr;
    1023882                if (!assign) {
    1024                         auto td = new ast::TypeDecl({}, "T", {}, nullptr, ast::TypeDecl::Dtype, true);
    1025                         assign = new ast::FunctionDecl({}, "?=?", {},
    1026                         { new ast::ObjectDecl({}, "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),
    1027                           new ast::ObjectDecl({}, "_src", new ast::TypeInstType("T", td))},
    1028                         { new ast::ObjectDecl({}, "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic);
     883                        auto td = new ast::TypeDecl(CodeLocation(), "T", {}, nullptr, ast::TypeDecl::Dtype, true);
     884                        assign = new ast::FunctionDecl(CodeLocation(), "?=?", {},
     885                        { new ast::ObjectDecl(CodeLocation(), "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),
     886                          new ast::ObjectDecl(CodeLocation(), "_src", new ast::TypeInstType("T", td))},
     887                        { new ast::ObjectDecl(CodeLocation(), "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic);
    1029888                }
    1030889                if (dst->result.as<ast::ReferenceType>()) {
     
    12031062        if ( ftype->params.size() != 2 ) return false;
    12041063
    1205         const ast::Type * t1 = getPointerBase( ftype->params.front() );
     1064        const ast::Type * t1 = ast::getPointerBase( ftype->params.front() );
    12061065        if ( ! t1 ) return false;
    12071066        const ast::Type * t2 = ftype->params.back();
    12081067
    1209         return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
     1068        return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable() );
    12101069}
     1070
    12111071
    12121072        const FunctionDecl * isAssignment( const Declaration * decl ) {
  • src/InitTweak/InitTweak.h

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Fri May 13 11:26:36 2016
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Dec  6 13:20:00 2021
    13 // Update Count     : 8
     12// Last Modified On : Wed Sep 22  9:21:00 2022
     13// Update Count     : 9
    1414//
    1515
     
    7474        DeclarationWithType * getFunction( Expression * expr );
    7575        const DeclarationWithType * getFunction( const Expression * expr );
    76         const ast::DeclWithType * getFunction( const ast::Expr * expr );
    7776
    7877        /// Non-Null if expr is a call expression whose target function is intrinsic
    7978        ApplicationExpr * isIntrinsicCallExpr( Expression * expr );
    80         const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr);
    8179
    8280        /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
     
    9896        /// returns the name of the function being called
    9997        std::string getFunctionName( Expression * expr );
    100         std::string getFunctionName( const ast::Expr * expr );
    10198
    10299        /// returns the argument to a call expression in position N indexed from 0
    103100        Expression *& getCallArg( Expression * callExpr, unsigned int pos );
    104         const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos );
    105101
    106102        /// returns the base type of a PointerType or ArrayType, else returns NULL
    107103        Type * getPointerBase( Type * );
    108         const ast::Type* getPointerBase( const ast::Type* );
    109104
    110105        /// returns the argument if it is a PointerType or ArrayType, else returns NULL
  • src/Parser/DeclarationNode.cc

    r9cd5bd2 rdf6cc9d  
    297297        } // if
    298298} // DeclarationNode::newEnumValueGeneric
     299
     300DeclarationNode * DeclarationNode::newEnumInLine( const string name ) {
     301        DeclarationNode * newnode = newName( new std::string(name) );
     302        newnode->enumInLine = true;
     303        return newnode;
     304}
    299305
    300306DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
  • src/Parser/ExpressionNode.cc

    r9cd5bd2 rdf6cc9d  
    523523                auto enumInst = new EnumInstType( Type::Qualifiers(), e );
    524524                auto obj = new ObjectDecl( name->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, enumInst, nullptr );
    525                 ret->set_var( obj );
    526525        }
    527526        return ret;
  • src/Parser/ParseNode.h

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb  2 09:15:49 2022
    13 // Update Count     : 905
     12// Last Modified On : Tue Oct 18 14:15:37 2022
     13// Update Count     : 936
    1414//
    1515
     
    240240        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
    241241        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
     242        static DeclarationNode * newEnumInLine( const std::string name );
    242243        static DeclarationNode * newName( const std::string * );
    243244        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
     
    339340
    340341        bool inLine = false;
     342        bool enumInLine = false;
    341343        Type::FuncSpecifiers funcSpecs;
    342344        Type::StorageClasses storageClasses;
     
    463465                        errors.append( e );
    464466                } // try
    465                 cur = dynamic_cast< NodeType * >( cur->get_next() );
     467                const ParseNode * temp = (cur->get_next());
     468                cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
     469                if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
     470                        SemanticError( cur->location, "internal error, non-homogeneous nodes founds in buildList processing." );
     471                } // if
    466472        } // while
    467473        if ( ! errors.isEmpty() ) {
  • src/Parser/TypeData.cc

    r9cd5bd2 rdf6cc9d  
    924924        list< Declaration * >::iterator members = ret->get_members().begin();
    925925        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
     926                if ( cur->enumInLine ) {
     927                        // Tell the compiler this is a inline value placeholder
     928                        ObjectDecl * member = dynamic_cast< ObjectDecl* >(* members);
     929                        member->enumInLine = true;
     930                }
    926931                if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
    927932                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
  • src/Parser/lex.ll

    r9cd5bd2 rdf6cc9d  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Tue Sep 20 21:18:55 2022
    13  * Update Count     : 762
     12 * Last Modified On : Thu Oct 13 20:46:04 2022
     13 * Update Count     : 764
    1414 */
    1515
     
    331331__uint128_t             { KEYWORD_RETURN(UINT128); }                    // GCC
    332332unsigned                { KEYWORD_RETURN(UNSIGNED); }
    333 __builtin_va_list { KEYWORD_RETURN(VALIST); }                   // GCC
     333__builtin_va_arg { KEYWORD_RETURN(VA_ARG); }                    // GCC
     334__builtin_va_list { KEYWORD_RETURN(VA_LIST); }                  // GCC
    334335virtual                 { KEYWORD_RETURN(VIRTUAL); }                    // CFA
    335336void                    { KEYWORD_RETURN(VOID); }
  • src/Parser/parser.yy

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 27 13:21:28 2022
    13 // Update Count     : 5661
     12// Last Modified On : Fri Oct 14 14:04:43 2022
     13// Update Count     : 5751
    1414//
    1515
     
    103103        // distribute declaration_specifier across all declared variables, e.g., static, const, but not __attribute__.
    104104        assert( declList );
    105 //      printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout );
     105        // printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout );
    106106        DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( typeSpec );
    107 //      printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout );
    108 //      cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name;
     107        // printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout );
     108        // cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name;
    109109
    110110        for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
     
    112112        } // for
    113113        declList->addType( cl );
    114 //      printf( "distAttr3 declList %p\n", declList ); declList->print( std::cout, 0 );
     114        // printf( "distAttr3 declList %p\n", declList ); declList->print( std::cout, 0 );
    115115        return declList;
    116116} // distAttr
     
    248248} // forCtrl
    249249
     250static void IdentifierBeforeIdentifier( string & identifier1, string & identifier2, const char * kind ) {
     251        SemanticError( yylloc, ::toString( "Adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n"
     252                                   "Possible cause is misspelled type name or missing generic parameter." ) );
     253} // IdentifierBeforeIdentifier
     254
     255static void IdentifierBeforeType( string & identifier, const char * kind ) {
     256        SemanticError( yylloc, ::toString( "Identifier \"", identifier, "\" cannot appear before a ", kind, ".\n"
     257                                   "Possible cause is misspelled storage/CV qualifier, misspelled typename, or missing generic parameter." ) );
     258} // IdentifierBeforeType
     259
    250260bool forall = false;                                                                    // aggregate have one or more forall qualifiers ?
    251261
     
    295305%token TYPEDEF
    296306%token EXTERN STATIC AUTO REGISTER
    297 %token THREADLOCALGCC THREADLOCALC11                                            // GCC, C11
     307%token THREADLOCALGCC THREADLOCALC11                                    // GCC, C11
    298308%token INLINE FORTRAN                                                                   // C99, extension ISO/IEC 9899:1999 Section J.5.9(1)
    299309%token NORETURN                                                                                 // C11
     
    308318%token DECIMAL32 DECIMAL64 DECIMAL128                                   // GCC
    309319%token ZERO_T ONE_T                                                                             // CFA
    310 %token SIZEOF TYPEOF VALIST AUTO_TYPE                                   // GCC
     320%token SIZEOF TYPEOF VA_LIST VA_ARG AUTO_TYPE                   // GCC
    311321%token OFFSETOF BASETYPEOF TYPEID                                               // CFA
    312322%token ENUM STRUCT UNION
     
    399409// declarations
    400410%type<decl> abstract_declarator abstract_ptr abstract_array abstract_function array_dimension multi_array_dimension
    401 %type<decl> abstract_parameter_declarator abstract_parameter_ptr abstract_parameter_array abstract_parameter_function array_parameter_dimension array_parameter_1st_dimension
     411%type<decl> abstract_parameter_declarator_opt abstract_parameter_declarator abstract_parameter_ptr abstract_parameter_array abstract_parameter_function array_parameter_dimension array_parameter_1st_dimension
    402412%type<decl> abstract_parameter_declaration
    403413
     
    651661        //      { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; }
    652662        | IDENTIFIER IDENTIFIER                                                         // syntax error
    653                 {
    654                         SemanticError( yylloc, ::toString( "Adjacent identifiers are not meaningful in an expression. "
    655                                                                                            "Possible problem is identifier \"", *$1.str,
    656                                                                                            "\" is a misspelled typename or an incorrectly specified type name, "
    657                                                                                            "e.g., missing generic parameter or missing struct/union/enum before typename." ) );
    658                         $$ = nullptr;
    659                 }
    660         | IDENTIFIER direct_type                                                        // syntax error
    661                 {
    662                         SemanticError( yylloc, ::toString( "Identifier \"", *$1.str, "\" cannot appear before a type. "
    663                                                                                            "Possible problem is misspelled storage or CV qualifier." ) );
    664                         $$ = nullptr;
    665                 }
     663                { IdentifierBeforeIdentifier( *$1.str, *$2.str, "n expression" ); $$ = nullptr; }
     664        | IDENTIFIER type_qualifier                                                     // syntax error
     665                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
     666        | IDENTIFIER storage_class                                                      // syntax error
     667                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
     668        | IDENTIFIER basic_type_name                                            // syntax error
     669                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
     670        | IDENTIFIER TYPEDEFname                                                        // syntax error
     671                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
     672        | IDENTIFIER TYPEGENname                                                        // syntax error
     673                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    666674        ;
    667675
     
    690698        primary_expression
    691699        | postfix_expression '[' assignment_expression ',' tuple_expression_list ']'
    692                         // Historic, transitional: Disallow commas in subscripts.
    693                         // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    694                         // Current: Commas in subscripts make tuples.
     700                // Historic, transitional: Disallow commas in subscripts.
     701                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
     702                // Current: Commas in subscripts make tuples.
    695703                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    696704        | postfix_expression '[' assignment_expression ']'
     
    712720        | postfix_expression '(' argument_expression_list_opt ')'
    713721                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     722        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
     723                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
     724                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
     725                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    714726        | postfix_expression '`' identifier                                     // CFA, postfix call
    715727                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     
    21482160        | LONG
    21492161                { $$ = DeclarationNode::newLength( DeclarationNode::Long ); }
    2150         | VALIST                                                                                        // GCC, __builtin_va_list
     2162        | VA_LIST                                                                                       // GCC, __builtin_va_list
    21512163                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
    21522164        | AUTO_TYPE
     
    25932605                { $$ = DeclarationNode::newEnumValueGeneric( $1, $2 ); }
    25942606        | INLINE type_name
    2595                 { $$ = DeclarationNode::newEnumValueGeneric( new string("inline"), nullptr ); }
     2607                { $$ = DeclarationNode::newEnumInLine( *$2->type->symbolic.name ); }
    25962608        | enumerator_list ',' identifier_or_type_name enumerator_value_opt
    25972609                { $$ = $1->appendList( DeclarationNode::newEnumValueGeneric( $3, $4 ) ); }
     
    29933005                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
    29943006        | declaration
     3007        | IDENTIFIER IDENTIFIER
     3008                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
     3009        | IDENTIFIER type_qualifier                                                     // syntax error
     3010                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
     3011        | IDENTIFIER storage_class                                                      // syntax error
     3012                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
     3013        | IDENTIFIER basic_type_name                                            // syntax error
     3014                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
     3015        | IDENTIFIER TYPEDEFname                                                        // syntax error
     3016                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
     3017        | IDENTIFIER TYPEGENname                                                        // syntax error
     3018                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    29953019        | external_function_definition
    29963020        | EXTENSION external_definition                                         // GCC, multiple __extension__ allowed, meaning unknown
     
    30233047                        $$ = $6;
    30243048                }
     3049        // global distribution
    30253050        | type_qualifier_list
    30263051                {
     
    30473072        | declaration_qualifier_list type_qualifier_list
    30483073                {
    3049                         if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    3050                         if ( ($1->type && $1->type->forall) || $2->type->forall ) forall = true; // remember generic type
     3074                        if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3075                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    30513076                }
    30523077          '{' up external_definition_list_opt down '}'          // CFA, namespace
     
    36553680// functions.
    36563681
     3682abstract_parameter_declarator_opt:
     3683        // empty
     3684                { $$ = nullptr; }
     3685        | abstract_parameter_declarator
     3686        ;
     3687
    36573688abstract_parameter_declarator:
    36583689        abstract_parameter_ptr
  • src/ResolvExpr/CandidateFinder.cpp

    r9cd5bd2 rdf6cc9d  
    862862                                }
    863863                        }
    864                 }
    865 
    866                 void postvisit( const ast::QualifiedNameExpr * qualifiedNameExpr ) {
    867                         auto mangleName = Mangle::mangle(qualifiedNameExpr->var);
    868                         addCandidate( qualifiedNameExpr, tenv );
    869864                }
    870865
  • src/ResolvExpr/Unify.cc

    r9cd5bd2 rdf6cc9d  
    10361036                /// Creates a tuple type based on a list of Type
    10371037
    1038 
    10391038                static bool unifyList(
    10401039                        const std::vector< ast::ptr< ast::Type > > & list1,
     
    11741173                        return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
    11751174                } else {
    1176                         ast::Pass<Unify_new> comparator{ type2, env, need, have, open, widen, symtab };
    1177                         type1->accept( comparator );
    1178                         return comparator.core.result;
     1175                        return ast::Pass<Unify_new>::read(
     1176                                type1, type2, env, need, have, open, widen, symtab );
    11791177                }
    11801178        }
  • src/SymTab/Mangler.cc

    r9cd5bd2 rdf6cc9d  
    6565                                void postvisit( const QualifiedType * qualType );
    6666
    67                                 void postvisit( const QualifiedNameExpr * qualNameExpr );
    68 
    6967                                std::string get_mangleName() { return mangleName; }
    7068                          private:
     
    307305                                        mangleName += Encoding::qualifiedTypeEnd;
    308306                                }
    309                         }
    310 
    311                         void Mangler_old::postvisit( const QualifiedNameExpr * qual ) {
    312                                 maybeAccept( qual->var, *visitor );
    313307                        }
    314308
     
    423417                        void postvisit( const ast::OneType * oneType );
    424418                        void postvisit( const ast::QualifiedType * qualType );
    425                         void postvisit( const ast::QualifiedNameExpr * qualNameExpr );
    426419
    427420                        std::string get_mangleName() { return mangleName; }
     
    652645                                mangleName += Encoding::qualifiedTypeEnd;
    653646                        }
    654                 }
    655                 void Mangler_new::postvisit( const ast::QualifiedNameExpr * qual ) {
    656                         maybeAccept( qual->var.get(), *visitor );
    657647                }
    658648
  • src/SymTab/Validate.cc

    r9cd5bd2 rdf6cc9d  
    858858                        declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
    859859                } else if ( EnumInstType * enumInst = dynamic_cast< EnumInstType * >( designatorType ) ) {
    860                         // declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) );
    861860                        if ( enumInst->baseEnum ) {
    862861                                const EnumDecl * enumDecl = enumInst->baseEnum;
  • src/SymTab/ValidateType.cc

    r9cd5bd2 rdf6cc9d  
    8181        void previsit( QualifiedType * qualType );
    8282        void postvisit( QualifiedType * qualType );
    83 
    8483        void postvisit( QualifiedNameExpr * qualExpr );
    85 
     84       
    8685        void postvisit( EnumDecl * enumDecl );
    8786        void postvisit( StructDecl * structDecl );
  • src/SynTree/AddressExpr.cc

    r9cd5bd2 rdf6cc9d  
    5050                                set_result( addrType( refType->base ) );
    5151                        } else {
     52                                if(!arg->result->location.isSet()) arg->result->location = arg->location;
    5253                                SemanticError( arg->result, "Attempt to take address of non-lvalue expression: " );
    5354                        } // if
  • src/SynTree/Declaration.h

    r9cd5bd2 rdf6cc9d  
    121121        Initializer * init;
    122122        Expression * bitfieldWidth;
     123        bool enumInLine = false;
    123124
    124125        ObjectDecl( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, Expression * bitfieldWidth, Type * type, Initializer * init,
  • src/SynTree/Expression.h

    r9cd5bd2 rdf6cc9d  
    168168        Declaration * type_decl;
    169169        std::string name;
    170         DeclarationWithType * var;
    171170
    172171        QualifiedNameExpr( Declaration * decl, std::string name): Expression(), type_decl(decl), name(name) {}
    173         QualifiedNameExpr( const QualifiedNameExpr & other): Expression(other), type_decl(other.type_decl), name(other.name), var(other.var) {}
    174         DeclarationWithType * get_var() const { return var; }
    175         void set_var( DeclarationWithType * newValue ) { var = newValue; }
     172        QualifiedNameExpr( const QualifiedNameExpr & other): Expression(other), type_decl(other.type_decl), name(other.name) {}
    176173
    177174        virtual ~QualifiedNameExpr() {
    178                 delete var;
    179175                delete type_decl;
    180176        }
  • src/Tuples/TupleExpansionNew.cpp

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Mon Aug 23 15:36:09 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Sep 20 16:17:00 2022
    13 // Update Count     : 4
     12// Last Modified On : Mon Sep 26 10:25:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    3030struct UniqueExprExpander final : public ast::WithDeclsToAdd<> {
    3131        const ast::Expr * postvisit( const ast::UniqueExpr * unqExpr );
    32         std::map< int, ast::ptr<ast::Expr> > decls; // not vector, because order added may not be increasing order
     32        // Not a vector, because they may not be adding in increasing order.
     33        std::map< int, ast::ptr<ast::Expr> > decls;
     34};
     35
     36/// Replaces Tuple Assign & Index Expressions, and Tuple Types.
     37struct TupleMainExpander final :
     38                public ast::WithCodeLocation,
     39                public ast::WithDeclsToAdd<>,
     40                public ast::WithGuards,
     41                public ast::WithVisitorRef<TupleMainExpander> {
     42        ast::Expr const * postvisit( ast::TupleAssignExpr const * expr );
     43
     44        void previsit( ast::CompoundStmt const * );
     45        ast::Expr const * postvisit( ast::Expr const * expr );
     46        ast::Type const * postvisit( ast::TupleType const * type );
     47
     48        ast::Expr const * postvisit( ast::TupleIndexExpr const * expr );
     49private:
     50        ScopedMap< int, ast::StructDecl const * > typeMap;
     51};
     52
     53struct TupleExprExpander final {
     54        ast::Expr const * postvisit( ast::TupleExpr const * expr );
    3355};
    3456
     
    100122}
    101123
    102 /// Replaces Tuple Assign & Index Expressions, and Tuple Types.
    103 struct TupleMainExpander final :
    104                 public ast::WithCodeLocation,
    105                 public ast::WithDeclsToAdd<>,
    106                 public ast::WithGuards,
    107                 public ast::WithVisitorRef<TupleMainExpander> {
    108         ast::Expr const * postvisit( ast::TupleAssignExpr const * expr ) {
    109                 // Just move the env on the new top level expression.
    110                 return ast::mutate_field( expr->stmtExpr.get(),
    111                         &ast::TupleAssignExpr::env, expr->env.get() );
    112         }
    113 
    114         void previsit( ast::CompoundStmt const * ) {
    115                 GuardScope( typeMap );
    116         }
    117 
    118         ast::Expr const * postvisit( ast::Expr const * expr ) {
    119                 if ( nullptr == expr->env ) {
    120                         return expr;
    121                 }
    122                 // TypeSubstitutions are never visited in the new Pass template,
    123                 // so it is done manually here, where all types have to be replaced.
    124                 return ast::mutate_field( expr, &ast::Expr::env,
    125                         expr->env->accept( *visitor ) );
    126         }
    127 
    128         ast::Type const * postvisit( ast::TupleType const * type ) {
    129                 assert( location );
    130                 unsigned tupleSize = type->size();
    131                 if ( !typeMap.count( tupleSize ) ) {
    132                         ast::StructDecl * decl = new ast::StructDecl( *location,
    133                                 toString( "_tuple", tupleSize, "_" )
     124// Handles expansion of tuple assignment.
     125ast::Expr const * TupleMainExpander::postvisit(
     126                ast::TupleAssignExpr const * expr ) {
     127        // Just move the env on the new top level expression.
     128        return ast::mutate_field( expr->stmtExpr.get(),
     129                &ast::TupleAssignExpr::env, expr->env.get() );
     130}
     131
     132// Context information for tuple type expansion.
     133void TupleMainExpander::previsit( ast::CompoundStmt const * ) {
     134        GuardScope( typeMap );
     135}
     136
     137// Make sure types in a TypeSubstitution are expanded.
     138ast::Expr const * TupleMainExpander::postvisit( ast::Expr const * expr ) {
     139        if ( nullptr == expr->env ) {
     140                return expr;
     141        }
     142        return ast::mutate_field( expr, &ast::Expr::env,
     143                expr->env->accept( *visitor ) );
     144}
     145
     146// Create a generic tuple structure of a given size.
     147ast::StructDecl * createTupleStruct(
     148                unsigned int tupleSize, CodeLocation const & location ) {
     149        ast::StructDecl * decl = new ast::StructDecl( location,
     150                toString( "_tuple", tupleSize, "_" )
     151        );
     152        decl->body = true;
     153
     154        for ( size_t i = 0 ; i < tupleSize ; ++i ) {
     155                ast::TypeDecl * typeParam = new ast::TypeDecl( location,
     156                        toString( "tuple_param_", tupleSize, "_", i ),
     157                        ast::Storage::Classes(),
     158                        nullptr,
     159                        ast::TypeDecl::Dtype,
     160                        true
    134161                        );
    135                         decl->body = true;
    136 
    137                         for ( size_t i = 0 ; i < tupleSize ; ++i ) {
    138                                 ast::TypeDecl * typeParam = new ast::TypeDecl( *location,
    139                                         toString( "tuple_param_", tupleSize, "_", i ),
    140                                         ast::Storage::Classes(),
    141                                         nullptr,
    142                                         ast::TypeDecl::Dtype,
    143                                         true
    144                                         );
    145                                 ast::ObjectDecl * member = new ast::ObjectDecl( *location,
    146                                         toString( "field_", i ),
    147                                         new ast::TypeInstType( typeParam )
    148                                         );
    149                                 decl->params.push_back( typeParam );
    150                                 decl->members.push_back( member );
    151                         }
    152 
    153                         // Empty structures are not standard C. Add a dummy field to
    154                         // empty tuples to silence warnings when a compound literal
    155                         // `_tuple0_` is created.
    156                         if ( tupleSize == 0 ) {
    157                                 decl->members.push_back(
    158                                         new ast::ObjectDecl( *location,
    159                                                 "dummy",
    160                                                 new ast::BasicType( ast::BasicType::SignedInt ),
    161                                                 nullptr,
    162                                                 ast::Storage::Classes(),
    163                                                 // Does this have to be a C linkage?
    164                                                 ast::Linkage::C
    165                                         )
    166                                 );
    167                         }
    168                         typeMap[tupleSize] = decl;
    169                         declsToAddBefore.push_back( decl );
    170                 }
    171 
    172                 ast::StructDecl const * decl = typeMap[ tupleSize ];
    173                 ast::StructInstType * newType =
    174                         new ast::StructInstType( decl, type->qualifiers );
    175                 for ( auto pair : group_iterate( type->types, decl->params ) ) {
    176                         ast::Type const * t = std::get<0>( pair );
    177                         newType->params.push_back(
    178                                 new ast::TypeExpr( *location, ast::deepCopy( t ) ) );
    179                 }
    180                 return newType;
    181         }
    182 
    183         ast::Expr const * postvisit( ast::TupleIndexExpr const * expr ) {
    184                 CodeLocation const & location = expr->location;
    185                 ast::Expr const * tuple = expr->tuple.get();
    186                 assert( tuple );
    187                 unsigned int index = expr->index;
    188                 ast::TypeSubstitution const * env = expr->env.get();
    189 
    190                 if ( auto tupleExpr = dynamic_cast<ast::TupleExpr const *>( tuple ) ) {
    191                         // Optimization: If it is a definitely pure tuple expr,
    192                         // then it can reduce to the only relevant component.
    193                         if ( !maybeImpureIgnoreUnique( tupleExpr ) ) {
    194                                 assert( index < tupleExpr->exprs.size() );
    195                                 ast::ptr<ast::Expr> const & expr =
    196                                         *std::next( tupleExpr->exprs.begin(), index );
    197                                 ast::Expr * ret = ast::mutate( expr.get() );
    198                                 ret->env = env;
    199                                 return ret;
    200                         }
    201                 }
    202 
    203                 auto type = tuple->result.strict_as<ast::StructInstType>();
    204                 ast::StructDecl const * structDecl = type->base;
    205                 assert( index < structDecl->members.size() );
    206                 ast::ptr<ast::Decl> const & member =
    207                         *std::next( structDecl->members.begin(), index );
    208                 ast::MemberExpr * memberExpr = new ast::MemberExpr( location,
    209                         member.strict_as<ast::DeclWithType>(), tuple );
    210                 memberExpr->env = env;
    211                 return memberExpr;
    212         }
    213 private:
    214         ScopedMap< int, ast::StructDecl const * > typeMap;
    215 };
     162                ast::ObjectDecl * member = new ast::ObjectDecl( location,
     163                        toString( "field_", i ),
     164                        new ast::TypeInstType( typeParam )
     165                        );
     166                decl->params.push_back( typeParam );
     167                decl->members.push_back( member );
     168        }
     169
     170        // Empty structures are not standard C. Add a dummy field to
     171        // empty tuples to silence warnings when a compound literal
     172        // `_tuple0_` is created.
     173        if ( tupleSize == 0 ) {
     174                decl->members.push_back(
     175                        new ast::ObjectDecl( location,
     176                                "dummy",
     177                                new ast::BasicType( ast::BasicType::SignedInt ),
     178                                nullptr,
     179                                ast::Storage::Classes(),
     180                                // Does this have to be a C linkage?
     181                                ast::Linkage::C
     182                        )
     183                );
     184        }
     185        return decl;
     186}
     187
     188ast::Type const * TupleMainExpander::postvisit( ast::TupleType const * type ) {
     189        assert( location );
     190        unsigned tupleSize = type->size();
     191        if ( !typeMap.count( tupleSize ) ) {
     192                ast::StructDecl * decl = createTupleStruct( tupleSize, *location );
     193                typeMap[tupleSize] = decl;
     194                declsToAddBefore.push_back( decl );
     195        }
     196
     197        ast::StructDecl const * decl = typeMap[ tupleSize ];
     198        ast::StructInstType * newType =
     199                new ast::StructInstType( decl, type->qualifiers );
     200        for ( auto pair : group_iterate( type->types, decl->params ) ) {
     201                ast::Type const * t = std::get<0>( pair );
     202                newType->params.push_back(
     203                        new ast::TypeExpr( *location, ast::deepCopy( t ) ) );
     204        }
     205        return newType;
     206}
     207
     208// Expand a tuple index into a field access in the underlying structure.
     209ast::Expr const * TupleMainExpander::postvisit(
     210                ast::TupleIndexExpr const * expr ) {
     211        CodeLocation const & location = expr->location;
     212        ast::Expr const * tuple = expr->tuple.get();
     213        assert( tuple );
     214        unsigned int index = expr->index;
     215        ast::TypeSubstitution const * env = expr->env.get();
     216
     217        if ( auto tupleExpr = dynamic_cast<ast::TupleExpr const *>( tuple ) ) {
     218                // Optimization: If it is a definitely pure tuple expr,
     219                // then it can reduce to the only relevant component.
     220                if ( !maybeImpureIgnoreUnique( tupleExpr ) ) {
     221                        assert( index < tupleExpr->exprs.size() );
     222                        ast::ptr<ast::Expr> const & expr =
     223                                *std::next( tupleExpr->exprs.begin(), index );
     224                        ast::Expr * ret = ast::mutate( expr.get() );
     225                        ret->env = env;
     226                        return ret;
     227                }
     228        }
     229
     230        auto type = tuple->result.strict_as<ast::StructInstType>();
     231        ast::StructDecl const * structDecl = type->base;
     232        assert( index < structDecl->members.size() );
     233        ast::ptr<ast::Decl> const & member =
     234                *std::next( structDecl->members.begin(), index );
     235        ast::MemberExpr * memberExpr = new ast::MemberExpr( location,
     236                member.strict_as<ast::DeclWithType>(), tuple );
     237        memberExpr->env = env;
     238        return memberExpr;
     239}
    216240
    217241ast::Expr const * replaceTupleExpr(
     
    249273}
    250274
    251 struct TupleExprExpander final {
    252         ast::Expr const * postvisit( ast::TupleExpr const * expr ) {
    253                 return replaceTupleExpr( expr->location,
    254                         expr->result, expr->exprs, expr->env );
    255         }
    256 };
     275ast::Expr const * TupleExprExpander::postvisit( ast::TupleExpr const * expr ) {
     276        return replaceTupleExpr( expr->location,
     277                expr->result, expr->exprs, expr->env );
     278}
    257279
    258280} // namespace
  • src/Tuples/Tuples.cc

    r9cd5bd2 rdf6cc9d  
    1717
    1818#include "AST/Pass.hpp"
     19#include "AST/Inspect.hpp"
    1920#include "AST/LinkageSpec.hpp"
    2021#include "Common/PassVisitor.h"
     
    8081
    8182                void previsit( ast::ApplicationExpr const * appExpr ) {
    82                         if ( ast::DeclWithType const * function = InitTweak::getFunction( appExpr ) ) {
     83                        if ( ast::DeclWithType const * function = ast::getFunction( appExpr ) ) {
    8384                                if ( function->linkage == ast::Linkage::Intrinsic
    8485                                                && ( function->name == "*?" || function->name == "?[?]" ) ) {
  • src/Validate/FixQualifiedTypes.cpp

    r9cd5bd2 rdf6cc9d  
    102102                        }
    103103
    104 
    105                 auto var = new ast::ObjectDecl( t->var->location, t->name,
    106                          new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall );
    107                         var->scopeLevel = 1; // 1 for now; should copy the scopeLevel of the enumValue
     104                auto var = new ast::ObjectDecl( t->location, t->name,
     105                        new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall );
    108106                        var->mangleName = Mangle::mangle( var );
    109107                        return new ast::VariableExpr( t->location, var );
    110                 // return ret;
    111108        }
    112109
  • src/Validate/LinkReferenceToTypes.cpp

    r9cd5bd2 rdf6cc9d  
    4444        void postvisit( ast::UnionDecl const * decl );
    4545        ast::TraitDecl const * postvisit( ast::TraitDecl const * decl );
    46         ast::QualifiedNameExpr const * previsit( ast::QualifiedNameExpr const * decl);
    4746
    4847private:
     
    203202        }
    204203
     204        // The following section
     205        auto mut = ast::mutate( decl );
     206        std::vector<ast::ptr<ast::Decl>> buffer;
     207        for ( auto it = decl->members.begin(); it != decl->members.end(); ++it) {
     208                auto member = (*it).as<ast::ObjectDecl>();
     209                if ( member->enumInLine ) {
     210                        auto targetEnum = symtab.lookupEnum( member->name );
     211                        if ( targetEnum ) {                     
     212                                for ( auto singleMamber : targetEnum->members ) {
     213                                        auto tm = singleMamber.as<ast::ObjectDecl>();
     214                                        auto t = new ast::ObjectDecl(
     215                                                member->location, // use the "inline" location
     216                                                tm->name,
     217                                                new ast::EnumInstType( decl, ast::CV::Const ),
     218                                                // Construct a new EnumInstType as the type
     219                                                tm->init,
     220                                                tm->storage,
     221                                                tm->linkage,
     222                                                tm->bitfieldWidth,
     223                                                {}, // enum member doesn't have attribute
     224                                                tm->funcSpec
     225                                        );
     226                                        t->importValue = true;
     227                                        buffer.push_back(t);
     228                                }
     229                        }
     230                } else {
     231                        auto search_it = std::find_if( buffer.begin(), buffer.end(), [member](ast::ptr<ast::Decl> cur) {
     232                                auto curAsObjDecl = cur.as<ast::ObjectDecl>();
     233                                return (curAsObjDecl->importValue) && (curAsObjDecl->name == member->name);
     234                        });
     235                        if ( search_it != buffer.end() ) {
     236                                buffer.erase( search_it ); // Found an import enum value that has the same name
     237                                // override the imported value
     238                        }
     239                        buffer.push_back( *it );
     240                }
     241        }
     242        mut->members = buffer;
     243        decl = mut;
     244
    205245        ForwardEnumsType::iterator fwds = forwardEnums.find( decl->name );
    206246        if ( fwds != forwardEnums.end() ) {
     
    284324}
    285325
    286 ast::QualifiedNameExpr const * LinkTypesCore::previsit( ast::QualifiedNameExpr const * decl ) {
    287         // Try to lookup type
    288         if ( auto objDecl = decl->type_decl.as<ast::ObjectDecl>() ) {
    289                 if ( auto inst = objDecl->type.as<ast::TypeInstType>()) {
    290                         if ( auto enumDecl = symtab.lookupEnum ( inst->name ) ) {
    291                                 auto mut = ast::mutate( decl );
    292                                 mut->type_decl = enumDecl;
    293                                 auto enumInst = new ast::EnumInstType( enumDecl );
    294                                 enumInst->name = decl->name;
    295                                 // Adding result; addCandidate() use result
    296                                 mut->result = enumInst;
    297                                 decl = mut;
    298                         }
    299                 }
    300         } else if ( auto enumDecl = decl->type_decl.as<ast::EnumDecl>() ) {
    301                 auto mut = ast::mutate( decl );
    302                 auto enumInst = new ast::EnumInstType( enumDecl );
    303                 enumInst->name = decl->name;
    304                 // Adding result; addCandidate() use result
    305                 mut->result = enumInst;
    306                 decl = mut;
    307         }
    308         // ast::EnumDecl const * decl = symtab.lookupEnum( type->name );
    309         // // It's not a semantic error if the enum is not found, just an implicit forward declaration.
    310         // if ( decl ) {
    311         //      // Just linking in the node.
    312         //      auto mut = ast::mutate( type );
    313         //      mut->base = const_cast<ast::EnumDecl *>( decl );
    314         //      type = mut;
    315         // }
    316         return decl;
    317 }
    318 
    319326} // namespace
    320327
  • src/main.cc

    r9cd5bd2 rdf6cc9d  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Sep 15 13:58:00 2022
    13 // Update Count     : 678
     12// Last Modified On : Wed Oct  5 12:06:00 2022
     13// Update Count     : 679
    1414//
    1515
     
    444444
    445445                PASS( "Instantiate Generics", GenPoly::instantiateGeneric( transUnit ) );
     446                if ( genericsp ) {
     447                        dump( std::move( transUnit ) );
     448                        return EXIT_SUCCESS;
     449                } // if
     450
     451                PASS( "Convert L-Value", GenPoly::convertLvalue( transUnit ) );
    446452
    447453                translationUnit = convert( std::move( transUnit ) );
    448 
    449                 if ( genericsp ) {
    450                         dump( translationUnit );
    451                         return EXIT_SUCCESS;
    452                 } // if
    453 
    454                 PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
    455454
    456455                if ( bboxp ) {
Note: See TracChangeset for help on using the changeset viewer.