source: src/Virtual/Tables.cc

Last change on this file was 37273c8, checked in by Andrew Beach <ajbeach@…>, 5 months ago

Removed the old-ast-compatable FunctionDecl? constructor. However, enough cases pass nothing polymorphic along some of the uses of the constructor now go to a new monomorphic function constructor.

  • Property mode set to 100644
File size: 6.4 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 : 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"
23
24namespace Virtual {
25
26std::string typeIdType( std::string const & type_name ) {
27        return "__cfatid_struct_" + type_name;
28}
29
30std::string typeIdName( std::string const & type_name ) {
31        return "__cfatid_" + type_name;
32}
33
34static std::string typeIdTypeToInstance( std::string const & type_name ) {
35        return typeIdName(type_name.substr(16));
36}
37
38std::string vtableTypeName( std::string const & name ) {
39        return name + "_vtable";
40}
41
42std::string baseTypeName( std::string const & vtable_type_name ) {
43        return vtable_type_name.substr(0, vtable_type_name.size() - 7);
44}
45
46std::string instanceName( std::string const & name ) {
47        return std::string("_") + name + "_instance";
48}
49
50std::string vtableInstanceName( std::string const & name ) {
51        return instanceName( vtableTypeName( name ) );
52}
53
54std::string concurrentDefaultVTableName() {
55        return "_default_vtable";
56}
57
58bool isVTableInstanceName( std::string const & name ) {
59        // There are some delicate length calculations here.
60        return 17 < name.size() && '_' == name[0] &&
61                std::string("_vtable_instance") == name.substr(1, name.size() - 17);
62}
63
64static ast::ObjectDecl * makeVtableDeclaration(
65                CodeLocation const & location, std::string const & name,
66                ast::StructInstType const * type, ast::Init const * init ) {
67        ast::Storage::Classes storage;
68        if ( nullptr == init ) {
69                storage.is_extern = true;
70        }
71        return new ast::ObjectDecl(
72                location,
73                name,
74                type,
75                init,
76                storage,
77                ast::Linkage::Cforall
78        );
79}
80
81ast::ObjectDecl * makeVtableForward(
82                CodeLocation const & location, std::string const & name,
83                ast::StructInstType const * vtableType ) {
84        assert( vtableType );
85        return makeVtableDeclaration( location, name, vtableType, nullptr );
86}
87
88static std::vector<ast::ptr<ast::Init>> buildInits(
89                CodeLocation const & location,
90                //std::string const & name,
91                ast::StructInstType const * vtableType,
92                ast::Type const * objectType ) {
93        ast::StructDecl const * vtableStruct = vtableType->base;
94
95        std::vector<ast::ptr<ast::Init>> inits;
96        inits.reserve( vtableStruct->members.size() );
97
98        // This is designed to run before the resolver.
99        for ( auto field : vtableStruct->members ) {
100                if ( std::string( "parent" ) == field->name ) {
101                        // This will not work with polymorphic state.
102                        auto oField = field.strict_as<ast::ObjectDecl>();
103                        auto fieldType = oField->type.strict_as<ast::PointerType>();
104                        auto parentType = fieldType->base.strict_as<ast::StructInstType>();
105                        std::string const & parentInstance = instanceName( parentType->name );
106                        inits.push_back(
107                                        new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, parentInstance ) ) ) );
108                } else if ( std::string( "__cfavir_typeid" ) == field->name ) {
109                        std::string const & baseType = baseTypeName( vtableType->name );
110                        std::string const & typeId = typeIdName( baseType );
111                        inits.push_back( new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, typeId ) ) ) );
112                } else if ( std::string( "size" ) == field->name ) {
113                        inits.push_back( new ast::SingleInit( location, new ast::SizeofExpr( location, objectType )
114                        ) );
115                } else if ( std::string( "align" ) == field->name ) {
116                        inits.push_back( new ast::SingleInit( location,
117                                new ast::AlignofExpr( location, objectType )
118                        ) );
119                } else {
120                        inits.push_back( new ast::SingleInit( location,
121                                new ast::NameExpr( location, field->name )
122                        ) );
123                }
124                //ast::Expr * expr = buildInitExpr(...);
125                //inits.push_back( new ast::SingleInit( location, expr ) )
126        }
127
128        return inits;
129}
130
131ast::ObjectDecl * makeVtableInstance(
132                CodeLocation const & location,
133                std::string const & name,
134                ast::StructInstType const * vtableType,
135                ast::Type const * objectType,
136                ast::Init const * init ) {
137        assert( vtableType );
138        assert( objectType );
139
140        // Build the initialization.
141        if ( nullptr == init ) {
142                init = new ast::ListInit( location,
143                        buildInits( location, vtableType, objectType ) );
144
145        // The provided init should initialize everything except the parent
146        // pointer, the size-of and align-of fields. These should be inserted.
147        } else {
148                // Except this is not yet supported.
149                assert(false);
150        }
151        return makeVtableDeclaration( location, name, vtableType, init );
152}
153
154namespace {
155        std::string const functionName = "get_exception_vtable";
156}
157
158ast::FunctionDecl * makeGetExceptionForward(
159                CodeLocation const & location,
160                ast::Type const * vtableType,
161                ast::Type const * exceptType ) {
162        assert( vtableType );
163        assert( exceptType );
164        return new ast::FunctionDecl(
165                location,
166                functionName,
167                { new ast::ObjectDecl(
168                        location,
169                        "__unused",
170                        new ast::PointerType( exceptType )
171                ) },
172                { new ast::ObjectDecl(
173                        location,
174                        "_retvalue",
175                        new ast::ReferenceType( vtableType )
176                ) },
177                nullptr,
178                ast::Storage::Classes(),
179                ast::Linkage::Cforall,
180                { new ast::Attribute( "unused" ) }
181        );
182}
183
184ast::FunctionDecl * makeGetExceptionFunction(
185                CodeLocation const & location,
186                ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType ) {
187        assert( vtableInstance );
188        assert( exceptType );
189        ast::FunctionDecl * func = makeGetExceptionForward(
190                        location, ast::deepCopy( vtableInstance->type ), exceptType );
191        func->stmts = new ast::CompoundStmt( location, {
192                new ast::ReturnStmt( location, new ast::VariableExpr( location, vtableInstance ) )
193        } );
194        return func;
195}
196
197ast::ObjectDecl * makeTypeIdInstance(
198                CodeLocation const & location,
199                ast::StructInstType const * typeIdType ) {
200        assert( typeIdType );
201        ast::StructInstType * type = ast::mutate( typeIdType );
202        type->set_const( true );
203        std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
204        return new ast::ObjectDecl(
205                location,
206                typeid_name,
207                type,
208                new ast::ListInit( location, {
209                        new ast::SingleInit( location,
210                                new ast::AddressExpr( location,
211                                        new ast::NameExpr( location, "__cfatid_exception_t" ) ) )
212                } ),
213                ast::Storage::Classes(),
214                ast::Linkage::Cforall,
215                nullptr,
216                { new ast::Attribute( "cfa_linkonce" ) }
217        );
218}
219
220}
Note: See TracBrowser for help on using the repository browser.