source: src/InitTweak/FixGlobalInit.cpp@ eae8b37

Last change on this file since eae8b37 was c92bdcc, checked in by Andrew Beach <ajbeach@…>, 17 months ago

Updated the rest of the names in src/ (except for the generated files).

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