Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SynTree/CompoundStmt.cc

    r60089f4 r23bb1b9  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 02 15:10:47 2016
     12// Last Modified On : Mon May 02 15:19:17 2016
    1313// Update Count     : 3
    1414//
     
    1818#include <algorithm>
    1919#include <functional>
     20#include "Expression.h"
     21#include "Declaration.h"
     22#include "SynTree/VarExprReplacer.h"
    2023
    2124using std::string;
     
    2730CompoundStmt::CompoundStmt( const CompoundStmt &other ) : Statement( other ) {
    2831        cloneAll( other.kids, kids );
     32
     33        // when cloning a compound statement, we may end up cloning declarations which
     34        // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
     35        // does a shallow copy, so the VariableExpr will end up pointing to the original
     36        // declaration. If the original declaration is deleted, e.g. because the original
     37        // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
     38        // find all DeclarationWithType nodes (since a VariableExpr must point to a
     39        // DeclarationWithType) in the original CompoundStmt and map them to the cloned
     40        // node in the new CompoundStmt ('this'), then replace the Declarations referred to
     41        // by each VariableExpr according to the constructed map. Note that only the declarations
     42        // in the current level are collected into the map, because child CompoundStmts will
     43        // recursively execute this routine. There may be more efficient ways of doing
     44        // this.
     45        VarExprReplacer::DeclMap declMap;
     46        std::list< Statement * >::const_iterator origit = other.kids.begin();
     47        for ( Statement * s : kids ) {
     48                assert( origit != other.kids.end() );
     49                Statement * origStmt = *origit++;
     50                if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) {
     51                        DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( origStmt );
     52                        assert( origDeclStmt );
     53                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) {
     54                                DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
     55                                assert( origdwt );
     56                                assert( dwt->get_name() == origdwt->get_name() );
     57                                declMap[ origdwt ] = dwt;
     58                        }
     59                }
     60        }
     61        if ( ! declMap.empty() ) {
     62                VarExprReplacer replacer( declMap );
     63                accept( replacer );
     64        }
    2965}
    3066
Note: See TracChangeset for help on using the changeset viewer.