source: src/ResolvExpr/ResolveTypeof.cc @ 41606df1

Last change on this file since 41606df1 was 0bd3faf, checked in by Andrew Beach <ajbeach@…>, 8 months ago

Removed forward declarations missed in the BaseSyntaxNode? removal. Removed code and modified names to support two versions of the ast.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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// ResolveTypeof.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 12:12:20 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed Mar 16 16:09:00 2022
13// Update Count     : 4
14//
15
16#include "ResolveTypeof.h"
17
18#include <cassert>  // for assert
19
20#include "AST/CVQualifiers.hpp"
21#include "AST/Node.hpp"
22#include "AST/Pass.hpp"
23#include "AST/TranslationUnit.hpp"
24#include "AST/Type.hpp"
25#include "AST/TypeEnvironment.hpp"
26#include "Common/utility.h"       // for copy
27#include "InitTweak/InitTweak.h"  // for isConstExpr
28#include "RenameVars.h"
29#include "Resolver.h"  // for resolveInVoidContext
30#include "SymTab/Mangler.h"
31
32namespace ResolvExpr {
33
34namespace {
35struct ResolveTypeof : public ast::WithShortCircuiting {
36    const ResolveContext & context;
37
38                ResolveTypeof( const ResolveContext & context ) :
39                        context( context ) {}
40
41                void previsit( const ast::TypeofType * ) { visit_children = false; }
42
43        const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
44        // pass on null expression
45            if ( ! typeofType->expr ) return typeofType;
46
47            ast::ptr< ast::Type > newType;
48            if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
49            // typeof wrapping type
50            newType = tyExpr->type;
51        } else {
52            // typeof wrapping expression
53            ast::TypeEnvironment dummy;
54            ast::ptr< ast::Expr > newExpr =
55                resolveInVoidContext( typeofType->expr, context, dummy );
56            assert( newExpr->result && ! newExpr->result->isVoid() );
57            newType = newExpr->result;
58        }
59
60        // clear qualifiers for base, combine with typeoftype quals regardless
61        if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
62            // replace basetypeof(<enum>) by int
63                                if ( newType.as< ast::EnumInstType >() ) {
64                                        newType = new ast::BasicType{
65                                                ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };
66            }
67                                reset_qualifiers(
68                                        newType,
69                                        ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
70        } else {
71                                add_qualifiers( newType, typeofType->qualifiers );
72        }
73
74        return newType.release();
75    }
76};
77} // anonymous namespace
78
79const ast::Type * resolveTypeof( const ast::Type * type , const ResolveContext & context ) {
80        ast::Pass< ResolveTypeof > mutator( context );
81        return type->accept( mutator );
82}
83
84struct FixArrayDimension {
85        const ResolveContext & context;
86        FixArrayDimension(const ResolveContext & context) : context( context ) {}
87
88        const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
89                if (!arrayType->dimension) return arrayType;
90                auto mutType = mutate(arrayType);
91                auto globalSizeType = context.global.sizeType;
92                ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
93                mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context );
94
95                if (InitTweak::isConstExpr(mutType->dimension)) {
96                        mutType->isVarLen = ast::LengthFlag::FixedLen;
97                }
98                else {
99                        mutType->isVarLen = ast::LengthFlag::VariableLen;
100                }
101                return mutType;
102        }
103};
104
105const ast::Type * fixArrayType( const ast::Type * type, const ResolveContext & context ) {
106        ast::Pass<FixArrayDimension> visitor(context);
107        return type->accept(visitor);
108}
109
110const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
111    if (decl->isTypeFixed) {
112        return decl;
113    }
114
115    auto mutDecl = mutate(decl);
116    fixObjectInit(decl, context);
117    {
118        auto resolvedType = resolveTypeof(decl->type, context);
119        resolvedType = fixArrayType(resolvedType, context);
120        mutDecl->type = resolvedType;
121    }
122
123    // Do not mangle unnamed variables.
124    if (!mutDecl->name.empty()) {
125        mutDecl->mangleName = Mangle::mangle(mutDecl);
126    }
127
128    mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
129    mutDecl->isTypeFixed = true;
130    return mutDecl;
131}
132
133const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl,
134                                     const ResolveContext &context) {
135    if (decl->isTypeFixed) {
136        return decl;
137    }
138
139    auto mutDecl = mutate(decl);
140
141    if ( auto mutListInit = mutDecl->init.as<ast::ListInit>() ) {
142        // std::list<ast::Designation *> newDesignations;       
143
144        for ( size_t k = 0; k < mutListInit->designations.size(); k++ ) {
145            const ast::Designation *des = mutListInit->designations[k].get();
146            // Desination here
147            ast::Designation * newDesignation = new ast::Designation(des->location);
148            std::deque<ast::ptr<ast::Expr>> newDesignators;
149
150            for ( ast::ptr<ast::Expr> designator : des->designators ) {
151                // Stupid flag variable for development, to be removed
152                // bool mutated = false;
153                if ( const ast::NameExpr * designatorName = designator.as<ast::NameExpr>() ) {
154                    auto candidates = context.symtab.lookupId(designatorName->name);
155                    // Does not work for the overloading case currently
156                    // assert( candidates.size() == 1 );
157                    if ( candidates.size() != 1 ) return mutDecl;
158                    auto candidate = candidates.at(0);
159                    if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) {
160                        // determine that is an enumInst, swap it with its const value
161                        assert( candidates.size() == 1 );
162                        const ast::EnumDecl * baseEnum = enumInst->base;
163                        // Need to iterate over all enum value to find the initializer to swap
164                        for ( size_t m = 0; m < baseEnum->members.size(); ++m ) {
165                            const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
166                            if ( baseEnum->members.at(m)->name == designatorName->name ) {
167                                assert(mem);
168                                newDesignators.push_back( ast::ConstantExpr::from_int(designator->location, m) );
169                                // mutated = true;
170                                break;
171                            }
172                        }
173                    } else {
174                        newDesignators.push_back( des->designators.at(0) );
175                    }
176                } else {
177                    newDesignators.push_back( des->designators.at(0) );
178                }
179            }           
180           
181            newDesignation->designators = newDesignators;
182            mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesignation);
183           
184        }
185    }
186    return mutDecl;
187}
188
189}  // namespace ResolvExpr
190
191// Local Variables: //
192// tab-width: 4 //
193// mode: c++ //
194// compile-command: "make install" //
195// End: //
Note: See TracBrowser for help on using the repository browser.