source: src/ControlStruct/ExceptDecl.cc@ f2f595d7

ADT ast-experimental
Last change on this file since f2f595d7 was 11df881, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Updated documentation on pre-resolver passes, moving code to headers instead of uses. Note that some comments were just copied over, I don't know if they are accurate.

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