Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Virtual/Tables.cc

    r4f6dda0 raff7e86  
    1010// Created On       : Mon Aug 31 11:11:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Mar 11 10:40:00 2022
    13 // Update Count     : 3
     12// Last Modified On : Wed Apr 21 15:36:00 2021
     13// Update Count     : 2
    1414//
    1515
    16 #include "AST/Attribute.hpp"
    17 #include "AST/Copy.hpp"
    18 #include "AST/Decl.hpp"
    19 #include "AST/Expr.hpp"
    20 #include "AST/Init.hpp"
    21 #include "AST/Stmt.hpp"
    22 #include "AST/Type.hpp"
    2316#include <SynTree/Attribute.h>
    2417#include <SynTree/Declaration.h>
     
    8477}
    8578
    86 static ast::ObjectDecl * makeVtableDeclaration(
    87                 CodeLocation const & location, std::string const & name,
    88                 ast::StructInstType const * type, ast::Init const * init ) {
    89         ast::Storage::Classes storage;
    90         if ( nullptr == init ) {
    91                 storage.is_extern = true;
    92         }
    93         return new ast::ObjectDecl(
    94                 location,
    95                 name,
    96                 type,
    97                 init,
    98                 storage,
    99                 ast::Linkage::Cforall
    100         );
    101 }
    102 
    10379ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
    10480        assert( type );
    10581        return makeVtableDeclaration( name, type, nullptr );
    106 }
    107 
    108 ast::ObjectDecl * makeVtableForward(
    109                 CodeLocation const & location, std::string const & name,
    110                 ast::StructInstType const * vtableType ) {
    111         assert( vtableType );
    112         return makeVtableDeclaration( location, name, vtableType, nullptr );
    11382}
    11483
     
    154123}
    155124
    156 static std::vector<ast::ptr<ast::Init>> buildInits(
    157                 CodeLocation const & location,
    158                 //std::string const & name,
    159                 ast::StructInstType const * vtableType,
    160                 ast::Type const * objectType ) {
    161         ast::StructDecl const * vtableStruct = vtableType->base;
    162 
    163         std::vector<ast::ptr<ast::Init>> inits;
    164         inits.reserve( vtableStruct->members.size() );
    165 
    166         // This is designed to run before the resolver.
    167         for ( auto field : vtableStruct->members ) {
    168                 if ( std::string( "parent" ) == field->name ) {
    169                         // This will not work with polymorphic state.
    170                         auto oField = field.strict_as<ast::ObjectDecl>();
    171                         auto fieldType = oField->type.strict_as<ast::PointerType>();
    172                         auto parentType = fieldType->base.strict_as<ast::StructInstType>();
    173                         std::string const & parentInstance = instanceName( parentType->name );
    174                         inits.push_back(
    175                                         new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, parentInstance ) ) ) );
    176                 } else if ( std::string( "__cfavir_typeid" ) == field->name ) {
    177                         std::string const & baseType = baseTypeName( vtableType->name );
    178                         std::string const & typeId = typeIdName( baseType );
    179                         inits.push_back( new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, typeId ) ) ) );
    180                 } else if ( std::string( "size" ) == field->name ) {
    181                         inits.push_back( new ast::SingleInit( location, new ast::SizeofExpr( location, objectType )
    182                         ) );
    183                 } else if ( std::string( "align" ) == field->name ) {
    184                         inits.push_back( new ast::SingleInit( location,
    185                                 new ast::AlignofExpr( location, objectType )
    186                         ) );
    187                 } else {
    188                         inits.push_back( new ast::SingleInit( location,
    189                                 new ast::NameExpr( location, field->name )
    190                         ) );
    191                 }
    192                 //ast::Expr * expr = buildInitExpr(...);
    193                 //inits.push_back( new ast::SingleInit( location, expr ) )
    194         }
    195 
    196         return inits;
    197 }
    198 
    199 ast::ObjectDecl * makeVtableInstance(
    200                 CodeLocation const & location,
    201                 std::string const & name,
    202                 ast::StructInstType const * vtableType,
    203                 ast::Type const * objectType,
    204                 ast::Init const * init ) {
    205         assert( vtableType );
    206         assert( objectType );
    207 
    208         // Build the initialization.
    209         if ( nullptr == init ) {
    210                 init = new ast::ListInit( location,
    211                         buildInits( location, vtableType, objectType ) );
    212 
    213         // The provided init should initialize everything except the parent
    214         // pointer, the size-of and align-of fields. These should be inserted.
    215         } else {
    216                 // Except this is not yet supported.
    217                 assert(false);
    218         }
    219         return makeVtableDeclaration( location, name, vtableType, init );
    220 }
    221 
    222125namespace {
    223126        std::string const functionName = "get_exception_vtable";
     
    237140                new ReferenceType( noQualifiers, vtableType ),
    238141                nullptr,
    239                 { new Attribute("unused") }
     142        { new Attribute("unused") }
    240143        ) );
    241144        type->parameters.push_back( new ObjectDecl(
     
    257160}
    258161
    259 ast::FunctionDecl * makeGetExceptionForward(
    260                 CodeLocation const & location,
    261                 ast::Type const * vtableType,
    262                 ast::Type const * exceptType ) {
    263         assert( vtableType );
    264         assert( exceptType );
    265         return new ast::FunctionDecl(
    266                 location,
    267                 functionName,
    268                 { /* forall */ },
    269                 { new ast::ObjectDecl(
    270                         location,
    271                         "__unused",
    272                         new ast::PointerType( exceptType )
    273                 ) },
    274                 { new ast::ObjectDecl(
    275                         location,
    276                         "_retvalue",
    277                         new ast::ReferenceType( vtableType )
    278                 ) },
    279                 nullptr,
    280                 ast::Storage::Classes(),
    281                 ast::Linkage::Cforall,
    282                 { new ast::Attribute( "unused" ) }
    283         );
    284 }
    285 
    286162FunctionDecl * makeGetExceptionFunction(
    287163                ObjectDecl * vtableInstance, Type * exceptType ) {
     
    292168        func->statements = new CompoundStmt( {
    293169                new ReturnStmt( new VariableExpr( vtableInstance ) ),
    294         } );
    295         return func;
    296 }
    297 
    298 ast::FunctionDecl * makeGetExceptionFunction(
    299                 CodeLocation const & location,
    300                 ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType ) {
    301         assert( vtableInstance );
    302         assert( exceptType );
    303         ast::FunctionDecl * func = makeGetExceptionForward(
    304                         location, ast::deepCopy( vtableInstance->type ), exceptType );
    305         func->stmts = new ast::CompoundStmt( location, {
    306                 new ast::ReturnStmt( location, new ast::VariableExpr( location, vtableInstance ) )
    307170        } );
    308171        return func;
     
    328191}
    329192
    330 ast::ObjectDecl * makeTypeIdInstance(
    331                 CodeLocation const & location,
    332                 ast::StructInstType const * typeIdType ) {
    333         assert( typeIdType );
    334         ast::StructInstType * type = ast::mutate( typeIdType );
    335         type->set_const( true );
    336         std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
    337         return new ast::ObjectDecl(
    338                 location,
    339                 typeid_name,
    340                 type,
    341                 new ast::ListInit( location, {
    342                         new ast::SingleInit( location,
    343                                 new ast::AddressExpr( location,
    344                                         new ast::NameExpr( location, "__cfatid_exception_t" ) ) )
    345                 } ),
    346                 ast::Storage::Classes(),
    347                 ast::Linkage::Cforall,
    348                 nullptr,
    349                 { new ast::Attribute( "cfa_linkonce" ) }
    350         );
    351193}
    352 
    353 }
Note: See TracChangeset for help on using the changeset viewer.