source: src/ControlStruct/TranslateEnumRange.cpp@ 1ad112a5

Last change on this file since 1ad112a5 was 0c327ce, checked in by JiadaL <j82liang@…>, 15 months ago
  1. Add bound check to Serial function: now compiler generates the unchecked functions in ImplementEnumFunc, and enum.hfa implements the bound check on top. Todo: Wrapped the checked version into a trait; 2. countof is now works on any type that implement Countof(). Because Countof() is implemented in enum.hfa for all CfaEnum, we can call countof on { T | CfaEnum(T) }
  • Property mode set to 100644
File size: 3.8 KB
RevLine 
[d66a43b]1#include "TranslateEnumRange.hpp"
[567c775]2
3#include "AST/Pass.hpp"
4#include "AST/TranslationUnit.hpp"
5
6namespace ControlStruct {
7
8struct addInitType {
9 const ast::Stmt * postvisit( const ast::ForStmt * stmt );
10};
11
12struct addInit {
13 const ast::Stmt * postvisit( const ast::ForStmt * stmt );
14};
15
16struct translateEnumRangeCore {
17 const ast::Stmt * postvisit( const ast::ForStmt * stmt );
18};
19
20const ast::Stmt* addInitType::postvisit( const ast::ForStmt * stmt ) {
21 if ( stmt->range_over ) {
22 auto typeExpr = stmt->range_over.strict_as<ast::TypeExpr>();
23 auto type = typeExpr->type;
24
[d3aa55e9]25 auto objInit = stmt->inits.front();
26 assert( stmt->inits.size() == 1 );
27
28 if (auto declStmt = objInit.as<ast::DeclStmt>()) {
[567c775]29 auto decl = declStmt->decl;
30 if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
31 if ( !objDecl->type && type ) {
32 auto objDeclWithType = ast::mutate_field( objDecl, &ast::ObjectDecl::type, type );
33 auto declWithType = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithType );
34 stmt = ast::mutate_field_index( stmt, &ast::ForStmt::inits, 0, declWithType );
35 }
36 }
37 }
38 }
39 return stmt;
40}
41
42const ast::Stmt* addInit::postvisit( const ast::ForStmt * stmt ) {
43 if ( stmt->range_over ) {
44 auto inits = stmt->inits;
45 auto init = stmt->inits.front();
46
47 if (auto declStmt = init.as<ast::DeclStmt>()) {
48 auto decl = declStmt->decl;
49 if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
50 if ( !objDecl->init ) {
51 auto location = stmt->location;
[73d0e3f4]52 ast::SingleInit * newInit = new ast::SingleInit( location,
[6d2b3dc]53 stmt->is_inc?
54 ast::UntypedExpr::createCall( location, "lowerBound", {} ):
55 ast::UntypedExpr::createCall( location, "upperBound", {} ),
56 ast::ConstructFlag::MaybeConstruct
57 );
[567c775]58 auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
59 auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
60 stmt = ast::mutate_field_index( stmt, &ast::ForStmt::inits, 0, declWithInit );
61 }
62 }
63 }
64 }
65 return stmt;
66}
67
68const ast::Stmt* translateEnumRangeCore::postvisit( const ast::ForStmt * stmt ) {
69 if ( !stmt->range_over ) return stmt;
70 auto location = stmt->location;
71 auto declStmt = stmt->inits.front().strict_as<ast::DeclStmt>();
72 auto initDecl = declStmt->decl.strict_as<ast::ObjectDecl>();
73 auto indexName = initDecl->name;
[73d0e3f4]74
[d3aa55e9]75 // Both inc and dec check if the current posn less than the number of enumerator
76 // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
77 // it wraps around and become unsigned max
78 ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
79 "?<=?",
[6d2b3dc]80 { new ast::NameExpr( location, indexName ),
81 ast::UntypedExpr::createCall( location, "upperBound", {} ) });
[d3aa55e9]82 auto increment = ast::UntypedExpr::createCall( location,
[0c327ce]83 stmt->is_inc? "succ_unsafe": "pred_unsafe",
[6d2b3dc]84 { new ast::NameExpr( location, indexName ) });
[567c775]85 auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
86 auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
87 mut = ast::mutate_field(stmt, &ast::ForStmt::inc, assig );
88 return mut;
89}
90
91void translateEnumRange( ast::TranslationUnit & translationUnit ) {
92 ast::Pass<addInit>::run( translationUnit );
93 ast::Pass<translateEnumRangeCore>::run( translationUnit );
94}
[d66a43b]95}
Note: See TracBrowser for help on using the repository browser.