source: src/Validate/HoistStruct.cpp @ b110bcc

ADT
Last change on this file since b110bcc was 9feb34b, checked in by Andrew Beach <ajbeach@…>, 20 months ago

Moved toString and toCString to a new header. Updated includes. cassert was somehow getting instances of toString before but that stopped working so I embedded the new smaller include.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2018 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// HoistStruct.cpp -- Flattens nested type declarations.
8//
9// Author           : Andrew Beach
10// Created On       : Thr Apr 21 10:34:00 2022
11// Last Modified By : Andrew Beach
12// Last Modified On : Thr Apr 21 10:34:00 2022
13// Update Count     : 0
14//
15
16#include "Validate/HoistStruct.hpp"
17
18#include <sstream>
19
20#include "AST/Pass.hpp"
21#include "AST/TranslationUnit.hpp"
22
23namespace Validate {
24
25namespace {
26
27bool shouldHoist( ast::Decl const * decl ) {
28        return dynamic_cast< ast::StructDecl const * >( decl )
29                || dynamic_cast< ast::UnionDecl const * >( decl )
30                || dynamic_cast< ast::StaticAssertDecl const * >( decl );
31}
32
33/* This pass also does some renaming and internal field alteration, but the
34 * complex part is the actual hoisting. Hoisted declarations should always
35 * appear before the declaration they are hoisted out of and if two types are
36 * nested in the same declaration their order should not change.
37 */
38struct HoistStructCore final :
39                public ast::WithDeclsToAdd<>, public ast::WithGuards {
40        ast::StructDecl const * previsit( ast::StructDecl const * decl );
41        ast::StructDecl const * postvisit( ast::StructDecl const * decl );
42        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
43        ast::UnionDecl const * postvisit( ast::UnionDecl const * decl );
44        ast::StructInstType const * previsit( ast::StructInstType const * type );
45        ast::UnionInstType const * previsit( ast::UnionInstType const * type );
46        ast::EnumInstType const * previsit( ast::EnumInstType const * type );
47
48private:
49        template<typename AggrDecl>
50        AggrDecl const * preAggregate( AggrDecl const * );
51        template<typename AggrDecl>
52        AggrDecl const * postAggregate( AggrDecl const * );
53
54        ast::AggregateDecl const * parent = nullptr;
55};
56
57void qualifiedName( ast::AggregateDecl const * decl, std::ostringstream & ss ) {
58        if ( decl->parent ) {
59                qualifiedName( decl->parent, ss );
60        }
61        ss << "__" << decl->name;
62}
63
64std::string qualifiedName( ast::AggregateDecl const * decl ) {
65        std::ostringstream ss;
66        qualifiedName( decl, ss );
67        return ss.str();
68}
69
70template<typename AggrDecl>
71AggrDecl const * HoistStructCore::preAggregate( AggrDecl const * decl ) {
72        if ( parent ) {
73                auto mut = ast::mutate( decl );
74                mut->parent = parent;
75                mut->name = qualifiedName( mut );
76                return mut;
77        } else {
78                GuardValue( parent ) = decl;
79                return decl;
80        }
81}
82
83template<typename AggrDecl>
84AggrDecl const * HoistStructCore::postAggregate( AggrDecl const * decl ) {
85        auto mut = ast::mutate( decl );
86        for ( auto it = mut->members.begin() ; it != mut->members.end() ; ) {
87                if ( shouldHoist( *it ) ) {
88                        // This is the place where the actual hoisting happens.
89                        declsToAddBefore.push_back( it->get() );
90                        it = mut->members.erase( it );
91                } else {
92                        ++it;
93                }
94        }
95        return mut;
96}
97
98ast::StructDecl const * HoistStructCore::previsit( ast::StructDecl const * decl ) {
99        return preAggregate( decl );
100}
101
102ast::StructDecl const * HoistStructCore::postvisit( ast::StructDecl const * decl ) {
103        return postAggregate( decl );
104}
105
106ast::UnionDecl const * HoistStructCore::previsit( ast::UnionDecl const * decl ) {
107        return preAggregate( decl );
108}
109
110ast::UnionDecl const * HoistStructCore::postvisit( ast::UnionDecl const * decl ) {
111        return postAggregate( decl );
112}
113
114template<typename InstType>
115InstType const * preInstType( InstType const * type ) {
116        assert( type->base );
117        auto mut = ast::mutate( type );
118        mut->name = mut->base->name;
119        return mut;
120}
121
122ast::StructInstType const * HoistStructCore::previsit( ast::StructInstType const * type ) {
123        return preInstType( type );
124}
125
126ast::UnionInstType const * HoistStructCore::previsit( ast::UnionInstType const * type ) {
127        return preInstType( type );
128}
129
130ast::EnumInstType const * HoistStructCore::previsit( ast::EnumInstType const * type ) {
131        return preInstType( type );
132}
133
134} // namespace
135
136void hoistStruct( ast::TranslationUnit & translationUnit ) {
137        ast::Pass<HoistStructCore>::run( translationUnit );
138}
139
140} // namespace Validate
141
142// Local Variables: //
143// tab-width: 4 //
144// mode: c++ //
145// compile-command: "make install" //
146// End: //
Note: See TracBrowser for help on using the repository browser.