source: src/ControlStruct/ExceptDecl.cc@ 34c32f0

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 34c32f0 was da602aec, checked in by Henry Xue <y58xue@…>, 4 years ago

Fix forall variant extern vtable decls

  • Property mode set to 100644
File size: 13.0 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 : Tue Aug 03 10:42:26 2021
13// Update Count : 4
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 * ehmTypeIdExtern(
283 const std::string & exceptionName,
284 const std::list< Expression *> & parameters
285) {
286 StructInstType * typeIdType = new StructInstType(
287 Type::Const,
288 Virtual::typeIdType( exceptionName )
289 );
290 cloneAll( parameters, typeIdType->parameters );
291 return new ObjectDecl(
292 Virtual::typeIdName( exceptionName ),
293 Type::Extern,
294 LinkageSpec::Cforall,
295 nullptr,
296 typeIdType,
297 nullptr,
298 { new Attribute( "cfa_linkonce" ) }
299 );
300}
301
302ObjectDecl * ehmExternVtable(
303 const std::string & exceptionName,
304 const std::list< Expression *> & parameters,
305 const std::string & tableName
306) {
307 StructInstType * vtableType = new StructInstType(
308 Type::Const,
309 Virtual::vtableTypeName( exceptionName )
310 );
311 cloneAll( parameters, vtableType->parameters );
312 return new ObjectDecl(
313 tableName,
314 Type::Extern,
315 LinkageSpec::Cforall,
316 nullptr,
317 vtableType,
318 nullptr
319 );
320}
321
322FunctionDecl * ehmDefineCopy(
323 const std::string & exceptionName,
324 const std::list< Expression *> & parameters
325) {
326 return new FunctionDecl(
327 "copy",
328 noStorageClasses,
329 LinkageSpec::Cforall,
330 makeCopyFnType( exceptionName, parameters ),
331 new CompoundStmt( {
332 new ExprStmt( new UntypedExpr( new NameExpr( "?=?" ), {
333 new UntypedExpr( new NameExpr( "*?" ), { new NameExpr( "this" ) } ),
334 new UntypedExpr( new NameExpr( "*?" ), { new NameExpr( "that" ) } )
335 } ) )
336 } )
337 );
338}
339
340FunctionDecl * ehmDefineMsg(
341 const std::string & exceptionName,
342 const std::list< Expression *> & parameters
343) {
344 std::stringstream msg;
345 msg << exceptionName;
346 if ( !parameters.empty() ) { // forall variant, add parameters
347 msg << "(";
348 for ( auto it = parameters.begin(); it != parameters.end(); it++ ) {
349 ( *it )->print( msg );
350 if ( it + 1 == parameters.end() ) {
351 msg << ")"; // end of list, close bracket
352 } else {
353 msg << ", "; // otherwise use comma as separator
354 }
355 }
356 }
357 return new FunctionDecl(
358 "msg",
359 noStorageClasses,
360 LinkageSpec::Cforall,
361 makeMsgFnType( exceptionName, parameters ),
362 new CompoundStmt( {
363 new ReturnStmt( new ConstantExpr( Constant::from_string( msg.str() ) ) )
364 } )
365 );
366}
367
368ObjectDecl * ehmVirtualTable(
369 const std::string & exceptionName,
370 const std::list< Expression *> & parameters,
371 const std::string & tableName
372) {
373 StructInstType * sizeofType = new StructInstType( noQualifiers, exceptionName );
374 cloneAll( parameters, sizeofType->parameters );
375 std::list< Initializer *> inits {
376 new SingleInit( new AddressExpr(
377 new NameExpr( Virtual::typeIdName( exceptionName ) ) ) ),
378 new SingleInit( new SizeofExpr( sizeofType ) ),
379 new SingleInit( new NameExpr( "copy" ) ),
380 new SingleInit( new NameExpr( "^?{}" ) ),
381 new SingleInit( new NameExpr( "msg" ) )
382 };
383 std::list< Designation *> desig {
384 new Designation( { new NameExpr( "__cfavir_typeid" ) } ),
385 new Designation( { new NameExpr( "size" ) } ),
386 new Designation( { new NameExpr( "copy" ) } ),
387 new Designation( { new NameExpr( "^?{}" ) } ),
388 new Designation( { new NameExpr( "msg" ) } )
389 };
390 StructInstType * vtableType = new StructInstType(
391 Type::Const,
392 Virtual::vtableTypeName( exceptionName )
393 );
394 cloneAll( parameters, vtableType->parameters );
395 return new ObjectDecl(
396 tableName,
397 noStorageClasses,
398 LinkageSpec::Cforall,
399 nullptr,
400 vtableType,
401 new ListInit( inits, desig )
402 );
403}
404
405class ExceptDeclCore : public WithDeclsToAdd {
406public:
407 // translates exception decls
408 Declaration * postmutate( StructDecl * structDecl );
409
410 // translates vtable decls
411 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
412};
413
414Declaration * ExceptDeclCore::postmutate( StructDecl * structDecl ) {
415 if ( structDecl->is_exception() ) {
416 const std::string & exceptionName = structDecl->get_name();
417 const std::list< TypeDecl *> & forallClause = structDecl->get_parameters();
418 const std::list< Expression *> & parameters = makeParameters( forallClause );
419 const std::list< Declaration *> & members = structDecl->get_members();
420
421 declsToAddBefore.push_back( ehmTypeIdStruct( exceptionName, forallClause ) );
422 if ( forallClause.empty() ) { // non-forall variant
423 declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, parameters ) );
424 }
425 declsToAddBefore.push_back( ehmExceptionStructDecl( exceptionName, forallClause ) );
426 declsToAddBefore.push_back( ehmVirtualTableStruct( exceptionName, forallClause, parameters ) );
427 return ehmExceptionStruct( exceptionName, forallClause, parameters, members );
428 }
429 return structDecl;
430}
431
432DeclarationWithType * ExceptDeclCore::postmutate( ObjectDecl * objectDecl ) {
433 // Check if it is VTableType
434 VTableType * vtableType = dynamic_cast< VTableType *>( objectDecl->get_type() );
435 if ( vtableType ) {
436 TypeInstType * base = dynamic_cast< TypeInstType *>( vtableType->get_base() );
437 assert( base ); // should be a TypeInstType
438 const std::string & exceptionName = base->get_name();
439 const std::string & tableName = objectDecl->get_name();
440 const std::list< Expression *> parameters = base->get_parameters();
441
442 if ( objectDecl->get_storageClasses().is_extern ) { // if extern
443 if ( !parameters.empty() ) { // forall variant
444 declsToAddBefore.push_back( ehmTypeIdExtern( exceptionName, parameters ) );
445 }
446 return ehmExternVtable( exceptionName, parameters, tableName );
447 }
448 // else, non-extern
449 if ( !parameters.empty() ) { // forall variant
450 declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, parameters ) );
451 }
452 declsToAddBefore.push_back( ehmDefineCopy( exceptionName, parameters ) );
453 declsToAddBefore.push_back( ehmDefineMsg( exceptionName, parameters ) );
454 return ehmVirtualTable( exceptionName, parameters, tableName );
455 }
456 return objectDecl;
457}
458
459void translateExcept( std::list< Declaration *> & translationUnit ) {
460 PassVisitor<ExceptDeclCore> translator;
461 mutateAll( translationUnit, translator );
462}
463
464}
Note: See TracBrowser for help on using the repository browser.