source: src/Validate/ForallPointerDecay.cpp@ 0dffe91

Last change on this file since 0dffe91 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: 7.3 KB
RevLine 
[9490621]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// ForallPointerDecay.cpp --
8//
9// Author : Andrew Beach
10// Created On : Tue Dec 7 16:15:00 2021
[b1f2007d]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sun Nov 26 18:49:57 2023
13// Update Count : 2
[9490621]14//
15
16#include "ForallPointerDecay.hpp"
17
18#include "AST/Copy.hpp"
19#include "AST/Decl.hpp"
20#include "AST/DeclReplacer.hpp"
21#include "AST/Pass.hpp"
[c92bdcc]22#include "CodeGen/OperatorTable.hpp"
23#include "Common/CodeLocation.hpp"
[9feb34b]24#include "Common/ToString.hpp"
[c92bdcc]25#include "Common/Utility.hpp"
26#include "SymTab/FixFunction.hpp"
[9490621]27
28namespace Validate {
29
30namespace {
31
32// Create a function type only using information on the FunctionDecl.
33ast::FunctionType * makeFuncType( const ast::FunctionDecl * decl ) {
34 auto type = new ast::FunctionType( decl->type->isVarArgs );
35 for ( auto & param : decl->params ) {
36 type->params.emplace_back( param->get_type() );
37 }
38 for ( auto & ret : decl->returns ) {
39 type->returns.emplace_back( ret->get_type() );
40 }
41 for ( auto & type_param : decl->type_params ) {
42 type->forall.emplace_back(
[b230091]43 new ast::TypeInstType( type_param ) );
[9490621]44 }
45 for ( auto & assertion : decl->assertions ) {
46 type->assertions.emplace_back( new ast::VariableExpr(
47 assertion->location, assertion ) );
48 }
49 return type;
50}
51
[b7c53a9d]52ast::FunctionDecl * updateAssertions( ast::FunctionDecl * decl ) {
53 auto type = ast::mutate( decl->type.get() );
54 type->assertions.clear();
55 type->assertions.reserve( decl->assertions.size() );
56 for ( auto & assertion : decl->assertions ) {
57 type->assertions.emplace_back(
58 new ast::VariableExpr( decl->location, assertion ) );
[9490621]59 }
[b7c53a9d]60 decl->type = type;
61 return decl;
[9490621]62}
63
64// Component Passes:
65/// Expand assertions from a trait instance,
66/// performing appropriate type variable substitutions.
67struct TraitExpander final {
68 using AssertionList = std::vector<ast::ptr<ast::DeclWithType>>;
69
70 static AssertionList expandTrait( const ast::TraitInstType * inst ) {
71 assertf( inst->base, "Trait instance not linked to base trait: %s",
72 toCString( inst ) );
73 AssertionList assertions;
74 // Substitute trait decl parameters for instance parameters.
[4f6dda0]75 ast::TypeSubstitution sub( inst->base->params, inst->params );
[9490621]76 for ( const ast::ptr<ast::Decl> & decl : inst->base->members ) {
77 ast::ptr<ast::DeclWithType> copy =
78 ast::deepCopy( decl.strict_as<ast::DeclWithType>() );
79
80 int count = sub.apply( copy );
81 (void)count;
82
[a556492]83 // Update the type (type substution does not seem to cover it).
[9490621]84 if ( auto func = copy.as<ast::FunctionDecl>() ) {
85 auto mut = ast::mutate( func );
86 mut->type = makeFuncType( func );
87 copy = mut;
88 }
89 assertions.push_back( copy );
90 }
91 return assertions;
92 }
93
94 static AssertionList expandAssertions( const AssertionList & old ) {
95 AssertionList assertions;
96 for ( const ast::ptr<ast::DeclWithType> & decl : old ) {
97 if ( auto traitInst = dynamic_cast<const ast::TraitInstType *>(
98 decl->get_type() ) ) {
99 auto moreAsserts = expandTrait( traitInst );
[b7c53a9d]100 splice( assertions, moreAsserts );
[9490621]101 } else {
102 assertions.push_back( decl );
103 }
104 }
105 return assertions;
106 }
107
108 using TypeDeclVec = std::vector<ast::ptr<ast::TypeDecl>>;
109
110 static TypeDeclVec expandTypeDecls( const TypeDeclVec & old ) {
111 TypeDeclVec typeDecls;
[b7c53a9d]112 typeDecls.reserve( old.size() );
[9490621]113 for ( const ast::TypeDecl * typeDecl : old ) {
114 typeDecls.push_back( ast::mutate_field( typeDecl,
115 &ast::TypeDecl::assertions,
116 expandAssertions( typeDecl->assertions ) ) );
117 }
118 return typeDecls;
119 }
120
121 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl ) {
122 if ( decl->assertions.empty() ) {
123 return decl;
124 }
125 auto mut = ast::mutate( decl );
[51b8582]126 mut->assertions = expandAssertions( decl->assertions );
[a556492]127 // Update the assertion list on the type as well.
[b7c53a9d]128 return updateAssertions( mut );
[9490621]129 }
130
131 const ast::StructDecl * previsit( const ast::StructDecl * decl ) {
132 if ( decl->params.empty() ) {
133 return decl;
134 }
135 return ast::mutate_field( decl, &ast::StructDecl::params,
[51b8582]136 expandTypeDecls( decl->params ) );
[9490621]137 }
138
139 const ast::UnionDecl * previsit( const ast::UnionDecl * decl ) {
140 if ( decl->params.empty() ) {
141 return decl;
142 }
143 return ast::mutate_field( decl, &ast::UnionDecl::params,
[51b8582]144 expandTypeDecls( decl->params ) );
[9490621]145 }
146};
147
148std::vector<ast::ptr<ast::DeclWithType>> fixAssertionList(
149 const ast::ParseNode * node,
150 const std::vector<ast::ptr<ast::DeclWithType>> & assertions ) {
151 std::vector<ast::ptr<ast::DeclWithType>> ret;
[b7c53a9d]152 ret.reserve( assertions.size() );
[9490621]153 for ( const auto & assn : assertions ) {
154 bool isVoid = false;
155 ret.push_back( SymTab::fixFunction( assn, isVoid ) );
156 if ( isVoid ) {
157 SemanticError( node->location, node,
158 "invalid type void in assertion of function " );
159 }
160 }
161 return ret;
162}
163
164std::vector<ast::ptr<ast::TypeDecl>> fixTypeDeclList(
165 const ast::ParseNode * node,
166 const std::vector<ast::ptr<ast::TypeDecl>> & type_params ) {
167 std::vector<ast::ptr<ast::TypeDecl>> ret;
168 ret.reserve( type_params.size() );
169 for ( const ast::TypeDecl * type_param : type_params ) {
170 auto mutParam = ast::mutate( type_param );
171 mutParam->assertions = fixAssertionList( node, mutParam->assertions );
172 ret.push_back( mutParam );
173 }
174 return ret;
175}
176
177struct AssertionFunctionFixer final {
178 const ast::FunctionDecl * previsit( const ast::FunctionDecl * decl ) {
179 if ( decl->assertions.empty() ) {
180 return decl;
181 }
182 return ast::mutate_field( decl, &ast::FunctionDecl::assertions,
183 fixAssertionList( decl, decl->assertions ) );
184 }
185
[b7c53a9d]186 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl ) {
187 if ( decl->assertions.empty() ) {
188 return decl;
189 }
190 return updateAssertions( mutate( decl ) );
191 }
192
[9490621]193 const ast::StructDecl * previsit( const ast::StructDecl * decl ) {
194 if ( decl->params.empty() ) {
195 return decl;
196 }
197 return ast::mutate_field( decl, &ast::StructDecl::params,
198 fixTypeDeclList( decl, decl->params ) );
199 }
200
201 const ast::UnionDecl * previsit( const ast::UnionDecl * decl ) {
202 if ( decl->params.empty() ) {
203 return decl;
204 }
205 return ast::mutate_field( decl, &ast::UnionDecl::params,
206 fixTypeDeclList( decl, decl->params ) );
207 }
208};
209
[b7c53a9d]210struct OperatorChecker final {
[9490621]211 void previsit( const ast::ObjectDecl * obj ) {
[b7c53a9d]212 if ( !CodeGen::isOperator( obj->name ) ) return;
213 auto type = obj->type->stripDeclarator();
214 if ( dynamic_cast< const ast::FunctionType * >( type ) ) return;
[b1f2007d]215 SemanticError( obj->location, "operator %s is not a function or function pointer.", obj->name.c_str() );
[9490621]216 }
217};
218
219struct UniqueFixCore final {
220 const ast::DeclWithType * postvisit( const ast::DeclWithType * decl ) {
221 if ( decl->uniqueId ) {
222 return decl;
223 } else {
224 auto mut = ast::mutate( decl );
225 mut->fixUniqueId();
226 return mut;
227 }
228 }
229};
230
231} // namespace
232
233void decayForallPointers( ast::TranslationUnit & transUnit ) {
234 ast::Pass<TraitExpander>::run( transUnit );
235 ast::Pass<AssertionFunctionFixer>::run( transUnit );
[b7c53a9d]236 ast::Pass<OperatorChecker>::run( transUnit );
[14c0f7b]237}
238
239void fixUniqueIds( ast::TranslationUnit & transUnit ) {
[9490621]240 ast::Pass<UniqueFixCore>::run( transUnit );
241}
242
[298fe57]243std::vector<ast::ptr<ast::DeclWithType>> expandAssertions(
244 std::vector<ast::ptr<ast::DeclWithType>> const & old ) {
245 return TraitExpander::expandAssertions( old );
246}
247
[9490621]248} // namespace Validate
249
250// Local Variables: //
251// tab-width: 4 //
252// mode: c++ //
253// compile-command: "make install" //
254// End: //
Note: See TracBrowser for help on using the repository browser.