source: src/ControlStruct/ExceptDecl.cc @ aa882e7e

jacob/cs343-translationnew-ast-unique-expr
Last change on this file since aa882e7e was aa882e7e, checked in by Henry Xue <y58xue@…>, 5 months ago

Translate virtual table declarations

  • Property mode set to 100644
File size: 10.8 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 : Thu Jul 22 10:40:55 2021
13// Update Count     : 2
14//
15
16#include "ExceptDecl.h"
17
18#include "Common/PassVisitor.h"  // for PassVisitor
19#include "SynTree/Mutator.h"     // for mutateAll
20#include "Virtual/Tables.h"      // for helpers
21
22namespace ControlStruct {
23
24StructDecl * ehmTypeIdStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
25        StructDecl * structDecl = new StructDecl( Virtual::typeIdType( exceptionName ) );
26        structDecl->members.push_back( new ObjectDecl(
27                "parent",
28                noStorageClasses,
29                LinkageSpec::Cforall,
30                nullptr,
31                new PointerType( noQualifiers,
32                        new TypeInstType( Type::Const, "__cfavir_type_info", false ) ),
33                nullptr
34        ) );
35        structDecl->set_body( true );
36        if ( parameters ) {
37                structDecl->parameters = *parameters;
38        }
39        return structDecl;
40}
41
42ObjectDecl * ehmTypeIdValue( const std::string & exceptionName, std::list< Expression *> * parameters ) {
43        StructInstType * structInstType = new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) );
44        if ( parameters ) {
45                structInstType->parameters = *parameters;
46        }
47        return new ObjectDecl(
48                Virtual::typeIdName( exceptionName ),
49                noStorageClasses,
50                LinkageSpec::Cforall,
51                nullptr,
52                structInstType,
53                new ListInit( { new SingleInit(
54                        new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
55                        ) }, {}, true ),
56                { new Attribute( "cfa_linkonce" ) }
57        );
58}
59
60StructDecl * ehmExceptionStructDecl( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
61        StructDecl * structDecl = new StructDecl( exceptionName );
62        if ( parameters ) {
63                structDecl->parameters = *parameters;
64        }
65        return structDecl;
66}
67
68StructDecl * ehmVirtualTableStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
69        // _EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid;
70        ObjectDecl * typeId = new ObjectDecl(
71                "__cfavir_typeid",
72                noStorageClasses,
73                LinkageSpec::Cforall,
74                nullptr,
75                new PointerType( noQualifiers,
76                        new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) ) ),
77                nullptr
78        );
79
80        // size_t size;
81        ObjectDecl * size = new ObjectDecl(
82                "size",
83                noStorageClasses,
84                LinkageSpec::Cforall,
85                nullptr,
86                new TypeInstType( noQualifiers, "size_t", false ),
87                nullptr
88        );
89       
90        // void (*copy)(exception_name parameters * this, exception_name parameters * other);
91        FunctionType * copyFnType = new FunctionType( noQualifiers, false );
92        copyFnType->get_parameters().push_back( new ObjectDecl(
93                "this",
94                noStorageClasses,
95                LinkageSpec::Cforall,
96                nullptr,
97                new PointerType( noQualifiers,
98                        new TypeInstType( noQualifiers, exceptionName, false ) ),
99                nullptr
100        ) );
101        copyFnType->get_parameters().push_back( new ObjectDecl(
102                "other",
103                noStorageClasses,
104                LinkageSpec::Cforall,
105                nullptr,
106                new PointerType( noQualifiers,
107                        new TypeInstType( noQualifiers, exceptionName, false ) ),
108                nullptr
109        ) );
110        copyFnType->get_returnVals().push_back( new ObjectDecl(
111                "",
112                noStorageClasses,
113                LinkageSpec::Cforall,
114                nullptr,
115                new VoidType( noQualifiers ),
116                nullptr
117        ) );
118        ObjectDecl * copy = new ObjectDecl(
119                "copy",
120                noStorageClasses,
121                LinkageSpec::Cforall,
122                nullptr,
123                new PointerType( noQualifiers, copyFnType ),
124                nullptr
125        );
126
127        // void (*^?{})(exception_name parameters & this);
128        FunctionType * dtorFnType = new FunctionType( noQualifiers, false );
129        dtorFnType->get_parameters().push_back( new ObjectDecl(
130                "this",
131                noStorageClasses,
132                LinkageSpec::Cforall,
133                nullptr,
134                new ReferenceType( noQualifiers,
135                        new TypeInstType( noQualifiers, exceptionName, false ) ),
136                nullptr
137        ) );
138        dtorFnType->get_returnVals().push_back( new ObjectDecl(
139                "",
140                noStorageClasses,
141                LinkageSpec::Cforall,
142                nullptr,
143                new VoidType( noQualifiers ),
144                nullptr
145        ) );
146        ObjectDecl * dtor = new ObjectDecl(
147                "^?{}",
148                noStorageClasses,
149                LinkageSpec::Cforall,
150                nullptr,
151                new PointerType( noQualifiers, dtorFnType ),
152                nullptr
153        );
154
155        // const char * (*msg)(exception_name parameters * this);
156        FunctionType * msgFnType = new FunctionType( noQualifiers, false );
157        msgFnType->get_parameters().push_back( new ObjectDecl(
158                "this",
159                noStorageClasses,
160                LinkageSpec::Cforall,
161                nullptr,
162                new PointerType( noQualifiers,
163                        new TypeInstType( noQualifiers, exceptionName, false ) ),
164                nullptr
165        ) );
166        msgFnType->get_returnVals().push_back( new ObjectDecl(
167                "",
168                noStorageClasses,
169                LinkageSpec::Cforall,
170                nullptr,
171                new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
172                nullptr
173        ) );
174        ObjectDecl * msg = new ObjectDecl(
175                "msg",
176                noStorageClasses,
177                LinkageSpec::Cforall,
178                nullptr,
179                new PointerType( noQualifiers, msgFnType ),
180                nullptr
181        );
182
183        StructDecl * structDecl = new StructDecl( Virtual::vtableTypeName( exceptionName ) );
184        structDecl->members.push_back( typeId );
185        structDecl->members.push_back( size );
186        structDecl->members.push_back( copy );
187        structDecl->members.push_back( dtor );
188        structDecl->members.push_back( msg );
189        structDecl->set_body( true );
190        if ( parameters ) {
191                structDecl->parameters = *parameters;
192        }
193        return structDecl;
194}
195
196StructDecl * ehmExceptionStruct( const std::string & exceptionName, const std::list<Declaration*> & members,
197                                                                 std::list<TypeDecl *> * parameters ) {
198        StructDecl * structDecl = new StructDecl( exceptionName );
199        structDecl->members = members;
200        structDecl->members.push_front( new ObjectDecl(
201                "virtual_table",
202                noStorageClasses,
203                LinkageSpec::Cforall,
204                nullptr,
205                new PointerType( noQualifiers,
206                        new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ) ),
207                nullptr
208        ) );
209        structDecl->set_body( true );
210        if ( parameters ) {
211                structDecl->parameters = *parameters;
212        }
213        return structDecl;
214}
215
216ObjectDecl * ehmExternVtable( const std::string & exceptionName, const std::string & tableName,
217                                                          std::list< Expression *> * parameters ) {
218        StructInstType * structInstType = new StructInstType( Type::Const, Virtual::vtableTypeName(exceptionName) );
219        if ( parameters ) {
220                structInstType->parameters = *parameters;
221        }
222        return new ObjectDecl(
223                tableName,
224                Type::Extern,
225                LinkageSpec::Cforall,
226                nullptr,
227                structInstType,
228                nullptr
229        );
230}
231
232FunctionDecl * ehmDefineCopy( const std::string & exceptionName ) {
233        FunctionType * copyFnType = new FunctionType( noQualifiers, false );
234        copyFnType->get_parameters().push_back( new ObjectDecl(
235                "this",
236                noStorageClasses,
237                LinkageSpec::Cforall,
238                nullptr,
239                new PointerType( noQualifiers,
240                        new TypeInstType( noQualifiers, exceptionName, false ) ),
241                nullptr
242        ) );
243        copyFnType->get_parameters().push_back( new ObjectDecl(
244                "that",
245                noStorageClasses,
246                LinkageSpec::Cforall,
247                nullptr,
248                new PointerType( noQualifiers,
249                        new TypeInstType( noQualifiers, exceptionName, false ) ),
250                nullptr
251        ) );
252        copyFnType->get_returnVals().push_back( new ObjectDecl(
253                "",
254                noStorageClasses,
255                LinkageSpec::Cforall,
256                nullptr,
257                new VoidType( noQualifiers ),
258                nullptr
259        ) );
260        return new FunctionDecl(
261                "copy",
262                noStorageClasses,
263                LinkageSpec::Cforall,
264                copyFnType,
265                new CompoundStmt( {
266                        new ExprStmt( new UntypedExpr( new NameExpr( "?=?" ), {
267                                new UntypedExpr( new NameExpr( "*?" ), { new NameExpr( "this" ) } ),
268                                new UntypedExpr( new NameExpr( "*?" ), { new NameExpr( "that" ) } )
269                        } ) )
270                } )
271        );
272}
273
274FunctionDecl * ehmDefineMsg( const std::string & exceptionName ) {
275        FunctionType * msgFnType = new FunctionType( noQualifiers, false );
276        msgFnType->get_parameters().push_back( new ObjectDecl(
277                "this",
278                noStorageClasses,
279                LinkageSpec::Cforall,
280                nullptr,
281                new PointerType( noQualifiers,
282                        new TypeInstType( noQualifiers, exceptionName, false ) ),
283                nullptr
284        ) );
285        msgFnType->get_returnVals().push_back( new ObjectDecl(
286                "",
287                noStorageClasses,
288                LinkageSpec::Cforall,
289                nullptr,
290                new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
291                nullptr
292        ) );
293        return new FunctionDecl(
294                "msg",
295                noStorageClasses,
296                LinkageSpec::Cforall,
297                msgFnType,
298                new CompoundStmt( {
299                        new ReturnStmt( new ConstantExpr( Constant::from_string( exceptionName ) ) )
300                } )
301        );
302}
303
304ObjectDecl * ehmVirtualTable( const std::string & exceptionName, const std::string & tableName ) {
305        std::list< Initializer *> inits {
306                new SingleInit( new AddressExpr(
307                        new NameExpr( Virtual::typeIdName( exceptionName ) ) ) ),
308                new SingleInit( new SizeofExpr(
309                        new StructInstType( noQualifiers, exceptionName ) ) ),
310                new SingleInit( new NameExpr( "copy" ) ),
311                new SingleInit( new NameExpr( "^?{}" ) ),
312                new SingleInit( new NameExpr( "msg" ) )
313        };
314        std::list< Designation *> desig {
315                new Designation( { new NameExpr( "__cfavir_typeid" ) } ),
316                new Designation( { new NameExpr( "size" ) } ),
317                new Designation( { new NameExpr( "copy" ) } ),
318                new Designation( { new NameExpr( "^?{}" ) } ),
319                new Designation( { new NameExpr( "msg" ) } )
320        };
321        return new ObjectDecl(
322                tableName,
323                noStorageClasses,
324                LinkageSpec::Cforall,
325                nullptr,
326                new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ),
327                new ListInit( inits, desig )
328        );
329}
330
331class ExceptDeclCore : public WithDeclsToAdd {
332public:
333        Declaration * postmutate( StructDecl * structDecl ); // translates exception decls
334        DeclarationWithType * postmutate( ObjectDecl * objectDecl ); // translates vtable decls
335};
336
337Declaration * ExceptDeclCore::postmutate( StructDecl * structDecl ) {
338        if ( structDecl->is_exception() ) {
339                const std::string & exceptionName = structDecl->get_name();
340                declsToAddBefore.push_back( ehmTypeIdStruct( exceptionName, nullptr ) );
341                declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, nullptr ) );
342                declsToAddBefore.push_back( ehmExceptionStructDecl( exceptionName, nullptr ) );
343                declsToAddBefore.push_back( ehmVirtualTableStruct( exceptionName, nullptr ) );
344                return ehmExceptionStruct( exceptionName, structDecl->get_members(), nullptr );
345        }
346        return structDecl;
347}
348
349DeclarationWithType * ExceptDeclCore::postmutate( ObjectDecl * objectDecl ) {
350        // Check if it is VTableType
351        VTableType * vtableType = dynamic_cast< VTableType *>( objectDecl->get_type() );
352        if ( vtableType ) {
353                TypeInstType * base = dynamic_cast< TypeInstType *>( vtableType->get_base() );
354                assert( base ); // should be a TypeInstType
355                const std::string & exceptionName = base->get_name();
356                const std::string & tableName = objectDecl->get_name();
357                if ( objectDecl->get_storageClasses().is_extern ) {
358                        return ehmExternVtable( exceptionName, tableName, nullptr );
359                } else {
360                        declsToAddBefore.push_back( ehmDefineCopy( exceptionName ) );
361                        declsToAddBefore.push_back( ehmDefineMsg( exceptionName ) );
362                        return ehmVirtualTable( exceptionName, tableName );
363                }
364        }
365        return objectDecl;
366}
367
368void translateExcept( std::list< Declaration *> & translationUnit ) {
369        PassVisitor<ExceptDeclCore> translator;
370        mutateAll( translationUnit, translator );
371}
372
373}
Note: See TracBrowser for help on using the repository browser.