source: src/Validate/EnumAndPointerDecay.cpp @ 13edbac

ADTast-experimental
Last change on this file since 13edbac was e874605, checked in by JiadaL <j82liang@…>, 2 years ago

Add class InlineValueDecl?, which is a Declaration class that works as a placeholder for aggregration value inherited from other aggregration. Disable inline value overwrite.

  • Property mode set to 100644
File size: 3.9 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#include "Validate/NoIdSymbolTable.hpp"
24
25namespace Validate {
26
27namespace {
28
29struct EnumAndPointerDecayCore final : public WithNoIdSymbolTable, public ast::WithCodeLocation {
30        ast::EnumDecl const * previsit( ast::EnumDecl const * decl );
31        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
32        ast::FunctionType const * previsit( ast::FunctionType const * type );
33};
34
35ast::EnumDecl const * EnumAndPointerDecayCore::previsit(
36                ast::EnumDecl const * decl ) {
37        if ( decl->members.empty() ) {
38                return decl;
39        }
40        // Set the type of each member of the enumeration to be EnumContant.
41        auto mut = ast::mutate( decl );
42        std::vector<ast::ptr<ast::Decl>> buffer;
43        for ( auto it = decl->members.begin(); it != decl->members.end(); ++it ) {
44                if ( ast::ObjectDecl const * object = (*it).as<ast::ObjectDecl>() ) {
45                        buffer.push_back( ast::mutate_field( object, &ast::ObjectDecl::type, new ast::EnumInstType( decl, ast::CV::Const ) ) );
46                } else if ( ast::InlineValueDecl const * value = (*it).as<ast::InlineValueDecl>() ) {
47                        if ( auto targetEnum = symtab.lookupEnum( value->name ) ) {
48                                for ( auto singleMember : targetEnum->members ) {
49                                        auto copyingMember = singleMember.as<ast::ObjectDecl>();
50                                        buffer.push_back( new ast::ObjectDecl(
51                                                value->location, // use the "inline" location
52                                                copyingMember->name,
53                                                new ast::EnumInstType( decl, ast::CV::Const ),
54                                                // Construct a new EnumInstType as the type
55                                                copyingMember->init,
56                                                copyingMember->storage,
57                                                copyingMember->linkage,
58                                                copyingMember->bitfieldWidth,
59                                                {},
60                                                copyingMember->funcSpec
61                                        ) );
62                                }
63                        }
64                }
65        }
66        mut->members = buffer;
67        return mut;
68}
69
70template<typename Member>
71void fixFunctionList( CodeLocation const & location, bool isVarArgs,
72                std::vector<ast::ptr<Member>> & list ) {
73        bool hasVoid = false;
74        for ( ast::ptr<Member> & member : list ) {
75                member = SymTab::fixFunction( member, hasVoid );
76        }
77
78        // The remaining code only applies if void is present.
79        if ( !hasVoid ) {
80                return;
81        }
82
83        // So there is a void, which is only valid if it is the only argument.
84        if ( 1 < list.size() || isVarArgs ) {
85                SemanticError( location, "invalid type void in function type " );
86        }
87
88        // If a single "void" thing in the list to remove it.
89        list.clear();
90}
91
92ast::FunctionDecl const * EnumAndPointerDecayCore::previsit(
93                ast::FunctionDecl const * decl ) {
94        auto mut = ast::mutate( decl );
95        ast::ArgumentFlag isVarArgs = mut->type->isVarArgs;
96        // It seems fixFunction (via fixFunctionList) does the pointer decay part.
97        fixFunctionList( mut->location, isVarArgs, mut->params );
98        fixFunctionList( mut->location, false, mut->returns );
99        return mut;
100}
101
102ast::FunctionType const * EnumAndPointerDecayCore::previsit(
103                ast::FunctionType const * type ) {
104        assert( location );
105        auto mut = ast::mutate( type );
106        ast::ArgumentFlag isVarArgs = mut->isVarArgs;
107        // It seems fixFunction (via fixFunctionList) does the pointer decay part.
108        fixFunctionList( *location, isVarArgs, mut->params );
109        fixFunctionList( *location, false, mut->returns );
110        return mut;
111}
112
113} // namespace
114
115void decayEnumsAndPointers( ast::TranslationUnit & translationUnit ) {
116        ast::Pass<EnumAndPointerDecayCore>::run( translationUnit );
117}
118
119} // namespace Validate
120
121// Local Variables: //
122// tab-width: 4 //
123// mode: c++ //
124// compile-command: "make install" //
125// End: //
Note: See TracBrowser for help on using the repository browser.