source: src/Validate/HoistStruct.cpp @ f704974

ADTast-experimental
Last change on this file since f704974 was 298fe57, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Translated 3/4 of validate_B. Link Reference To Types has been removed and will be translated after we know how much support we need for forall function pointers.

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