source: src/InitTweak/FixGlobalInit.cc@ 1ccae59

Last change on this file since 1ccae59 was 0bd3faf, checked in by Andrew Beach <ajbeach@…>, 23 months ago

Removed forward declarations missed in the BaseSyntaxNode removal. Removed code and modified names to support two versions of the ast.

  • Property mode set to 100644
File size: 3.9 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// FixGlobalInit.cc --
8//
9// Author : Rob Schluntz
10// Created On : Mon May 04 15:14:56 2016
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Dec 13 23:41:10 2019
13// Update Count : 19
14//
15
16#include "FixGlobalInit.h"
17
18#include <cassert> // for assert
19#include <stddef.h> // for NULL
20#include <algorithm> // for replace_if
21
22#include "AST/Expr.hpp"
23#include "AST/Node.hpp"
24#include "AST/Pass.hpp"
25#include "Common/UniqueName.h" // for UniqueName
26#include "InitTweak.h" // for isIntrinsicSingleArgCallStmt
27
28namespace InitTweak {
29 class GlobalFixer : public ast::WithShortCircuiting {
30 public:
31 void previsit (const ast::ObjectDecl *);
32 void previsit (const ast::FunctionDecl *) { visit_children = false; }
33 void previsit (const ast::StructDecl *) { visit_children = false; }
34 void previsit (const ast::UnionDecl *) { visit_children = false; }
35 void previsit (const ast::EnumDecl *) { visit_children = false; }
36 void previsit (const ast::TraitDecl *) { visit_children = false; }
37 void previsit (const ast::TypeDecl *) { visit_children = false; }
38
39 std::list< ast::ptr<ast::Stmt> > initStmts;
40 std::list< ast::ptr<ast::Stmt> > destroyStmts;
41 };
42
43 void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) {
44 ast::Pass<GlobalFixer> fixer;
45 accept_all(translationUnit, fixer);
46
47 // Say these magic declarations come at the end of the file.
48 CodeLocation const & location = translationUnit.decls.back()->location;
49
50 if ( !fixer.core.initStmts.empty() ) {
51 std::vector<ast::ptr<ast::Expr>> ctorParams;
52 if (inLibrary) ctorParams.emplace_back(ast::ConstantExpr::from_int(location, 200));
53 auto initFunction = new ast::FunctionDecl(location,
54 "__global_init__", {}, {}, {},
55 new ast::CompoundStmt(location, std::move(fixer.core.initStmts)),
56 ast::Storage::Static, ast::Linkage::C,
57 {new ast::Attribute("constructor", std::move(ctorParams))});
58
59 translationUnit.decls.emplace_back( initFunction );
60 } // if
61
62 if ( !fixer.core.destroyStmts.empty() ) {
63 std::vector<ast::ptr<ast::Expr>> dtorParams;
64 if (inLibrary) dtorParams.emplace_back(ast::ConstantExpr::from_int(location, 200));
65 auto destroyFunction = new ast::FunctionDecl( location,
66 "__global_destroy__", {}, {}, {},
67 new ast::CompoundStmt(location, std::move(fixer.core.destroyStmts)),
68 ast::Storage::Static, ast::Linkage::C,
69 {new ast::Attribute("destructor", std::move(dtorParams))});
70
71 translationUnit.decls.emplace_back(destroyFunction);
72 } // if
73 }
74
75 void GlobalFixer::previsit(const ast::ObjectDecl * objDecl) {
76 auto mutDecl = mutate(objDecl);
77 assertf(mutDecl == objDecl, "Global object decl must be unique");
78 if ( auto ctorInit = objDecl->init.as<ast::ConstructorInit>() ) {
79 // a decision should have been made by the resolver, so ctor and init are not both non-NULL
80 assert( ! ctorInit->ctor || ! ctorInit->init );
81
82 const ast::Stmt * dtor = ctorInit->dtor;
83 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
84 // don't need to call intrinsic dtor, because it does nothing, but
85 // non-intrinsic dtors must be called
86 destroyStmts.push_front( dtor );
87 // ctorInit->dtor = nullptr;
88 } // if
89 if ( const ast::Stmt * ctor = ctorInit->ctor ) {
90 addDataSectionAttribute(mutDecl);
91 initStmts.push_back( ctor );
92 mutDecl->init = nullptr;
93 // ctorInit->ctor = nullptr;
94 } else if ( const ast::Init * init = ctorInit->init ) {
95 mutDecl->init = init;
96 // ctorInit->init = nullptr;
97 } else {
98 // no constructor and no initializer, which is okay
99 mutDecl->init = nullptr;
100 } // if
101 // delete ctorInit;
102 } // if
103 }
104
105} // namespace InitTweak
106
107// Local Variables: //
108// tab-width: 4 //
109// mode: c++ //
110// compile-command: "make install" //
111// End: //
Note: See TracBrowser for help on using the repository browser.