source: src/Validate/HoistStruct.cpp@ ff71057

ADT ast-experimental
Last change on this file since ff71057 was 9feb34b, checked in by Andrew Beach <ajbeach@…>, 2 years 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.