source: src/Virtual/Tables.cc @ 69c5c00

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

Rework exceptions mark_exception -> get_exception_vtable and the needed follow up.

  • Property mode set to 100644
File size: 4.2 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/Attribute.h>
17#include <SynTree/Declaration.h>
18#include <SynTree/Expression.h>
19#include <SynTree/Statement.h>
20#include <SynTree/Type.h>
21
22namespace Virtual {
23
24std::string vtableTypeName( std::string const & name ) {
25        return name + "_vtable";
26}
27
28std::string instanceName( std::string const & name ) {
29        return std::string("_") + name + "_instance";
30}
31
32std::string vtableInstanceName( std::string const & name ) {
33        return instanceName( vtableTypeName( name ) );
34}
35
36bool isVTableInstanceName( std::string const & name ) {
37        // There are some delicate length calculations here.
38        return 17 < name.size() && '_' == name[0] &&
39                std::string("_vtable_instance") == name.substr(1, name.size() - 17);
40}
41
42static ObjectDecl * makeVtableDeclaration(
43                StructInstType * type, Initializer * init ) {
44        std::string const & name = instanceName( type->name );
45        Type::StorageClasses storage = noStorageClasses;
46        if ( nullptr == init ) {
47                storage.is_extern = true;
48        }
49        return new ObjectDecl(
50                name,
51                storage,
52                LinkageSpec::Cforall,
53                nullptr,
54                type,
55                init
56        );
57}
58
59ObjectDecl * makeVtableForward( StructInstType * type ) {
60        assert( type );
61        return makeVtableDeclaration( type, nullptr );
62}
63
64ObjectDecl * makeVtableInstance(
65                StructInstType * vtableType, Type * objectType, Initializer * init ) {
66        assert( vtableType );
67        assert( objectType );
68        StructDecl * vtableStruct = vtableType->baseStruct;
69        // Build the initialization
70        if ( nullptr == init ) {
71                std::list< Initializer * > inits;
72
73                // This is going to have to be run before the resolver to connect expressions.
74                for ( auto field : vtableStruct->members ) {
75                        if ( std::string( "parent" ) == field->name ) {
76                                // This will not work with polymorphic state.
77                                auto oField = strict_dynamic_cast< ObjectDecl * >( field );
78                                auto fieldType = strict_dynamic_cast< PointerType * >( oField->type );
79                                auto parentType = strict_dynamic_cast< StructInstType * >( fieldType->base );
80                                std::string const & parentInstance = instanceName( parentType->name );
81                                inits.push_back(
82                                                new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
83                        } else if ( std::string( "size" ) == field->name ) {
84                                inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
85                        } else if ( std::string( "align" ) == field->name ) {
86                                inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );
87                        } else {
88                                inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
89                        }
90                }
91                init = new ListInit( inits );
92        // This should initialize everything except the parent pointer, the
93        // size-of and align-of fields. These should be inserted.
94        } else {
95                assert(false);
96        }
97        return makeVtableDeclaration( vtableType, init );
98}
99
100namespace {
101        std::string const functionName = "get_exception_vtable";
102}
103
104FunctionDecl * makeGetExceptionForward(
105                Type * vtableType, Type * exceptType ) {
106        assert( vtableType );
107        assert( exceptType );
108        FunctionType * type = new FunctionType( noQualifiers, false );
109        vtableType->tq.is_const = true;
110        type->returnVals.push_back( new ObjectDecl(
111                "_retvalue",
112                noStorageClasses,
113                LinkageSpec::Cforall,
114                nullptr,
115                new ReferenceType( noQualifiers, vtableType ),
116                nullptr,
117        { new Attribute("unused") }
118        ) );
119        type->parameters.push_back( new ObjectDecl(
120                "__unused",
121                noStorageClasses,
122                LinkageSpec::Cforall,
123                nullptr,
124                new PointerType( noQualifiers, exceptType ),
125                nullptr,
126                { new Attribute("unused") }
127        ) );
128        return new FunctionDecl(
129                functionName,
130                noStorageClasses,
131                LinkageSpec::Cforall,
132                type,
133                nullptr
134        );
135}
136
137FunctionDecl * makeGetExceptionFunction(
138                ObjectDecl * vtableInstance, Type * exceptType ) {
139        assert( vtableInstance );
140        assert( exceptType );
141        FunctionDecl * func = makeGetExceptionForward(
142                vtableInstance->type->clone(), exceptType );
143        func->statements = new CompoundStmt( {
144                new ReturnStmt( new VariableExpr( vtableInstance ) ),
145        } );
146        return func;
147}
148
149}
Note: See TracBrowser for help on using the repository browser.