source: src/Virtual/Tables.cc @ 91fb850

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 91fb850 was 1c01c58, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Rather large commit to get coroutine cancellation working.

This includes what you would expect, like new code in exceptions and a new
test, but it also includes a bunch of other things.

New coroutine state, currently just marks that the stack was cancelled. New
helpers for checking code structure and generating vtables. Changes to the
coroutine interface so resume may throw exceptions on cancellation, plus the
exception type that is thrown. Changes to the coroutine keyword generation to
generate exception code for each type of coroutine.

  • Property mode set to 100644
File size: 3.8 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Tables.cc --
8//
9// Author           : Andrew Beach
10// Created On       : Mon Aug 31 11:11:00 2020
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue Sep  3 14:56:00 2020
13// Update Count     : 0
14//
15
16#include <SynTree/Declaration.h>
17#include <SynTree/Expression.h>
18#include <SynTree/Type.h>
19
20namespace Virtual {
21
22std::string vtableTypeName( std::string const & name ) {
23        return name + "_vtable";
24}
25
26std::string instanceName( std::string const & name ) {
27        return std::string("_") + name + "_instance";
28}
29
30std::string vtableInstanceName( std::string const & name ) {
31        return instanceName( vtableTypeName( name ) );
32}
33
34bool isVTableInstanceName( std::string const & name ) {
35        // There are some delicate length calculations here.
36        return 17 < name.size() && '_' == name[0] &&
37                std::string("_vtable_instance") == name.substr(1, name.size() - 17);
38}
39
40// Fuse base polymorphic declaration and forall arguments into a new type.
41static StructInstType * vtableInstType(
42                StructDecl * polyDecl, std::list< Expression * > && parameters ) {
43        assert( parameters.size() == polyDecl->parameters.size() );
44        StructInstType * type = new StructInstType(
45                        Type::Qualifiers( /* Type::Const */ ), polyDecl );
46        type->parameters = std::move( parameters );
47        return type;
48}
49
50static ObjectDecl * makeVtableDeclaration(
51                StructInstType * type, Initializer * init ) {
52        std::string const & name = instanceName( type->name );
53        Type::StorageClasses storage = noStorageClasses;
54        if ( nullptr == init ) {
55                storage.is_extern = true;
56        }
57        return new ObjectDecl(
58                name,
59                storage,
60                LinkageSpec::Cforall,
61                nullptr,
62                type,
63                init
64        );
65}
66
67ObjectDecl * makeVtableForward( StructInstType * type ) {
68        return makeVtableDeclaration( type, nullptr );
69}
70
71ObjectDecl * makeVtableForward(
72                StructDecl * polyDecl, std::list< Expression * > && parameters ) {
73        return makeVtableForward( vtableInstType( polyDecl, std::move( parameters ) ) );
74}
75
76ObjectDecl * makeVtableInstance(
77                StructInstType * vtableType, Type * vobject_type, Initializer * init ) {
78        StructDecl * vtableStruct = vtableType->baseStruct;
79        // Build the initialization
80        if ( nullptr == init ) {
81                std::list< Initializer * > inits;
82
83                // This is going to have to be run before the resolver to connect expressions.
84                for ( auto field : vtableStruct->members ) {
85                        if ( std::string( "parent" ) == field->name ) {
86                                // This will not work with polymorphic state.
87                                auto oField = strict_dynamic_cast< ObjectDecl * >( field );
88                                auto fieldType = strict_dynamic_cast< PointerType * >( oField->type );
89                                auto parentType = strict_dynamic_cast< StructInstType * >( fieldType->base );
90                                std::string const & parentInstance = instanceName( parentType->name );
91                                inits.push_back(
92                                                new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
93                        } else if ( std::string( "size" ) == field->name ) {
94                                inits.push_back( new SingleInit( new SizeofExpr( vobject_type->clone() ) ) );
95                        } else if ( std::string( "align" ) == field->name ) {
96                                inits.push_back( new SingleInit( new AlignofExpr( vobject_type->clone() ) ) );
97                        } else {
98                                inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
99                        }
100                }
101                init = new ListInit( inits );
102        // This should initialize everything except the parent pointer, the
103        // size-of and align-of fields. These should be inserted.
104        } else {
105                assert(false);
106        }
107        return makeVtableDeclaration( vtableType, init );
108}
109
110ObjectDecl * makeVtableInstance(
111                StructDecl * polyDecl, std::list< Expression * > && parameters,
112                Type * vobject, Initializer * init ) {
113        return makeVtableInstance(
114                vtableInstType( polyDecl, std::move( parameters ) ), vobject, init );
115}
116
117}
Note: See TracBrowser for help on using the repository browser.