source: src/Virtual/Tables.cc@ f2898df

Last change on this file since f2898df was 37273c8, checked in by Andrew Beach <ajbeach@…>, 22 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.