source: src/ControlStruct/ExceptDecl.cc@ e4da70b

ADT ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since e4da70b 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
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//
7// ExceptDecl.cc --
8//
9// Author : Henry Xue
10// Created On : Tue Jul 20 04:10:50 2021
11// Last Modified By : Henry Xue
[98233b3]12// Last Modified On : Mon Jul 26 12:55:28 2021
13// Update Count : 3
[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
[98233b3]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
[0c730d9]49 );
[98233b3]50 cloneAll( parameters, exceptInstType->parameters );
51 return exceptInstType;
[0c730d9]52}
53
[98233b3]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) {
[0c730d9]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,
[98233b3]66 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]67 nullptr
68 ) );
69 copyFnType->get_parameters().push_back( new ObjectDecl(
[98233b3]70 "that",
[0c730d9]71 noStorageClasses,
72 LinkageSpec::Cforall,
73 nullptr,
74 new PointerType( noQualifiers,
[98233b3]75 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]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 ) );
[98233b3]86 return copyFnType;
87}
[0c730d9]88
[98233b3]89// void (*^?{})(exception_name parameters & this);
90FunctionType * makeDtorFnType(
91 const std::string & exceptionName,
92 const std::list< Expression *> & parameters
93) {
[0c730d9]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,
[98233b3]101 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]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 ) );
[98233b3]112 return dtorFnType;
113}
[0c730d9]114
[98233b3]115// const char * (*msg)(exception_name parameters * this);
116FunctionType * makeMsgFnType(
117 const std::string & exceptionName,
118 const std::list< Expression *> & parameters
119) {
[0c730d9]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,
[98233b3]127 makeExceptInstType( exceptionName, parameters ) ),
[0c730d9]128 nullptr
129 ) );
130 msgFnType->get_returnVals().push_back( new ObjectDecl(
131 "",
132 noStorageClasses,
133 LinkageSpec::Cforall,
134 nullptr,
[98233b3]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 ) ),
[0c730d9]154 nullptr
155 ) );
[98233b3]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 );
[0c730d9]236 ObjectDecl * msg = new ObjectDecl(
237 "msg",
238 noStorageClasses,
239 LinkageSpec::Cforall,
240 nullptr,
[98233b3]241 new PointerType( noQualifiers,
242 makeMsgFnType( exceptionName, parameters ) ),
[0c730d9]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 );
[98233b3]252 cloneAll( forallClause, structDecl->parameters );
[0c730d9]253 return structDecl;
254}
255
[98233b3]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 );
[0c730d9]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,
[98233b3]274 new PointerType( noQualifiers, vtableType ),
[0c730d9]275 nullptr
276 ) );
277 structDecl->set_body( true );
[98233b3]278 cloneAll( forallClause, structDecl->parameters );
[0c730d9]279 return structDecl;
280}
281
[98233b3]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 );
[aa882e7e]292 return new ObjectDecl(
293 tableName,
294 Type::Extern,
295 LinkageSpec::Cforall,
296 nullptr,
[98233b3]297 vtableType,
[aa882e7e]298 nullptr
299 );
300}
301
[98233b3]302FunctionDecl * ehmDefineCopy(
303 const std::string & exceptionName,
304 const std::list< Expression *> & parameters
305) {
[aa882e7e]306 return new FunctionDecl(
307 "copy",
308 noStorageClasses,
309 LinkageSpec::Cforall,
[98233b3]310 makeCopyFnType( exceptionName, parameters ),
[aa882e7e]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
[98233b3]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 }
[aa882e7e]337 return new FunctionDecl(
338 "msg",
339 noStorageClasses,
340 LinkageSpec::Cforall,
[98233b3]341 makeMsgFnType( exceptionName, parameters ),
[aa882e7e]342 new CompoundStmt( {
[98233b3]343 new ReturnStmt( new ConstantExpr( Constant::from_string( msg.str() ) ) )
[aa882e7e]344 } )
345 );
346}
347
[98233b3]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 );
[aa882e7e]355 std::list< Initializer *> inits {
356 new SingleInit( new AddressExpr(
357 new NameExpr( Virtual::typeIdName( exceptionName ) ) ) ),
[98233b3]358 new SingleInit( new SizeofExpr( sizeofType ) ),
[aa882e7e]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 };
[98233b3]370 StructInstType * vtableType = new StructInstType(
371 Type::Const,
372 Virtual::vtableTypeName( exceptionName )
373 );
374 cloneAll( parameters, vtableType->parameters );
[aa882e7e]375 return new ObjectDecl(
376 tableName,
377 noStorageClasses,
378 LinkageSpec::Cforall,
379 nullptr,
[98233b3]380 vtableType,
[aa882e7e]381 new ListInit( inits, desig )
382 );
383}
384
[0c730d9]385class ExceptDeclCore : public WithDeclsToAdd {
386public:
[98233b3]387 // translates exception decls
388 Declaration * postmutate( StructDecl * structDecl );
389
390 // translates vtable decls
391 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
[0c730d9]392};
393
394Declaration * ExceptDeclCore::postmutate( StructDecl * structDecl ) {
395 if ( structDecl->is_exception() ) {
[aa882e7e]396 const std::string & exceptionName = structDecl->get_name();
[98233b3]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 );
[0c730d9]408 }
409 return structDecl;
410}
411
[aa882e7e]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();
[98233b3]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 ) );
[aa882e7e]428 }
[98233b3]429 declsToAddBefore.push_back( ehmDefineCopy( exceptionName, parameters ) );
430 declsToAddBefore.push_back( ehmDefineMsg( exceptionName, parameters ) );
431 return ehmVirtualTable( exceptionName, parameters, tableName );
[aa882e7e]432 }
433 return objectDecl;
434}
435
[0c730d9]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.