source: src/ControlStruct/ExceptDecl.cc @ 98233b3

jacob/cs343-translationnew-ast-unique-expr
Last change on this file since 98233b3 was 98233b3, checked in by Henry Xue <y58xue@…>, 3 months 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.