Changeset df6cc9d for src/AST


Ignore:
Timestamp:
Oct 19, 2022, 4:43:26 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, stuck-waitfor-destruct
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/AST
Files:
11 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        }
Note: See TracChangeset for help on using the changeset viewer.