source: src/ControlStruct/ExceptDecl.cc@ a5a6a1a8

ADT ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since a5a6a1a8 was aa882e7e, checked in by Henry Xue <y58xue@…>, 4 years ago

Translate virtual table declarations

  • Property mode set to 100644
File size: 10.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// ExceptDecl.cc --
8//
9// Author : Henry Xue
10// Created On : Tue Jul 20 04:10:50 2021
11// Last Modified By : Henry Xue
12// Last Modified On : Thu Jul 22 10:40:55 2021
13// Update Count : 2
14//
15
16#include "ExceptDecl.h"
17
18#include "Common/PassVisitor.h" // for PassVisitor
19#include "SynTree/Mutator.h" // for mutateAll
20#include "Virtual/Tables.h" // for helpers
21
22namespace ControlStruct {
23
24StructDecl * ehmTypeIdStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
25 StructDecl * structDecl = new StructDecl( Virtual::typeIdType( exceptionName ) );
26 structDecl->members.push_back( new ObjectDecl(
27 "parent",
28 noStorageClasses,
29 LinkageSpec::Cforall,
30 nullptr,
31 new PointerType( noQualifiers,
32 new TypeInstType( Type::Const, "__cfavir_type_info", false ) ),
33 nullptr
34 ) );
35 structDecl->set_body( true );
36 if ( parameters ) {
37 structDecl->parameters = *parameters;
38 }
39 return structDecl;
40}
41
42ObjectDecl * ehmTypeIdValue( const std::string & exceptionName, std::list< Expression *> * parameters ) {
43 StructInstType * structInstType = new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) );
44 if ( parameters ) {
45 structInstType->parameters = *parameters;
46 }
47 return new ObjectDecl(
48 Virtual::typeIdName( exceptionName ),
49 noStorageClasses,
50 LinkageSpec::Cforall,
51 nullptr,
52 structInstType,
53 new ListInit( { new SingleInit(
54 new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
55 ) }, {}, true ),
56 { new Attribute( "cfa_linkonce" ) }
57 );
58}
59
60StructDecl * ehmExceptionStructDecl( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
61 StructDecl * structDecl = new StructDecl( exceptionName );
62 if ( parameters ) {
63 structDecl->parameters = *parameters;
64 }
65 return structDecl;
66}
67
68StructDecl * ehmVirtualTableStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
69 // _EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid;
70 ObjectDecl * typeId = new ObjectDecl(
71 "__cfavir_typeid",
72 noStorageClasses,
73 LinkageSpec::Cforall,
74 nullptr,
75 new PointerType( noQualifiers,
76 new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) ) ),
77 nullptr
78 );
79
80 // size_t size;
81 ObjectDecl * size = new ObjectDecl(
82 "size",
83 noStorageClasses,
84 LinkageSpec::Cforall,
85 nullptr,
86 new TypeInstType( noQualifiers, "size_t", false ),
87 nullptr
88 );
89
90 // void (*copy)(exception_name parameters * this, exception_name parameters * other);
91 FunctionType * copyFnType = new FunctionType( noQualifiers, false );
92 copyFnType->get_parameters().push_back( new ObjectDecl(
93 "this",
94 noStorageClasses,
95 LinkageSpec::Cforall,
96 nullptr,
97 new PointerType( noQualifiers,
98 new TypeInstType( noQualifiers, exceptionName, false ) ),
99 nullptr
100 ) );
101 copyFnType->get_parameters().push_back( new ObjectDecl(
102 "other",
103 noStorageClasses,
104 LinkageSpec::Cforall,
105 nullptr,
106 new PointerType( noQualifiers,
107 new TypeInstType( noQualifiers, exceptionName, false ) ),
108 nullptr
109 ) );
110 copyFnType->get_returnVals().push_back( new ObjectDecl(
111 "",
112 noStorageClasses,
113 LinkageSpec::Cforall,
114 nullptr,
115 new VoidType( noQualifiers ),
116 nullptr
117 ) );
118 ObjectDecl * copy = new ObjectDecl(
119 "copy",
120 noStorageClasses,
121 LinkageSpec::Cforall,
122 nullptr,
123 new PointerType( noQualifiers, copyFnType ),
124 nullptr
125 );
126
127 // void (*^?{})(exception_name parameters & this);
128 FunctionType * dtorFnType = new FunctionType( noQualifiers, false );
129 dtorFnType->get_parameters().push_back( new ObjectDecl(
130 "this",
131 noStorageClasses,
132 LinkageSpec::Cforall,
133 nullptr,
134 new ReferenceType( noQualifiers,
135 new TypeInstType( noQualifiers, exceptionName, false ) ),
136 nullptr
137 ) );
138 dtorFnType->get_returnVals().push_back( new ObjectDecl(
139 "",
140 noStorageClasses,
141 LinkageSpec::Cforall,
142 nullptr,
143 new VoidType( noQualifiers ),
144 nullptr
145 ) );
146 ObjectDecl * dtor = new ObjectDecl(
147 "^?{}",
148 noStorageClasses,
149 LinkageSpec::Cforall,
150 nullptr,
151 new PointerType( noQualifiers, dtorFnType ),
152 nullptr
153 );
154
155 // const char * (*msg)(exception_name parameters * this);
156 FunctionType * msgFnType = new FunctionType( noQualifiers, false );
157 msgFnType->get_parameters().push_back( new ObjectDecl(
158 "this",
159 noStorageClasses,
160 LinkageSpec::Cforall,
161 nullptr,
162 new PointerType( noQualifiers,
163 new TypeInstType( noQualifiers, exceptionName, false ) ),
164 nullptr
165 ) );
166 msgFnType->get_returnVals().push_back( new ObjectDecl(
167 "",
168 noStorageClasses,
169 LinkageSpec::Cforall,
170 nullptr,
171 new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
172 nullptr
173 ) );
174 ObjectDecl * msg = new ObjectDecl(
175 "msg",
176 noStorageClasses,
177 LinkageSpec::Cforall,
178 nullptr,
179 new PointerType( noQualifiers, msgFnType ),
180 nullptr
181 );
182
183 StructDecl * structDecl = new StructDecl( Virtual::vtableTypeName( exceptionName ) );
184 structDecl->members.push_back( typeId );
185 structDecl->members.push_back( size );
186 structDecl->members.push_back( copy );
187 structDecl->members.push_back( dtor );
188 structDecl->members.push_back( msg );
189 structDecl->set_body( true );
190 if ( parameters ) {
191 structDecl->parameters = *parameters;
192 }
193 return structDecl;
194}
195
196StructDecl * ehmExceptionStruct( const std::string & exceptionName, const std::list<Declaration*> & members,
197 std::list<TypeDecl *> * parameters ) {
198 StructDecl * structDecl = new StructDecl( exceptionName );
199 structDecl->members = members;
200 structDecl->members.push_front( new ObjectDecl(
201 "virtual_table",
202 noStorageClasses,
203 LinkageSpec::Cforall,
204 nullptr,
205 new PointerType( noQualifiers,
206 new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ) ),
207 nullptr
208 ) );
209 structDecl->set_body( true );
210 if ( parameters ) {
211 structDecl->parameters = *parameters;
212 }
213 return structDecl;
214}
215
216ObjectDecl * ehmExternVtable( const std::string & exceptionName, const std::string & tableName,
217 std::list< Expression *> * parameters ) {
218 StructInstType * structInstType = new StructInstType( Type::Const, Virtual::vtableTypeName(exceptionName) );
219 if ( parameters ) {
220 structInstType->parameters = *parameters;
221 }
222 return new ObjectDecl(
223 tableName,
224 Type::Extern,
225 LinkageSpec::Cforall,
226 nullptr,
227 structInstType,
228 nullptr
229 );
230}
231
232FunctionDecl * ehmDefineCopy( const std::string & exceptionName ) {
233 FunctionType * copyFnType = new FunctionType( noQualifiers, false );
234 copyFnType->get_parameters().push_back( new ObjectDecl(
235 "this",
236 noStorageClasses,
237 LinkageSpec::Cforall,
238 nullptr,
239 new PointerType( noQualifiers,
240 new TypeInstType( noQualifiers, exceptionName, false ) ),
241 nullptr
242 ) );
243 copyFnType->get_parameters().push_back( new ObjectDecl(
244 "that",
245 noStorageClasses,
246 LinkageSpec::Cforall,
247 nullptr,
248 new PointerType( noQualifiers,
249 new TypeInstType( noQualifiers, exceptionName, false ) ),
250 nullptr
251 ) );
252 copyFnType->get_returnVals().push_back( new ObjectDecl(
253 "",
254 noStorageClasses,
255 LinkageSpec::Cforall,
256 nullptr,
257 new VoidType( noQualifiers ),
258 nullptr
259 ) );
260 return new FunctionDecl(
261 "copy",
262 noStorageClasses,
263 LinkageSpec::Cforall,
264 copyFnType,
265 new CompoundStmt( {
266 new ExprStmt( new UntypedExpr( new NameExpr( "?=?" ), {
267 new UntypedExpr( new NameExpr( "*?" ), { new NameExpr( "this" ) } ),
268 new UntypedExpr( new NameExpr( "*?" ), { new NameExpr( "that" ) } )
269 } ) )
270 } )
271 );
272}
273
274FunctionDecl * ehmDefineMsg( const std::string & exceptionName ) {
275 FunctionType * msgFnType = new FunctionType( noQualifiers, false );
276 msgFnType->get_parameters().push_back( new ObjectDecl(
277 "this",
278 noStorageClasses,
279 LinkageSpec::Cforall,
280 nullptr,
281 new PointerType( noQualifiers,
282 new TypeInstType( noQualifiers, exceptionName, false ) ),
283 nullptr
284 ) );
285 msgFnType->get_returnVals().push_back( new ObjectDecl(
286 "",
287 noStorageClasses,
288 LinkageSpec::Cforall,
289 nullptr,
290 new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
291 nullptr
292 ) );
293 return new FunctionDecl(
294 "msg",
295 noStorageClasses,
296 LinkageSpec::Cforall,
297 msgFnType,
298 new CompoundStmt( {
299 new ReturnStmt( new ConstantExpr( Constant::from_string( exceptionName ) ) )
300 } )
301 );
302}
303
304ObjectDecl * ehmVirtualTable( const std::string & exceptionName, const std::string & tableName ) {
305 std::list< Initializer *> inits {
306 new SingleInit( new AddressExpr(
307 new NameExpr( Virtual::typeIdName( exceptionName ) ) ) ),
308 new SingleInit( new SizeofExpr(
309 new StructInstType( noQualifiers, exceptionName ) ) ),
310 new SingleInit( new NameExpr( "copy" ) ),
311 new SingleInit( new NameExpr( "^?{}" ) ),
312 new SingleInit( new NameExpr( "msg" ) )
313 };
314 std::list< Designation *> desig {
315 new Designation( { new NameExpr( "__cfavir_typeid" ) } ),
316 new Designation( { new NameExpr( "size" ) } ),
317 new Designation( { new NameExpr( "copy" ) } ),
318 new Designation( { new NameExpr( "^?{}" ) } ),
319 new Designation( { new NameExpr( "msg" ) } )
320 };
321 return new ObjectDecl(
322 tableName,
323 noStorageClasses,
324 LinkageSpec::Cforall,
325 nullptr,
326 new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ),
327 new ListInit( inits, desig )
328 );
329}
330
331class ExceptDeclCore : public WithDeclsToAdd {
332public:
333 Declaration * postmutate( StructDecl * structDecl ); // translates exception decls
334 DeclarationWithType * postmutate( ObjectDecl * objectDecl ); // translates vtable decls
335};
336
337Declaration * ExceptDeclCore::postmutate( StructDecl * structDecl ) {
338 if ( structDecl->is_exception() ) {
339 const std::string & exceptionName = structDecl->get_name();
340 declsToAddBefore.push_back( ehmTypeIdStruct( exceptionName, nullptr ) );
341 declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, nullptr ) );
342 declsToAddBefore.push_back( ehmExceptionStructDecl( exceptionName, nullptr ) );
343 declsToAddBefore.push_back( ehmVirtualTableStruct( exceptionName, nullptr ) );
344 return ehmExceptionStruct( exceptionName, structDecl->get_members(), nullptr );
345 }
346 return structDecl;
347}
348
349DeclarationWithType * ExceptDeclCore::postmutate( ObjectDecl * objectDecl ) {
350 // Check if it is VTableType
351 VTableType * vtableType = dynamic_cast< VTableType *>( objectDecl->get_type() );
352 if ( vtableType ) {
353 TypeInstType * base = dynamic_cast< TypeInstType *>( vtableType->get_base() );
354 assert( base ); // should be a TypeInstType
355 const std::string & exceptionName = base->get_name();
356 const std::string & tableName = objectDecl->get_name();
357 if ( objectDecl->get_storageClasses().is_extern ) {
358 return ehmExternVtable( exceptionName, tableName, nullptr );
359 } else {
360 declsToAddBefore.push_back( ehmDefineCopy( exceptionName ) );
361 declsToAddBefore.push_back( ehmDefineMsg( exceptionName ) );
362 return ehmVirtualTable( exceptionName, tableName );
363 }
364 }
365 return objectDecl;
366}
367
368void translateExcept( std::list< Declaration *> & translationUnit ) {
369 PassVisitor<ExceptDeclCore> translator;
370 mutateAll( translationUnit, translator );
371}
372
373}
Note: See TracBrowser for help on using the repository browser.