source: src/GenPoly/ScrubTyVars.cc@ 8d182b1

Last change on this file since 8d182b1 was c6b4432, checked in by Andrew Beach <ajbeach@…>, 23 months ago

Remove BaseSyntaxNode and clean-up.

  • Property mode set to 100644
File size: 5.1 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// ScrubTyVars.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Mon May 18 07:44:20 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed Dec 7 17:01:00 2022
13// Update Count : 6
14//
15
16#include <utility> // for pair
17
18#include "AST/Pass.hpp"
19#include "GenPoly.h" // for mangleType, TyVarMap, alignof...
20#include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it...
21#include "ScrubTyVars.h"
22#include "SymTab/Mangler.h" // for mangleType
23
24namespace GenPoly {
25
26namespace {
27
28struct ScrubTypeVars :
29 public ast::WithGuards,
30 public ast::WithShortCircuiting,
31 public ast::WithVisitorRef<ScrubTypeVars> {
32
33 ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
34 mode ( m ), typeVars( tv ) {}
35
36 void previsit( ast::TypeInstType const * ) { visit_children = false; }
37 void previsit( ast::StructInstType const * ) { visit_children = false; }
38 void previsit( ast::UnionInstType const * ) { visit_children = false; }
39 void previsit( ast::SizeofExpr const * expr ) { primeBaseScrub( expr->type ); }
40 void previsit( ast::AlignofExpr const * expr ) { primeBaseScrub( expr->type ); }
41 void previsit( ast::PointerType const * type ) { primeBaseScrub( type->base ); }
42
43 ast::Type const * postvisit( ast::TypeInstType const * type );
44 ast::Type const * postvisit( ast::StructInstType const * type );
45 ast::Type const * postvisit( ast::UnionInstType const * type );
46 ast::Expr const * postvisit( ast::SizeofExpr const * expr );
47 ast::Expr const * postvisit( ast::AlignofExpr const * expr );
48 ast::Type const * postvisit( ast::PointerType const * type );
49
50private:
51 ScrubMode const mode;
52 /// Type varriables to scrub.
53 TypeVarMap const * const typeVars;
54 /// Value cached by primeBaseScrub.
55 ast::Type const * dynType = nullptr;
56
57 /// Returns the type if it should be scrubbed, nullptr otherwise.
58 ast::Type const * shouldScrub( ast::Type const * type ) {
59 switch ( mode ) {
60 case ScrubMode::FromMap:
61 return isPolyType( type, *typeVars );
62 case ScrubMode::DynamicFromMap:
63 return isDynType( type, *typeVars );
64 case ScrubMode::All:
65 return isPolyType( type );
66 default:
67 assertf( false, "Invalid ScrubMode in shouldScrub." );
68 throw;
69 }
70 }
71
72 void primeBaseScrub( ast::Type const * type ) {
73 // Need to determine whether type needs to be scrubbed to
74 // determine whether automatic recursion is necessary.
75 if ( ast::Type const * t = shouldScrub( type ) ) {
76 visit_children = false;
77 GuardValue( dynType ) = t;
78 }
79 }
80
81 ast::Type const * postvisitAggregateType(
82 ast::BaseInstType const * type ) {
83 if ( !shouldScrub( type ) ) return type;
84 return new ast::PointerType( new ast::VoidType( type->qualifiers ) );
85 }
86};
87
88ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) {
89 ast::TypeDecl::Kind kind;
90 // This implies that mode == ScrubMode::All.
91 if ( !typeVars ) {
92 kind = type->kind;
93 } else {
94 // Otherwise, only scrub the type var if it is in map.
95 auto typeVar = typeVars->find( *type );
96 if ( typeVar == typeVars->end() ) {
97 return type;
98 }
99 kind = typeVar->second.kind;
100 }
101
102 switch ( kind ) {
103 case ast::TypeDecl::Dtype:
104 case ast::TypeDecl::Ttype:
105 return new ast::PointerType(
106 new ast::VoidType( type->qualifiers ) );
107 case ast::TypeDecl::Ftype:
108 return new ast::PointerType(
109 new ast::FunctionType( ast::VariableArgs ) );
110 default:
111 assertf( false, "Unhandled type variable kind: %d", kind );
112 throw; // Just in case the assert is removed, stop here.
113 }
114}
115
116ast::Type const * ScrubTypeVars::postvisit( ast::StructInstType const * type ) {
117 return postvisitAggregateType( type );
118}
119
120ast::Type const * ScrubTypeVars::postvisit( ast::UnionInstType const * type ) {
121 return postvisitAggregateType( type );
122}
123
124ast::Expr const * ScrubTypeVars::postvisit( ast::SizeofExpr const * expr ) {
125 // sizeof( T ) becomes the _sizeof_T parameter.
126 if ( dynType ) {
127 return new ast::NameExpr( expr->location,
128 sizeofName( Mangle::mangleType( dynType ) ) );
129 } else {
130 return expr;
131 }
132}
133
134ast::Expr const * ScrubTypeVars::postvisit( ast::AlignofExpr const * expr ) {
135 // alignof( T ) becomes the _alignof_T parameter.
136 if ( dynType ) {
137 return new ast::NameExpr( expr->location,
138 alignofName( Mangle::mangleType( dynType ) ) );
139 } else {
140 return expr;
141 }
142}
143
144ast::Type const * ScrubTypeVars::postvisit( ast::PointerType const * type ) {
145 if ( dynType ) {
146 ast::Type * ret = ast::mutate( dynType->accept( *visitor ) );
147 ret->qualifiers |= type->qualifiers;
148 return ret;
149 } else {
150 return type;
151 }
152}
153
154} // namespace
155
156const ast::Node * scrubTypeVarsBase(
157 const ast::Node * node, const TypeVarMap * typeVars, ScrubMode mode ) {
158 if ( ScrubMode::All == mode ) {
159 assert( nullptr == typeVars );
160 } else {
161 assert( nullptr != typeVars );
162 }
163 ast::Pass<ScrubTypeVars> visitor( mode, typeVars );
164 return node->accept( visitor );
165}
166
167} // namespace GenPoly
168
169// Local Variables: //
170// tab-width: 4 //
171// mode: c++ //
172// compile-command: "make install" //
173// End: //
Note: See TracBrowser for help on using the repository browser.