source: src/GenPoly/ScrubTypeVars.cpp

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