source: src/GenPoly/ScrubTyVars.cc @ f22b170b

Last change on this file since f22b170b was b8b5535, checked in by Andrew Beach <ajbeach@…>, 9 months ago

Major round of clean-up in the GenPoly? directory.

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[51587aa]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//
[b8b5535]7// ScrubTyVars.cc -- Remove polymorphic types.
[51587aa]8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
[3606fe4]11// Last Modified By : Andrew Beach
[ea2ed3a]12// Last Modified On : Wed Dec  7 17:01:00 2022
13// Update Count     : 6
[51587aa]14//
[01aeade]15
[08fc48f]16#include <utility>                      // for pair
[db0b3ce]17
[3606fe4]18#include "AST/Pass.hpp"
[08fc48f]19#include "GenPoly.h"                    // for mangleType, TyVarMap, alignof...
20#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
[51b7345]21#include "ScrubTyVars.h"
[0026d67]22#include "SymTab/Mangler.h"             // for mangleType
[51b7345]23
24namespace GenPoly {
[3606fe4]25
26namespace {
27
28struct ScrubTypeVars :
[b8b5535]29                public ast::WithGuards,
30                public ast::WithShortCircuiting,
31                public ast::WithVisitorRef<ScrubTypeVars> {
[3606fe4]32
[c8837e5]33        ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
[3606fe4]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.
[c8837e5]53        TypeVarMap const * const typeVars;
[3606fe4]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 ) {
[2f61765]89        ast::TypeDecl::Kind kind;
[3606fe4]90        // This implies that mode == ScrubMode::All.
91        if ( !typeVars ) {
[2f61765]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;
[3606fe4]98                }
[2f61765]99                kind = typeVar->second.kind;
[3606fe4]100        }
101
[2f61765]102        switch ( kind ) {
103        case ast::TypeDecl::Dtype:
104        case ast::TypeDecl::Ttype:
[3606fe4]105                return new ast::PointerType(
106                        new ast::VoidType( type->qualifiers ) );
[2f61765]107        case ast::TypeDecl::Ftype:
[3606fe4]108                return new ast::PointerType(
109                        new ast::FunctionType( ast::VariableArgs ) );
110        default:
[2f61765]111                assertf( false, "Unhandled type variable kind: %d", kind );
[3606fe4]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,
[0026d67]128                        sizeofName( Mangle::mangleType( dynType ) ) );
[3606fe4]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,
[0026d67]138                        alignofName( Mangle::mangleType( dynType ) ) );
[3606fe4]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
[ea2ed3a]154} // namespace
155
[3606fe4]156const ast::Node * scrubTypeVarsBase(
[ea2ed3a]157                const ast::Node * node, const TypeVarMap * typeVars, ScrubMode mode ) {
[3606fe4]158        if ( ScrubMode::All == mode ) {
159                assert( nullptr == typeVars );
160        } else {
161                assert( nullptr != typeVars );
162        }
163        ast::Pass<ScrubTypeVars> visitor( mode, typeVars );
[ea2ed3a]164        return node->accept( visitor );
[3606fe4]165}
166
[51b7345]167} // namespace GenPoly
[01aeade]168
[51587aa]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.