source: src/ControlStruct/ExceptTranslateNew.cpp@ f681823

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since f681823 was 5ee153d, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Translated the Translate Throws pass to the new ast.

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