source: src/ControlStruct/ExceptDecl.cc@ 2d028039

ADT ast-experimental
Last change on this file since 2d028039 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
RevLine 
[0c730d9]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//
[11df881]7// ExceptDecl.cc -- Handles declarations of exception types.
[0c730d9]8//
9// Author : Henry Xue
10// Created On : Tue Jul 20 04:10:50 2021
[c715e5f]11// Last Modified By : Andrew Beach
12// Last Modified On : Wed May 25 16:43:00 2022
13// Update Count : 5
[0c730d9]14//
15
16#include "ExceptDecl.h"
17
[98233b3]18#include <cassert> // for assert
19#include <string> // for string
20#include <sstream> // for stringstream
21
[0c730d9]22#include "Common/PassVisitor.h" // for PassVisitor
[98233b3]23#include "Common/utility.h" // for cloneAll
[0c730d9]24#include "SynTree/Mutator.h" // for mutateAll
25#include "Virtual/Tables.h" // for helpers
26
27namespace ControlStruct {
28
[98233b3]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 ) );
[0c730d9]37 }
[98233b3]38 return *parameters;
[0c730d9]39}
40
[c715e5f]41StructInstType * makeExceptInstType(
[98233b3]42 const std::string & exceptionName,
43 const std::list< Expression *> & parameters
44) {
[c715e5f]45 StructInstType * exceptInstType = new StructInstType(
[98233b3]46 noQualifiers,
[c715e5f]47 exceptionName
[0c730d9]48 );
[98233b3]49 cloneAll( parameters, exceptInstType->parameters );
50 return exceptInstType;
[0c730d9]51}
52
[98233b3]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) {
[0c730d9]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,
[98233b3]65 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]66 nullptr
67 ) );
68 copyFnType->get_parameters().push_back( new ObjectDecl(
[98233b3]69 "that",
[0c730d9]70 noStorageClasses,
71 LinkageSpec::Cforall,
72 nullptr,
73 new PointerType( noQualifiers,
[98233b3]74 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]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 ) );
[98233b3]85 return copyFnType;
86}
[0c730d9]87
[98233b3]88// void (*^?{})(exception_name parameters & this);
89FunctionType * makeDtorFnType(
90 const std::string & exceptionName,
91 const std::list< Expression *> & parameters
92) {
[0c730d9]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,
[98233b3]100 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]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 ) );
[98233b3]111 return dtorFnType;
112}
[0c730d9]113
[98233b3]114// const char * (*msg)(exception_name parameters * this);
115FunctionType * makeMsgFnType(
116 const std::string & exceptionName,
117 const std::list< Expression *> & parameters
118) {
[0c730d9]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,
[98233b3]126 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]127 nullptr
128 ) );
129 msgFnType->get_returnVals().push_back( new ObjectDecl(
130 "",
131 noStorageClasses,
132 LinkageSpec::Cforall,
133 nullptr,
[98233b3]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,
[c715e5f]152 new StructInstType( Type::Const, "__cfavir_type_info" ) ),
[0c730d9]153 nullptr
154 ) );
[98233b3]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 );
[0c730d9]235 ObjectDecl * msg = new ObjectDecl(
236 "msg",
237 noStorageClasses,
238 LinkageSpec::Cforall,
239 nullptr,
[98233b3]240 new PointerType( noQualifiers,
241 makeMsgFnType( exceptionName, parameters ) ),
[0c730d9]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 );
[98233b3]251 cloneAll( forallClause, structDecl->parameters );
[0c730d9]252 return structDecl;
253}
254
[98233b3]255StructDecl * ehmExceptionStruct(
256 const std::string & exceptionName,
257 const std::list< TypeDecl *> & forallClause,
[c715e5f]258 const std::list< Expression *> & parameters,
[98233b3]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 );
[0c730d9]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,
[98233b3]273 new PointerType( noQualifiers, vtableType ),
[0c730d9]274 nullptr
275 ) );
276 structDecl->set_body( true );
[98233b3]277 cloneAll( forallClause, structDecl->parameters );
[0c730d9]278 return structDecl;
279}
280
[da602aec]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
[98233b3]301ObjectDecl * ehmExternVtable(
302 const std::string & exceptionName,
[c715e5f]303 const std::list< Expression *> & parameters,
[98233b3]304 const std::string & tableName
305) {
306 StructInstType * vtableType = new StructInstType(
307 Type::Const,
308 Virtual::vtableTypeName( exceptionName )
309 );
310 cloneAll( parameters, vtableType->parameters );
[aa882e7e]311 return new ObjectDecl(
312 tableName,
313 Type::Extern,
314 LinkageSpec::Cforall,
315 nullptr,
[98233b3]316 vtableType,
[aa882e7e]317 nullptr
318 );
319}
320
[98233b3]321FunctionDecl * ehmDefineCopy(
322 const std::string & exceptionName,
323 const std::list< Expression *> & parameters
324) {
[aa882e7e]325 return new FunctionDecl(
326 "copy",
327 noStorageClasses,
328 LinkageSpec::Cforall,
[98233b3]329 makeCopyFnType( exceptionName, parameters ),
[aa882e7e]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
[98233b3]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 }
[aa882e7e]356 return new FunctionDecl(
357 "msg",
358 noStorageClasses,
359 LinkageSpec::Cforall,
[98233b3]360 makeMsgFnType( exceptionName, parameters ),
[aa882e7e]361 new CompoundStmt( {
[98233b3]362 new ReturnStmt( new ConstantExpr( Constant::from_string( msg.str() ) ) )
[aa882e7e]363 } )
364 );
365}
366
[98233b3]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 );
[aa882e7e]374 std::list< Initializer *> inits {
375 new SingleInit( new AddressExpr(
376 new NameExpr( Virtual::typeIdName( exceptionName ) ) ) ),
[98233b3]377 new SingleInit( new SizeofExpr( sizeofType ) ),
[aa882e7e]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 };
[98233b3]389 StructInstType * vtableType = new StructInstType(
390 Type::Const,
391 Virtual::vtableTypeName( exceptionName )
392 );
393 cloneAll( parameters, vtableType->parameters );
[aa882e7e]394 return new ObjectDecl(
395 tableName,
396 noStorageClasses,
397 LinkageSpec::Cforall,
398 nullptr,
[98233b3]399 vtableType,
[aa882e7e]400 new ListInit( inits, desig )
401 );
402}
403
[0c730d9]404class ExceptDeclCore : public WithDeclsToAdd {
405public:
[98233b3]406 // translates exception decls
407 Declaration * postmutate( StructDecl * structDecl );
408
409 // translates vtable decls
410 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
[0c730d9]411};
412
413Declaration * ExceptDeclCore::postmutate( StructDecl * structDecl ) {
414 if ( structDecl->is_exception() ) {
[aa882e7e]415 const std::string & exceptionName = structDecl->get_name();
[98233b3]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 );
[0c730d9]427 }
428 return structDecl;
429}
430
[aa882e7e]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();
[98233b3]439 const std::list< Expression *> parameters = base->get_parameters();
440
441 if ( objectDecl->get_storageClasses().is_extern ) { // if extern
[da602aec]442 if ( !parameters.empty() ) { // forall variant
443 declsToAddBefore.push_back( ehmTypeIdExtern( exceptionName, parameters ) );
444 }
[98233b3]445 return ehmExternVtable( exceptionName, parameters, tableName );
446 }
447 // else, non-extern
448 if ( !parameters.empty() ) { // forall variant
449 declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, parameters ) );
[aa882e7e]450 }
[98233b3]451 declsToAddBefore.push_back( ehmDefineCopy( exceptionName, parameters ) );
452 declsToAddBefore.push_back( ehmDefineMsg( exceptionName, parameters ) );
453 return ehmVirtualTable( exceptionName, parameters, tableName );
[aa882e7e]454 }
455 return objectDecl;
456}
457
[c715e5f]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
[0c730d9]475void translateExcept( std::list< Declaration *> & translationUnit ) {
476 PassVisitor<ExceptDeclCore> translator;
477 mutateAll( translationUnit, translator );
[c715e5f]478 PassVisitor<VTableCore> typeTranslator;
479 mutateAll( translationUnit, typeTranslator );
[0c730d9]480}
481
482}
Note: See TracBrowser for help on using the repository browser.