source: src/Validate/EnumAndPointerDecay.cpp@ 03c56f6

ADT ast-experimental
Last change on this file since 03c56f6 was e874605, checked in by JiadaL <j82liang@…>, 3 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.