source: src/ControlStruct/ExceptDecl.cc@ d83b266

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

Translate forall variants of exception/vtable decls

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