Ignore:
Timestamp:
Mar 11, 2022, 1:56:07 PM (2 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
623d1c8
Parents:
eb3bc52 (diff), 630c4bb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Virtual/Tables.cc

    reb3bc52 r510e6f9  
    1010// Created On       : Mon Aug 31 11:11:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Apr 21 15:36:00 2021
    13 // Update Count     : 2
    14 //
    15 
     12// Last Modified On : Fri Mar 11 10:40:00 2022
     13// Update Count     : 3
     14//
     15
     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"
    1623#include <SynTree/Attribute.h>
    1724#include <SynTree/Declaration.h>
     
    7784}
    7885
     86static 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
    79103ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
    80104        assert( type );
    81105        return makeVtableDeclaration( name, type, nullptr );
     106}
     107
     108ast::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 );
    82113}
    83114
     
    123154}
    124155
     156static 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
     199ast::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
    125222namespace {
    126223        std::string const functionName = "get_exception_vtable";
     
    140237                new ReferenceType( noQualifiers, vtableType ),
    141238                nullptr,
    142         { new Attribute("unused") }
     239                { new Attribute("unused") }
    143240        ) );
    144241        type->parameters.push_back( new ObjectDecl(
     
    157254                type,
    158255                nullptr
     256        );
     257}
     258
     259ast::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" ) }
    159283        );
    160284}
     
    172296}
    173297
     298ast::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 ) )
     307        } );
     308        return func;
     309}
     310
    174311ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) {
    175312        assert( typeIdType );
     
    191328}
    192329
    193 }
     330ast::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        );
     351}
     352
     353}
Note: See TracChangeset for help on using the changeset viewer.