| 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 | 
 | 
|---|
| 27 | namespace ControlStruct {
 | 
|---|
| 28 | 
 | 
|---|
| 29 | const 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 | 
 | 
|---|
| 41 | TypeInstType * 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);
 | 
|---|
| 55 | FunctionType * 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);
 | 
|---|
| 90 | FunctionType * 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);
 | 
|---|
| 116 | FunctionType * 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 | 
 | 
|---|
| 142 | StructDecl * 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 | 
 | 
|---|
| 161 | ObjectDecl * 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 | 
 | 
|---|
| 183 | StructDecl * 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 | 
 | 
|---|
| 192 | StructDecl * 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 | 
 | 
|---|
| 256 | StructDecl * 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 | 
 | 
|---|
| 282 | ObjectDecl * 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 | 
 | 
|---|
| 302 | ObjectDecl * 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 | 
 | 
|---|
| 322 | FunctionDecl * 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 | 
 | 
|---|
| 340 | FunctionDecl * 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 | 
 | 
|---|
| 368 | ObjectDecl * 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 | 
 | 
|---|
| 405 | class ExceptDeclCore : public WithDeclsToAdd {
 | 
|---|
| 406 | public:
 | 
|---|
| 407 |         // translates exception decls
 | 
|---|
| 408 |         Declaration * postmutate( StructDecl * structDecl );
 | 
|---|
| 409 | 
 | 
|---|
| 410 |         // translates vtable decls
 | 
|---|
| 411 |         DeclarationWithType * postmutate( ObjectDecl * objectDecl );
 | 
|---|
| 412 | };
 | 
|---|
| 413 | 
 | 
|---|
| 414 | Declaration * 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 | 
 | 
|---|
| 432 | DeclarationWithType * 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 | 
 | 
|---|
| 459 | void translateExcept( std::list< Declaration *> & translationUnit ) {
 | 
|---|
| 460 |         PassVisitor<ExceptDeclCore> translator;
 | 
|---|
| 461 |         mutateAll( translationUnit, translator );
 | 
|---|
| 462 | }
 | 
|---|
| 463 | 
 | 
|---|
| 464 | }
 | 
|---|