source: src/Virtual/Tables.cpp@ 4d5c5b6a

Last change on this file since 4d5c5b6a was d3cf623, checked in by Andrew Beach <ajbeach@…>, 9 months ago

Solved the requested warning with exceptions. Also went through the exceptions tests and managed to remove about 2/3rds of them from the lax list that now either didn't have any warnings or warnings because of the test itself.

  • Property mode set to 100644
File size: 6.6 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.cpp --
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 }
125
126 return inits;
127}
128
129ast::ObjectDecl * makeVtableInstance(
130 CodeLocation const & location,
131 std::string const & name,
132 ast::StructInstType const * vtableType,
133 ast::Type const * objectType,
134 ast::Init const * init ) {
135 assert( vtableType );
136 assert( objectType );
137
138 // Build the initialization.
139 if ( nullptr == init ) {
140 init = new ast::ListInit( location,
141 buildInits( location, vtableType, objectType ) );
142
143 // The provided init should initialize everything except the parent
144 // pointer, the size-of and align-of fields. These should be inserted.
145 } else {
146 // Except this is not yet supported.
147 assert(false);
148 }
149 return makeVtableDeclaration( location, name, vtableType, init );
150}
151
152namespace {
153 std::string const functionName = "get_exception_vtable";
154}
155
156ast::FunctionDecl * makeGetExceptionForward(
157 CodeLocation const & location,
158 ast::Type const * vtableType,
159 ast::Type const * exceptType ) {
160 assert( vtableType );
161 assert( exceptType );
162
163 // If this is called after Fix Return Statements (currently it is in
164 // Implement Concurrent Keywords) then this must be marked as unused
165 // to avoid warnings.
166 ast::ObjectDecl * frontRet = new ast::ObjectDecl( location,
167 "_retvalue",
168 new ast::ReferenceType( vtableType )
169 );
170 frontRet->attributes.emplace_back( new ast::Attribute( "unused" ) );
171
172 return new ast::FunctionDecl(
173 location,
174 functionName,
175 { new ast::ObjectDecl(
176 location,
177 /* The parameter only exists to provide a type id. */ "",
178 new ast::PointerType( exceptType )
179 ) },
180 { frontRet },
181 nullptr,
182 ast::Storage::Classes(),
183 ast::Linkage::Cforall,
184 { new ast::Attribute( "unused" ) }
185 );
186}
187
188ast::FunctionDecl * makeGetExceptionFunction(
189 CodeLocation const & location,
190 ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType ) {
191 assert( vtableInstance );
192 assert( exceptType );
193 ast::FunctionDecl * func = makeGetExceptionForward(
194 location, ast::deepCopy( vtableInstance->type ), exceptType );
195 func->stmts = new ast::CompoundStmt( location, {
196 new ast::ReturnStmt( location, new ast::VariableExpr( location, vtableInstance ) )
197 } );
198 return func;
199}
200
201ast::ObjectDecl * makeTypeIdInstance(
202 CodeLocation const & location,
203 ast::StructInstType const * typeIdType ) {
204 assert( typeIdType );
205 ast::StructInstType * type = ast::mutate( typeIdType );
206 type->set_const( true );
207 std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
208 return new ast::ObjectDecl(
209 location,
210 typeid_name,
211 type,
212 new ast::ListInit( location, {
213 new ast::SingleInit( location,
214 new ast::AddressExpr( location,
215 new ast::NameExpr( location, "__cfatid_exception_t" ) ) )
216 } ),
217 ast::Storage::Classes(),
218 ast::Linkage::Cforall,
219 nullptr,
220 { new ast::Attribute( "cfa_linkonce" ) }
221 );
222}
223
224}
Note: See TracBrowser for help on using the repository browser.