Changeset e9b44489


Ignore:
Timestamp:
May 22, 2019, 3:19:07 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
f4c2f1a
Parents:
b0abc8a0
Message:

Implemented declReplacer

Location:
src/AST
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/AST/DeclReplacer.cpp

    rb0abc8a0 re9b44489  
    1414//
    1515
    16 #warning unimplemented
     16#include "DeclReplacer.hpp"
     17#include "Expr.hpp"
     18#include "Type.hpp"
     19
     20#include "Pass.hpp"
     21
     22namespace ast {
     23
     24namespace DeclReplacer {
     25        namespace {
     26                struct DeclReplacer {
     27                private:
     28                        const DeclMap & declMap;
     29                        const TypeMap & typeMap;
     30                        bool debug;
     31
     32                public:
     33                        DeclReplacer(const DeclMap & declMap, const TypeMap & typeMap, bool debug)
     34                                : declMap( declMap ), typeMap( typeMap ), debug( debug )
     35                        {}
     36
     37                        const ast::VariableExpr * previsit( const ast::VariableExpr * );
     38                        const ast::TypeInstType * previsit( const ast::TypeInstType * );
     39                };
     40        }
     41
     42        const ast::Node * replace( const ast::Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {
     43                if(!node) return nullptr;
     44                Pass<DeclReplacer> replacer = { declMap, typeMap, debug };
     45                return node->accept( replacer );
     46        }
     47
     48        const ast::Node * replace( const ast::Node * node, const DeclMap & declMap, bool debug ) {
     49                TypeMap typeMap;
     50                return replace( node, declMap, typeMap, debug );
     51        }
     52
     53        const ast::Node * replace( const ast::Node * node, const TypeMap & typeMap, bool debug ) {
     54                DeclMap declMap;
     55                return replace( node, declMap, typeMap, debug );
     56        }
     57
     58        namespace {
     59                // replace variable with new node from decl map
     60                const ast::VariableExpr * DeclReplacer::previsit( const VariableExpr * varExpr ) {
     61                        // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
     62                        if ( !declMap.count( varExpr->var ) ) return varExpr;
     63
     64                        auto replacement = declMap.at( varExpr->var );
     65                        if ( debug ) {
     66                                std::cerr << "replacing variable reference: "
     67                                        << (void*)varExpr->var.get() << " " << varExpr->var
     68                                        << " with " << (void*)replacement << " " << replacement
     69                                        << std::endl;
     70                        }
     71                        auto nexpr = mutate(varExpr);
     72                        nexpr->var = replacement;
     73                        return nexpr;
     74                }
     75
     76                const TypeInstType * DeclReplacer::previsit( const TypeInstType * inst ) {
     77                        if ( !typeMap.count( inst->base ) ) return inst;
     78
     79                        auto replacement = typeMap.at( inst->base );
     80                        if ( debug ) {
     81                                std::cerr << "replacing type reference: "
     82                                        << (void*)inst->base.get() << " " << inst->base
     83                                        << " with " << (void*)replacement << " " << replacement
     84                                        << std::endl;
     85                        }
     86                        auto ninst = mutate(inst);
     87                        ninst->base = replacement;
     88                        return ninst;
     89                }
     90        }
     91}
     92
     93}
    1794
    1895// Local Variables: //
  • src/AST/DeclReplacer.hpp

    rb0abc8a0 re9b44489  
    2525
    2626        namespace DeclReplacer {
    27                 using DeclMap = std::unordered_map< DeclWithType*, DeclWithType* >;
    28                 using TypeMap = std::unordered_map< TypeDecl*, TypeDecl* >;
     27                using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >;
     28                using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >;
    2929
    30                 void replace( Node* node, const DeclMap& declMap );
    31                 void replace( Node* node, const TypeMap& typeMap );
    32                 void replace( Node* node, const DeclMap& declMap, const TypeMap& typeMap );
     30                const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false );
     31                const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false );
     32                const Node * replace( const Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
    3333        }
    3434}
  • src/AST/Stmt.cpp

    rb0abc8a0 re9b44489  
    1616#include "Stmt.hpp"
    1717
     18
    1819#include "DeclReplacer.hpp"
     20#include "Type.hpp"
    1921
    2022namespace ast {
    2123
    2224// --- CompoundStmt
    23 CompoundStmt::CompoundStmt( const CompoundStmt& o ) : Stmt(o), kids(o.kids) {
    24         assert(!"implemented");
     25CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids(other.kids) {
     26        // when cloning a compound statement, we may end up cloning declarations which
     27        // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
     28        // does a shallow copy, so the VariableExpr will end up pointing to the original
     29        // declaration. If the original declaration is deleted, e.g. because the original
     30        // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
     31        // find all DeclarationWithType nodes (since a VariableExpr must point to a
     32        // DeclarationWithType) in the original CompoundStmt and map them to the cloned
     33        // node in the new CompoundStmt ('this'), then replace the Declarations referred to
     34        // by each VariableExpr according to the constructed map. Note that only the declarations
     35        // in the current level are collected into the map, because child CompoundStmts will
     36        // recursively execute this routine. There may be more efficient ways of doing
     37        // this.
     38        DeclReplacer::DeclMap declMap;
     39        auto origit = other.kids.begin();
     40        for ( const Stmt * s : kids ) {
     41                assert( origit != other.kids.end() );
     42                const Stmt * origStmt = *origit++;
     43                if ( const DeclStmt * declStmt = dynamic_cast< const DeclStmt * >( s ) ) {
     44                        const DeclStmt * origDeclStmt = strict_dynamic_cast< const DeclStmt * >( origStmt );
     45                        if ( const DeclWithType * dwt = dynamic_cast< const DeclWithType * > ( declStmt->decl.get() ) ) {
     46                                const DeclWithType * origdwt = strict_dynamic_cast< const DeclWithType * > ( origDeclStmt->decl.get() );
     47                                assert( dwt->name == origdwt->name );
     48                                declMap[ origdwt ] = dwt;
     49                        } else assert( ! dynamic_cast< const DeclWithType * > ( origDeclStmt->decl.get() ) );
     50                } else assert( ! dynamic_cast< const DeclStmt * > ( s ) );
     51        }
     52        if ( ! declMap.empty() ) {
     53                DeclReplacer::replace( this, declMap );
     54        }
    2555}
    2656
Note: See TracChangeset for help on using the changeset viewer.