source: src/Validate/EnumAndPointerDecay.cpp @ 11df881

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 11df881 was 11df881, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Updated documentation on pre-resolver passes, moving code to headers instead of uses. Note that some comments were just copied over, I don't know if they are accurate.

  • Property mode set to 100644
File size: 3.3 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 Jul 12 14:45:00 2022
13// Update Count     : 0
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::WithGuards {
29        CodeLocation const * location = nullptr;
30        void previsit( ast::ParseNode const * node );
31        ast::EnumDecl const * previsit( ast::EnumDecl const * decl );
32        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
33        ast::FunctionType const * previsit( ast::FunctionType const * type );
34};
35
36void EnumAndPointerDecayCore::previsit( ast::ParseNode const * node ) {
37        GuardValue( location ) = &node->location;
38}
39
40ast::EnumDecl const * EnumAndPointerDecayCore::previsit(
41                ast::EnumDecl const * decl ) {
42        if ( decl->members.empty() ) {
43                return decl;
44        }
45        // Set the type of each member of the enumeration to be EnumContant.
46        auto mut = ast::mutate( decl );
47        for ( ast::ptr<ast::Decl> & member : mut->members ) {
48                ast::ObjectDecl const * object = member.strict_as<ast::ObjectDecl>();
49                member = ast::mutate_field( object, &ast::ObjectDecl::type,
50                        new ast::EnumInstType( decl, ast::CV::Const ) );
51        }
52        GuardValue( location ) = &decl->location;
53        return mut;
54}
55
56template<typename Member>
57void fixFunctionList( CodeLocation const & location, bool isVarArgs,
58                std::vector<ast::ptr<Member>> & list ) {
59        bool hasVoid = false;
60        for ( ast::ptr<Member> & member : list ) {
61                member = SymTab::fixFunction( member, hasVoid );
62        }
63
64        // The remaining code only applies if void is present.
65        if ( !hasVoid ) {
66                return;
67        }
68
69        // So there is a void, which is only valid if it is the only argument.
70        if ( 1 < list.size() || isVarArgs ) {
71                SemanticError( location, "invalid type void in function type " );
72        }
73
74        // If a single "void" thing in the list to remove it.
75        list.clear();
76}
77
78ast::FunctionDecl const * EnumAndPointerDecayCore::previsit(
79                ast::FunctionDecl const * decl ) {
80        auto mut = ast::mutate( decl );
81        GuardValue( location ) = &decl->location;
82        ast::ArgumentFlag isVarArgs = mut->type->isVarArgs;
83        // It seems fixFunction (via fixFunctionList) does the pointer decay part.
84        fixFunctionList( mut->location, isVarArgs, mut->params );
85        fixFunctionList( mut->location, false, mut->returns );
86        return mut;
87}
88
89ast::FunctionType const * EnumAndPointerDecayCore::previsit(
90                ast::FunctionType const * type ) {
91        assert( location );
92        auto mut = ast::mutate( type );
93        ast::ArgumentFlag isVarArgs = mut->isVarArgs;
94        // It seems fixFunction (via fixFunctionList) does the pointer decay part.
95        fixFunctionList( *location, isVarArgs, mut->params );
96        fixFunctionList( *location, false, mut->returns );
97        return mut;
98}
99
100} // namespace
101
102void decayEnumsAndPointers( ast::TranslationUnit & translationUnit ) {
103        ast::Pass<EnumAndPointerDecayCore>::run( translationUnit );
104}
105
106} // namespace Validate
107
108// Local Variables: //
109// tab-width: 4 //
110// mode: c++ //
111// compile-command: "make install" //
112// End: //
Note: See TracBrowser for help on using the repository browser.