Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Virtual/Tables.cc

    rc6b4432 r4f6dda0  
    2121#include "AST/Stmt.hpp"
    2222#include "AST/Type.hpp"
     23#include <SynTree/Attribute.h>
     24#include <SynTree/Declaration.h>
     25#include <SynTree/Expression.h>
     26#include <SynTree/Statement.h>
     27#include <SynTree/Type.h>
    2328
    2429namespace Virtual {
     
    6065        return 17 < name.size() && '_' == name[0] &&
    6166                std::string("_vtable_instance") == name.substr(1, name.size() - 17);
     67}
     68
     69static ObjectDecl * makeVtableDeclaration(
     70                std::string const & name,
     71                StructInstType * type, Initializer * init ) {
     72        Type::StorageClasses storage = noStorageClasses;
     73        if ( nullptr == init ) {
     74                storage.is_extern = true;
     75        }
     76        return new ObjectDecl(
     77                name,
     78                storage,
     79                LinkageSpec::Cforall,
     80                nullptr,
     81                type,
     82                init
     83        );
    6284}
    6385
     
    79101}
    80102
     103ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
     104        assert( type );
     105        return makeVtableDeclaration( name, type, nullptr );
     106}
     107
    81108ast::ObjectDecl * makeVtableForward(
    82109                CodeLocation const & location, std::string const & name,
     
    84111        assert( vtableType );
    85112        return makeVtableDeclaration( location, name, vtableType, nullptr );
     113}
     114
     115ObjectDecl * makeVtableInstance(
     116                std::string const & name, StructInstType * vtableType,
     117                Type * objectType, Initializer * init ) {
     118        assert( vtableType );
     119        assert( objectType );
     120        StructDecl * vtableStruct = vtableType->baseStruct;
     121        // Build the initialization
     122        if ( nullptr == init ) {
     123                std::list< Initializer * > inits;
     124
     125                // This is going to have to be run before the resolver to connect expressions.
     126                for ( auto field : vtableStruct->members ) {
     127                        if ( std::string( "parent" ) == field->name ) {
     128                                // This will not work with polymorphic state.
     129                                auto oField = strict_dynamic_cast< ObjectDecl * >( field );
     130                                auto fieldType = strict_dynamic_cast< PointerType * >( oField->type );
     131                                auto parentType = strict_dynamic_cast< StructInstType * >( fieldType->base );
     132                                std::string const & parentInstance = instanceName( parentType->name );
     133                                inits.push_back(
     134                                                new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
     135                        } else if ( std::string( "__cfavir_typeid" ) == field->name ) {
     136                                std::string const & baseType = baseTypeName( vtableType->name );
     137                                std::string const & typeId = typeIdName( baseType );
     138                                inits.push_back( new SingleInit( new AddressExpr( new NameExpr( typeId ) ) ) );
     139                        } else if ( std::string( "size" ) == field->name ) {
     140                                inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
     141                        } else if ( std::string( "align" ) == field->name ) {
     142                                inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );
     143                        } else {
     144                                inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
     145                        }
     146                }
     147                init = new ListInit( inits );
     148        // This should initialize everything except the parent pointer, the
     149        // size-of and align-of fields. These should be inserted.
     150        } else {
     151                assert(false);
     152        }
     153        return makeVtableDeclaration( name, vtableType, init );
    86154}
    87155
     
    156224}
    157225
     226FunctionDecl * makeGetExceptionForward(
     227                Type * vtableType, Type * exceptType ) {
     228        assert( vtableType );
     229        assert( exceptType );
     230        FunctionType * type = new FunctionType( noQualifiers, false );
     231        vtableType->tq.is_const = true;
     232        type->returnVals.push_back( new ObjectDecl(
     233                "_retvalue",
     234                noStorageClasses,
     235                LinkageSpec::Cforall,
     236                nullptr,
     237                new ReferenceType( noQualifiers, vtableType ),
     238                nullptr,
     239                { new Attribute("unused") }
     240        ) );
     241        type->parameters.push_back( new ObjectDecl(
     242                "__unused",
     243                noStorageClasses,
     244                LinkageSpec::Cforall,
     245                nullptr,
     246                new PointerType( noQualifiers, exceptType ),
     247                nullptr,
     248                { new Attribute("unused") }
     249        ) );
     250        return new FunctionDecl(
     251                functionName,
     252                noStorageClasses,
     253                LinkageSpec::Cforall,
     254                type,
     255                nullptr
     256        );
     257}
     258
    158259ast::FunctionDecl * makeGetExceptionForward(
    159260                CodeLocation const & location,
     
    183284}
    184285
     286FunctionDecl * makeGetExceptionFunction(
     287                ObjectDecl * vtableInstance, Type * exceptType ) {
     288        assert( vtableInstance );
     289        assert( exceptType );
     290        FunctionDecl * func = makeGetExceptionForward(
     291                vtableInstance->type->clone(), exceptType );
     292        func->statements = new CompoundStmt( {
     293                new ReturnStmt( new VariableExpr( vtableInstance ) ),
     294        } );
     295        return func;
     296}
     297
    185298ast::FunctionDecl * makeGetExceptionFunction(
    186299                CodeLocation const & location,
     
    196309}
    197310
     311ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) {
     312        assert( typeIdType );
     313        StructInstType * type = typeIdType->clone();
     314        type->tq.is_const = true;
     315        std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
     316        return new ObjectDecl(
     317                typeid_name,
     318                noStorageClasses,
     319                LinkageSpec::Cforall,
     320                /* bitfieldWidth */ nullptr,
     321                type,
     322                new ListInit( { new SingleInit(
     323                        new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
     324                        ) } ),
     325                { new Attribute( "cfa_linkonce", {} ) },
     326                noFuncSpecifiers
     327        );
     328}
     329
    198330ast::ObjectDecl * makeTypeIdInstance(
    199331                CodeLocation const & location,
Note: See TracChangeset for help on using the changeset viewer.