Changeset e9b44489 for src/AST/Stmt.cpp


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

Implemented declReplacer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.