source: src/Validate/EnumAndPointerDecay.cpp@ 135143ba

ADT ast-experimental
Last change on this file since 135143ba was e9e9f56, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Used the WithCodeLocation helper in more passes. This cleans up some code and should improve efficiency.

  • Property mode set to 100644
File size: 3.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// EnumAndPointerDecay.cpp -- Normalizes enumerations and types in functions.
8//
9// Author : Andrew Beach
10// Created On : Tue Jun 28 15:50:00 2022
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue Sep 20 16:14:00 2022
13// Update Count : 1
14//
15
16#include "EnumAndPointerDecay.hpp"
17
18#include "AST/CVQualifiers.hpp"
19#include "AST/Decl.hpp"
20#include "AST/Pass.hpp"
21#include "AST/Type.hpp"
22#include "SymTab/FixFunction.h"
23
24namespace Validate {
25
26namespace {
27
28struct EnumAndPointerDecayCore final : public ast::WithCodeLocation {
29 ast::EnumDecl const * previsit( ast::EnumDecl const * decl );
30 ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
31 ast::FunctionType const * previsit( ast::FunctionType const * type );
32};
33
34ast::EnumDecl const * EnumAndPointerDecayCore::previsit(
35 ast::EnumDecl const * decl ) {
36 if ( decl->members.empty() ) {
37 return decl;
38 }
39 // Set the type of each member of the enumeration to be EnumContant.
40 auto mut = ast::mutate( decl );
41 for ( ast::ptr<ast::Decl> & member : mut->members ) {
42 ast::ObjectDecl const * object = member.strict_as<ast::ObjectDecl>();
43 member = ast::mutate_field( object, &ast::ObjectDecl::type,
44 new ast::EnumInstType( decl, ast::CV::Const ) );
45 }
46 return mut;
47}
48
49template<typename Member>
50void fixFunctionList( CodeLocation const & location, bool isVarArgs,
51 std::vector<ast::ptr<Member>> & list ) {
52 bool hasVoid = false;
53 for ( ast::ptr<Member> & member : list ) {
54 member = SymTab::fixFunction( member, hasVoid );
55 }
56
57 // The remaining code only applies if void is present.
58 if ( !hasVoid ) {
59 return;
60 }
61
62 // So there is a void, which is only valid if it is the only argument.
63 if ( 1 < list.size() || isVarArgs ) {
64 SemanticError( location, "invalid type void in function type " );
65 }
66
67 // If a single "void" thing in the list to remove it.
68 list.clear();
69}
70
71ast::FunctionDecl const * EnumAndPointerDecayCore::previsit(
72 ast::FunctionDecl const * decl ) {
73 auto mut = ast::mutate( decl );
74 ast::ArgumentFlag isVarArgs = mut->type->isVarArgs;
75 // It seems fixFunction (via fixFunctionList) does the pointer decay part.
76 fixFunctionList( mut->location, isVarArgs, mut->params );
77 fixFunctionList( mut->location, false, mut->returns );
78 return mut;
79}
80
81ast::FunctionType const * EnumAndPointerDecayCore::previsit(
82 ast::FunctionType const * type ) {
83 assert( location );
84 auto mut = ast::mutate( type );
85 ast::ArgumentFlag isVarArgs = mut->isVarArgs;
86 // It seems fixFunction (via fixFunctionList) does the pointer decay part.
87 fixFunctionList( *location, isVarArgs, mut->params );
88 fixFunctionList( *location, false, mut->returns );
89 return mut;
90}
91
92} // namespace
93
94void decayEnumsAndPointers( ast::TranslationUnit & translationUnit ) {
95 ast::Pass<EnumAndPointerDecayCore>::run( translationUnit );
96}
97
98} // namespace Validate
99
100// Local Variables: //
101// tab-width: 4 //
102// mode: c++ //
103// compile-command: "make install" //
104// End: //
Note: See TracBrowser for help on using the repository browser.