source: src/Validate/EnumAndPointerDecay.cpp@ 411aa65

Last change on this file since 411aa65 was a8404d9, checked in by Andrew Beach <ajbeach@…>, 7 months ago

Just some formatting clean-up I did while investigating EnumDecl::inlinedDecl.

  • Property mode set to 100644
File size: 4.0 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.hpp"
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 member : decl->members ) {
44 if ( ast::ObjectDecl const * object = member.as<ast::ObjectDecl>() ) {
45 buffer.push_back( ast::mutate_field( object,
46 &ast::ObjectDecl::type,
47 new ast::EnumInstType( decl, ast::CV::Const ) ) );
48 } else if ( auto value = member.as<ast::InlineMemberDecl>() ) {
49 auto targetEnum = symtab.lookupEnum( value->name );
50 if (!targetEnum) {
51 SemanticError(value, "Only another enum is allowed for enum inline syntax ");
52 }
53 const ast::EnumInstType * instType = new ast::EnumInstType(targetEnum);
54 mut->inlinedDecl.emplace_back( instType );
55 for ( auto enumMember : targetEnum->members ) {
56 auto enumObject = enumMember.strict_as<ast::ObjectDecl>();
57 buffer.push_back(new ast::ObjectDecl(
58 // Get the location from the "inline" declaration.
59 value->location,
60 enumObject->name,
61 // Construct a new EnumInstType as the type.
62 new ast::EnumInstType( decl, ast::CV::Const ),
63 enumObject->init,
64 enumObject->storage,
65 enumObject->linkage,
66 enumObject->bitfieldWidth,
67 {},
68 enumObject->funcSpec
69 ));
70 }
71 }
72 }
73 mut->members = buffer;
74 return mut;
75}
76
77template<typename Member>
78void fixFunctionList( CodeLocation const & location, bool isVarArgs,
79 std::vector<ast::ptr<Member>> & list ) {
80 bool hasVoid = false;
81 for ( ast::ptr<Member> & member : list ) {
82 member = SymTab::fixFunction( member, hasVoid );
83 }
84
85 // The remaining code only applies if void is present.
86 if ( !hasVoid ) {
87 return;
88 }
89
90 // So there is a void, which is only valid if it is the only argument.
91 if ( 1 < list.size() || isVarArgs ) {
92 SemanticError( location, "invalid type void in function type " );
93 }
94
95 // If a single "void" thing in the list to remove it.
96 list.clear();
97}
98
99ast::FunctionDecl const * EnumAndPointerDecayCore::previsit(
100 ast::FunctionDecl const * decl ) {
101 auto mut = ast::mutate( decl );
102 ast::ArgumentFlag isVarArgs = mut->type->isVarArgs;
103 // It seems fixFunction (via fixFunctionList) does the pointer decay part.
104 fixFunctionList( mut->location, isVarArgs, mut->params );
105 fixFunctionList( mut->location, false, mut->returns );
106 return mut;
107}
108
109ast::FunctionType const * EnumAndPointerDecayCore::previsit(
110 ast::FunctionType const * type ) {
111 assert( location );
112 auto mut = ast::mutate( type );
113 ast::ArgumentFlag isVarArgs = mut->isVarArgs;
114 // It seems fixFunction (via fixFunctionList) does the pointer decay part.
115 fixFunctionList( *location, isVarArgs, mut->params );
116 fixFunctionList( *location, false, mut->returns );
117 return mut;
118}
119
120} // namespace
121
122void decayEnumsAndPointers( ast::TranslationUnit & translationUnit ) {
123 ast::Pass<EnumAndPointerDecayCore>::run( translationUnit );
124}
125
126} // namespace Validate
127
128// Local Variables: //
129// tab-width: 4 //
130// mode: c++ //
131// compile-command: "make install" //
132// End: //
Note: See TracBrowser for help on using the repository browser.