source: src/ControlStruct/ExceptTranslateNew.cpp@ fde0a58

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since fde0a58 was 0fba0d4, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

remove anonymous namespace

  • Property mode set to 100644
File size: 4.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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// ExceptTranslateNew.cpp -- Conversion of exception control flow structures.
8//
9// Author : Andrew Beach
10// Created On : Mon Nov 8 11:53:00 2021
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Mon Jan 31 18:49:58 2022
13// Update Count : 1
14//
15
16#include "ExceptTranslate.h"
17
18#include "AST/Expr.hpp"
19#include "AST/Pass.hpp"
20#include "AST/Stmt.hpp"
21#include "AST/TranslationUnit.hpp"
22
23namespace ControlStruct {
24
25class TranslateThrowsCore : public ast::WithGuards {
26 const ast::ObjectDecl * terminateHandlerExcept;
27 enum Context { NoHandler, TerHandler, ResHandler } currentContext;
28
29 const ast::Stmt * createEitherThrow(
30 const ast::ThrowStmt * throwStmt, const char * funcName );
31 const ast::Stmt * createTerminateRethrow( const ast::ThrowStmt * );
32
33public:
34 TranslateThrowsCore() :
35 terminateHandlerExcept( nullptr ), currentContext( NoHandler )
36 {}
37
38 void previsit( const ast::CatchStmt * stmt );
39 const ast::Stmt * postvisit( const ast::ThrowStmt * stmt );
40};
41
42const ast::Stmt * TranslateThrowsCore::createEitherThrow(
43 const ast::ThrowStmt * throwStmt, const char * funcName ) {
44 // `throwFunc`( `throwStmt->name` );
45 ast::UntypedExpr * call = new ast::UntypedExpr( throwStmt->location,
46 new ast::NameExpr( throwStmt->location, funcName )
47 );
48 call->args.push_back( throwStmt->expr );
49 return new ast::ExprStmt( throwStmt->location, call );
50}
51
52ast::VariableExpr * varOf( const ast::DeclWithType * decl ) {
53 return new ast::VariableExpr( decl->location, decl );
54}
55
56const ast::Stmt * TranslateThrowsCore::createTerminateRethrow(
57 const ast::ThrowStmt * stmt ) {
58 // { `terminate_handler_except` = 0p; __rethrow_terminate(); }
59 assert( nullptr == stmt->expr );
60 assert( terminateHandlerExcept );
61
62 ast::CompoundStmt * result = new ast::CompoundStmt(
63 stmt->location, {}, std::vector<ast::Label>( stmt->labels ) );
64 result->push_back( new ast::ExprStmt( stmt->location,
65 ast::UntypedExpr::createAssign(
66 stmt->location,
67 varOf( terminateHandlerExcept ),
68 ast::ConstantExpr::null(
69 stmt->location,
70 terminateHandlerExcept->type
71 )
72 )
73 ) );
74 result->push_back( new ast::ExprStmt( stmt->location, new ast::UntypedExpr(
75 stmt->location,
76 new ast::NameExpr( stmt->location, "__cfaehm_rethrow_terminate" )
77 ) ) );
78 return result;
79}
80
81void TranslateThrowsCore::previsit( const ast::CatchStmt * stmt ) {
82 // Validate the statement's form.
83 const ast::ObjectDecl * decl = stmt->decl.as<ast::ObjectDecl>();
84 // Also checking the type would be nice.
85 if ( !decl || !decl->type.as<ast::PointerType>() ) {
86 std::string kind = (ast::Terminate == stmt->kind) ? "catch" : "catchResume";
87 SemanticError( stmt->location, kind + " must have pointer to an exception type" );
88 }
89
90 // Track the handler context.
91 if ( ast::Terminate == stmt->kind ) {
92 GuardValue( currentContext ) = TerHandler;
93 GuardValue( terminateHandlerExcept ) = decl;
94 } else {
95 GuardValue( currentContext ) = ResHandler;
96 }
97}
98
99const ast::Stmt * TranslateThrowsCore::postvisit(
100 const ast::ThrowStmt * stmt ) {
101 // Ignoring ThrowStmt::target for now.
102 // Handle Termination (Raise, Reraise, Error):
103 if ( ast::Terminate == stmt->kind ) {
104 if ( stmt->expr ) {
105 return createEitherThrow( stmt, "$throw" );
106 } else if ( TerHandler == currentContext ) {
107 return createTerminateRethrow( stmt );
108 } else {
109 abort( "Invalid throw in %s at %i\n",
110 stmt->location.filename.c_str(),
111 stmt->location.first_line);
112 }
113 // Handle Resumption (Raise, Reraise, Error):
114 } else {
115 if ( stmt->expr ) {
116 return createEitherThrow( stmt, "$throwResume" );
117 } else if ( ResHandler == currentContext ) {
118 // This has to be handled later.
119 return stmt;
120 } else {
121 abort( "Invalid throwResume in %s at %i\n",
122 stmt->location.filename.c_str(),
123 stmt->location.first_line);
124 }
125 }
126}
127
128void translateThrows( ast::TranslationUnit & transUnit ) {
129 ast::Pass<TranslateThrowsCore>::run( transUnit );
130}
131
132} // namespace ControlStruct
133
134// Local Variables: //
135// tab-width: 4 //
136// mode: c++ //
137// compile-command: "make install" //
138// End: //
Note: See TracBrowser for help on using the repository browser.