Пример #1
0
bool ClangToSageTranslator::VisitParmVarDecl(clang::ParmVarDecl * param_var_decl, SgNode ** node) {
#if DEBUG_VISIT_DECL
    std::cerr << "ClangToSageTranslator::VisitParmVarDecl" << std::endl;
#endif
    bool res = true;

    SgName name(param_var_decl->getNameAsString());

    SgType * type = buildTypeFromQualifiedType(param_var_decl->getOriginalType());

    SgInitializer * init = NULL;

    if (param_var_decl->hasDefaultArg()) {
        SgNode * tmp_expr = Traverse(param_var_decl->getDefaultArg());
        SgExpression * expr = isSgExpression(tmp_expr);
        if (tmp_expr != NULL && expr == NULL) {
            std::cerr << "Runtime error: tmp_expr != NULL && expr == NULL" << std::endl;
            res = false;
        }
        else {
            applySourceRange(expr, param_var_decl->getDefaultArgRange());
            init = SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type());
            applySourceRange(init, param_var_decl->getDefaultArgRange());
        }
    }

    *node = SageBuilder::buildInitializedName(name, type, init);

    return VisitDeclaratorDecl(param_var_decl, node) && res;
}
Пример #2
0
bool  ClangToSageTranslator::VisitEnumConstantDecl(clang::EnumConstantDecl * enum_constant_decl, SgNode ** node) {
#if DEBUG_VISIT_DECL
    std::cerr << "ClangToSageTranslator::VisitEnumConstantDecl" << std::endl;
#endif
    bool res = true;

    SgName name(enum_constant_decl->getNameAsString());

    SgType * type = buildTypeFromQualifiedType(enum_constant_decl->getType());

    SgInitializer * init = NULL;

    if (enum_constant_decl->getInitExpr() != NULL) {
        SgNode * tmp_expr = Traverse(enum_constant_decl->getInitExpr());
        SgExpression * expr = isSgExpression(tmp_expr);
        if (tmp_expr != NULL && expr == NULL) {
            std::cerr << "Runtime error: tmp_expr != NULL && expr == NULL" << std::endl;
            res = false;
        }
        else {
            init = SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type());
        }
    }

    SgInitializedName * init_name = SageBuilder::buildInitializedName(name, type, init);

    SgEnumFieldSymbol * symbol = new SgEnumFieldSymbol(init_name);

    SageBuilder::topScopeStack()->insert_symbol(name, symbol);

    *node = init_name;

    return VisitValueDecl(enum_constant_decl, node) && res;
}
Пример #3
0
    virtual void visit(SgNode* n) {
        if (isSgBasicBlock(n)) {
            SgBasicBlock* bb = isSgBasicBlock(n);
            SgStatementPtrList& stmts = bb->get_statements();
            size_t initi;
            for (size_t decli = 0; decli < stmts.size(); ++decli) {
                if (isSgVariableDeclaration(stmts[decli])) {
                    SgVariableDeclaration* decl = isSgVariableDeclaration(stmts[decli]);
                    SgInitializedNamePtrList& vars = decl->get_variables();
                    for (size_t vari = 0; vari != vars.size(); ++vari) {
                        SgInitializedName* in = vars[vari];
                        if (in->get_initializer() == 0) {
                            bool used = false;
                            for (initi = decli + 1; initi < stmts.size();
                                    used |= containsVariableReference(stmts[initi], in),
                                    ++initi) {
                                SgExprStatement* initExprStmt = isSgExprStatement(stmts[initi]);
                                if (initExprStmt) {
                                    SgExpression* top = initExprStmt->get_expression();
                                    if (isSgAssignOp(top)) {
                                        SgVarRefExp* vr = isSgVarRefExp(isSgAssignOp(top)->get_lhs_operand());
                                        ROSE_ASSERT(isSgAssignOp(top) != NULL);
                                        SgExpression* newinit = isSgAssignOp(top)->get_rhs_operand();
                                        if (!used && vr && vr->get_symbol()->get_declaration() == in) {
                                            ROSE_ASSERT(newinit != NULL);
                                            // printf ("MoveDeclarationsToFirstUseVisitor::visit(): newinit = %p = %s \n",newinit,newinit->class_name().c_str());
                                            ROSE_ASSERT(newinit->get_type() != NULL);
                                            SgAssignInitializer* i = new SgAssignInitializer(SgNULL_FILE,newinit,newinit->get_type());
                                            i->set_endOfConstruct(SgNULL_FILE);
                                            // printf ("Built a SgAssignInitializer #1 \n");
                                            vars[vari]->set_initializer(i);
                                            stmts[initi] = decl;
                                            newinit->set_parent(i);

                                            // DQ (6/23/2006): Set the parent and file_info pointers
                                            // printf ("Setting parent of i = %p = %s to parent = %p = %s \n",i,i->class_name().c_str(),in,in->class_name().c_str());
                                            i->set_parent(in);
                                            ROSE_ASSERT(i->get_parent() != NULL);

                                            i->set_file_info(new Sg_File_Info(*(newinit->get_file_info())));
                                            ROSE_ASSERT(i->get_file_info() != NULL);

                                            // Assumes only one var per declaration FIXME
                                            ROSE_ASSERT (vars.size() == 1);
                                            stmts.erase(stmts.begin() + decli);
                                            --decli; // To counteract ++decli in loop header
                                            break; // To get out of initi loop
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
Пример #4
0
void RtedTransformation::transformPtrDerefs(SharedPtrDerefContainer::value_type ptrderef)
{
    ROSE_ASSERT(ptrderef);

    SgExpression* operand = ptrderef->get_operand();
    ROSE_ASSERT ( isUpcSharedPointer(operand->get_type()) );

    SgStatement*   stmt = getSurroundingStatement(*ptrderef);
    SgExprListExp* lock_args   = SB::buildExprListExp();
    SgExprListExp* unlock_args = SB::buildExprListExp();

    SI::appendExpression(lock_args,   SI::deepCopy(operand));
    SI::appendExpression(unlock_args, SI::deepCopy(operand));

    insertCheck(ilBefore, stmt, symbols.roseUpcEnterSharedPtr, lock_args);
    insertCheck(ilAfter,  stmt, symbols.roseUpcExitSharedPtr,  unlock_args);
}
Пример #5
0
bool ClangToSageTranslator::VisitFieldDecl(clang::FieldDecl * field_decl, SgNode ** node) {
#if DEBUG_VISIT_DECL
    std::cerr << "ClangToSageTranslator::VisitFieldDecl" << std::endl;
#endif  
    bool res = true;
    
    SgName name(field_decl->getNameAsString());

    SgType * type = buildTypeFromQualifiedType(field_decl->getType());

    clang::Expr * init_expr = field_decl->getInClassInitializer();
    SgNode * tmp_init = Traverse(init_expr);
    SgExpression * expr = isSgExpression(tmp_init);
    // TODO expression list if aggregated initializer !
    if (tmp_init != NULL && expr == NULL) {
        std::cerr << "Runtime error: not a SgInitializer..." << std::endl;
        res = false;
    }
    SgInitializer * init = expr != NULL ? SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type()) : NULL;
    if (init != NULL)
        applySourceRange(init, init_expr->getSourceRange());

  // Cannot use 'SageBuilder::buildVariableDeclaration' because of anonymous field
    // *node = SageBuilder::buildVariableDeclaration(name, type, init, SageBuilder::topScopeStack());
  // Build it by hand...
    SgVariableDeclaration * var_decl = new SgVariableDeclaration(name, type, init);

    if (isSgClassType(type)) {
        std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type));
        ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end());
        if (bool_it->second) {
            var_decl->set_baseTypeDefiningDeclaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration());
            var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true);
        }
    }
    else if (isSgEnumType(type)) {
        std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type));
        ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end());
        if (bool_it->second) {
            var_decl->set_baseTypeDefiningDeclaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration());
            var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true);
        }
    }

    var_decl->set_firstNondefiningDeclaration(var_decl);
    var_decl->set_parent(SageBuilder::topScopeStack());

    ROSE_ASSERT(var_decl->get_variables().size() == 1);

    SgInitializedName * init_name = var_decl->get_variables()[0];
    ROSE_ASSERT(init_name != NULL);
    init_name->set_scope(SageBuilder::topScopeStack());

    applySourceRange(init_name, field_decl->getSourceRange());

    SgVariableDefinition * var_def = isSgVariableDefinition(init_name->get_declptr());
    ROSE_ASSERT(var_def != NULL);
    applySourceRange(var_def, field_decl->getSourceRange());

    SgVariableSymbol * var_symbol = new SgVariableSymbol(init_name);
    SageBuilder::topScopeStack()->insert_symbol(name, var_symbol);

    *node = var_decl;

    return VisitDeclaratorDecl(field_decl, node) && res; 
}
Пример #6
0
bool ClangToSageTranslator::VisitVarDecl(clang::VarDecl * var_decl, SgNode ** node) {
#if DEBUG_VISIT_DECL
    std::cerr << "ClangToSageTranslator::VisitVarDecl" << std::endl;
#endif
    bool res = true;

  // Create the SAGE node: SgVariableDeclaration

    SgName name(var_decl->getNameAsString());

    SgType * type = buildTypeFromQualifiedType(var_decl->getType());

    clang::Expr * init_expr = var_decl->getInit();
    SgNode * tmp_init = Traverse(init_expr);
    SgExpression * expr = isSgExpression(tmp_init);
    if (tmp_init != NULL && expr == NULL) {
        std::cerr << "Runtime error: not a SgInitializer..." << std::endl; // TODO
        res = false;
    }
    SgExprListExp * expr_list_expr = isSgExprListExp(expr);

    SgInitializer * init = NULL;
    if (expr_list_expr != NULL)
        init = SageBuilder::buildAggregateInitializer(expr_list_expr, type);
    else if (expr != NULL)
        init = SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type());
    if (init != NULL)
        applySourceRange(init, init_expr->getSourceRange());

    SgVariableDeclaration * sg_var_decl = new SgVariableDeclaration(name, type, init); // scope: obtain from the scope stack.

    if (isSgClassType(type)) {
        std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type));
        ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end());
        if (bool_it->second) {
            sg_var_decl->set_baseTypeDefiningDeclaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration());
            sg_var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true);
        }
    }
    else if (isSgEnumType(type)) {
        std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type));
        ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end());
        if (bool_it->second) {
            sg_var_decl->set_baseTypeDefiningDeclaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration());
            sg_var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true);
        }
    }

    sg_var_decl->set_firstNondefiningDeclaration(sg_var_decl);
    sg_var_decl->set_parent(SageBuilder::topScopeStack());

    ROSE_ASSERT(sg_var_decl->get_variables().size() == 1);

    SgInitializedName * init_name = sg_var_decl->get_variables()[0];
    ROSE_ASSERT(init_name != NULL);
    init_name->set_scope(SageBuilder::topScopeStack());

    applySourceRange(init_name, var_decl->getSourceRange());

    SgVariableDefinition * var_def = isSgVariableDefinition(init_name->get_declptr());
    ROSE_ASSERT(var_def != NULL);
    applySourceRange(var_def, var_decl->getSourceRange());

    SgVariableSymbol * var_symbol = new SgVariableSymbol(init_name);
    SageBuilder::topScopeStack()->insert_symbol(name, var_symbol);

    *node = sg_var_decl;

    return VisitDeclaratorDecl(var_decl, node) && res;
}
Пример #7
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
   {
#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     SgGlobal* globalScope = TransformationSupport::getGlobalScope(funcall);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

     SgExpression* funname = funcall->get_function();
     SgExpression* funname2 = isSgFunctionRefExp(funname);
     SgDotExp* dotexp = isSgDotExp(funname);
     SgArrowExp* arrowexp = isSgArrowExp(funname);
     SgExpression* thisptr = 0;
     if (dotexp || arrowexp)
        {
          funname2 = isSgBinaryOp(funname)->get_rhs_operand();
          if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
              SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
              ROSE_ASSERT (isSgInitializer(ai->get_operand()));
#if 1
              printf ("ai = %p ai->isTransformation() = %s \n",ai,ai->isTransformation() ? "true" : "false");
#endif
              SgInitializedName* in = isSgInitializedName(ai->get_parent());
              ROSE_ASSERT (in);
              removeRedundantCopyInConstruction(in);
              lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
          } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
          } else {
            assert (false);
          }
        }

     if (!funname2)
        {
       // std::cout << "Inline failed: not a call to a named function" << std::endl;
          return false; // Probably a call through a fun ptr
        }

     SgFunctionSymbol* funsym = 0;
     if (isSgFunctionRefExp(funname2))
          funsym = isSgFunctionRefExp(funname2)->get_symbol();
       else
          if (isSgMemberFunctionRefExp(funname2))
               funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
            else
               assert (false);

     assert (funsym);
     if (isSgMemberFunctionSymbol(funsym) &&
         isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
        {
       // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
          return false;
        }

     SgFunctionDeclaration* fundecl = funsym->get_declaration();
     fundecl = fundecl ? isSgFunctionDeclaration(fundecl->get_definingDeclaration()) : NULL;

     SgFunctionDefinition* fundef = fundecl ? fundecl->get_definition() : NULL;
     if (!fundef)
        {
       // std::cout << "Inline failed: no definition is visible" << std::endl;
          return false; // No definition of the function is visible
        }
     if (!allowRecursion)
        {
          SgNode* my_fundef = funcall;
          while (my_fundef && !isSgFunctionDefinition(my_fundef))
             {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
               my_fundef = my_fundef->get_parent();
               ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
             }
       // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
          assert (isSgFunctionDefinition(my_fundef));
          if (isSgFunctionDefinition(my_fundef) == fundef)
             {
               std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
               return false;
             }
        }

     SgVariableDeclaration* thisdecl = 0;
     SgName thisname("this__");
     thisname << ++gensym_counter;
     SgInitializedName* thisinitname = 0;
     if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
        {
          assert (thisptr != NULL);
          SgType* thisptrtype = thisptr->get_type();
          const SgSpecialFunctionModifier& specialMod = 
            funsym->get_declaration()->get_specialFunctionModifier();
          if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
          }
          SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
       // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
          thisptrtype = new SgModifierType(thisptrtype);
          isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
       // }
       // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
          SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
          assignInitializer->set_endOfConstruct(SgNULL_FILE);
#if 1
          printf ("before new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
#if 1
          printf ("(after new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl->set_endOfConstruct(SgNULL_FILE);
          thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
          thisdecl->set_definingDeclaration(thisdecl);

          thisinitname = (thisdecl->get_variables()).back();
          //thisinitname = lastElementOfContainer(thisdecl->get_variables());
          // thisinitname->set_endOfConstruct(SgNULL_FILE);
          assignInitializer->set_parent(thisinitname);
          markAsTransformation(assignInitializer);

       // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

       // DQ (6/23/2006): New test
          ROSE_ASSERT(assignInitializer->get_parent() != NULL);
        }

     // Get the list of actual argument expressions from the function call, which we'll later use to initialize new local
     // variables in the inlined code.  We need to detach the actual arguments from the AST here since we'll be reattaching
     // them below (otherwise we would violate the invariant that the AST is a tree).
     SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);
     SgExpressionPtrList funargs = funcall->get_args()->get_expressions();
     funcall->get_args()->get_expressions().clear();
     BOOST_FOREACH (SgExpression *actual, funargs)
         actual->set_parent(NULL);

     // Make a copy of the to-be-inlined function so we're not modifying and (re)inserting the original.
     SgBasicBlock* funbody_raw = fundef->get_body();
     SgInitializedNamePtrList& params = fundecl->get_args();
     std::vector<SgInitializedName*> inits;
     SgTreeCopy tc;
     SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
     ROSE_ASSERT (function_copy);
     SgBasicBlock* funbody_copy = function_copy->get_body();

     renameLabels(funbody_copy, targetFunction);
     ASSERT_require(funbody_raw->get_symbol_table()->size() == funbody_copy->get_symbol_table()->size());

     // We don't need to keep the copied SgFunctionDefinition now that the labels in it have been moved to the target function
     // (having it in the memory pool confuses the AST tests), but we must not delete the formal argument list or the body
     // because we need them below.
     if (function_copy->get_declaration()) {
         ASSERT_require(function_copy->get_declaration()->get_parent() == function_copy);
         function_copy->get_declaration()->set_parent(NULL);
         function_copy->set_declaration(NULL);
     }
     if (function_copy->get_body()) {
         ASSERT_require(function_copy->get_body()->get_parent() == function_copy);
         function_copy->get_body()->set_parent(NULL);
         function_copy->set_body(NULL);
     }
     delete function_copy;
     function_copy = NULL;
#if 0
     SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
     pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaBegin->set_parent(pragmaBeginDecl);
     pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
     funbody_copy->prepend_statement(pragmaBeginDecl);
     pragmaBeginDecl->set_parent(funbody_copy);
#endif

     // In the to-be-inserted function body, create new local variables with distinct non-conflicting names, one per formal
     // argument and having the same type as the formal argument. Initialize those new local variables with the actual
     // arguments.  Also, build a paramMap that maps each formal argument (SgInitializedName) to its corresponding new local
     // variable (SgVariableSymbol).
     ReplaceParameterUseVisitor::paramMapType paramMap;
     SgInitializedNamePtrList::iterator formalIter = params.begin();
     SgExpressionPtrList::iterator actualIter = funargs.begin();
     for (size_t argNumber=0;
          formalIter != params.end() && actualIter != funargs.end();
          ++argNumber, ++formalIter, ++actualIter) {
         SgInitializedName *formalArg = *formalIter;
         SgExpression *actualArg = *actualIter;

         // Build the new local variable.
         // FIXME[Robb P. Matzke 2014-12-12]: we need a better way to generate a non-conflicting local variable name
         SgAssignInitializer* initializer = new SgAssignInitializer(SgNULL_FILE, actualArg, formalArg->get_type());
         ASSERT_not_null(initializer);
         initializer->set_endOfConstruct(SgNULL_FILE);
#if 1
         printf ("initializer = %p initializer->isTransformation() = %s \n",initializer,initializer->isTransformation() ? "true" : "false");
#endif
         SgName shadow_name(formalArg->get_name());
         shadow_name << "__" << ++gensym_counter;
         SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE, shadow_name, formalArg->get_type(), initializer);
         vardecl->set_definingDeclaration(vardecl);
         vardecl->set_endOfConstruct(SgNULL_FILE);
         vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
         vardecl->set_parent(funbody_copy);

         // Insert the new local variable into the (near) beginning of the to-be-inserted function body.  We insert them in the
         // order their corresponding actuals/formals appear, although the C++ standard does not require this order of
         // evaluation.
         SgInitializedName* init = vardecl->get_variables().back();
         inits.push_back(init);
         initializer->set_parent(init);
         init->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + argNumber, vardecl);
         SgVariableSymbol* sym = new SgVariableSymbol(init);
         paramMap[formalArg] = sym;
         funbody_copy->insert_symbol(shadow_name, sym);
         sym->set_parent(funbody_copy->get_symbol_table());
     }

     // Similarly for "this". We create a local variable in the to-be-inserted function body that will be initialized with the
     // caller's "this".
     if (thisdecl) {
         thisdecl->set_parent(funbody_copy);
         thisinitname->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
         SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
         funbody_copy->insert_symbol(thisname, thisSym);
         thisSym->set_parent(funbody_copy->get_symbol_table());
         ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
     }
     ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

     SgName end_of_inline_name = "rose_inline_end__";
     end_of_inline_name << ++gensym_counter;
     SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
     end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
     printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

  // Need to set the parent of funbody_copy to avoid error.
     funbody_copy->set_parent(funbody_raw->get_parent());

     printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

     printf ("funbody_raw->get_statements().size()  = %" PRIuPTR " \n",funbody_raw->get_statements().size());
     printf ("funbody_copy->get_statements().size() = %" PRIuPTR " \n",funbody_copy->get_statements().size());

     printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
     printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

     printf ("Output the symbol table for funbody_raw \n");
     funbody_raw->get_symbol_table()->print("debugging copy problem");

  // printf ("Output the symbol table for funbody_copy \n");
  // funbody_copy->get_symbol_table()->print("debugging copy problem");

     SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
     ROSE_ASSERT(project_copy != NULL);

     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
     generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

     funbody_copy->append_statement(end_of_inline_label);
     end_of_inline_label->set_scope(targetFunction);
     SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
     end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
     targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);

     // To ensure that there is some statement after the label
     SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
     dummyStatement->set_endOfConstruct(SgNULL_FILE);
     funbody_copy->append_statement(dummyStatement);
     dummyStatement->set_parent(funbody_copy);
#if 0
     SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
     pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaEnd->set_parent(pragmaEndDecl);
     pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
     funbody_copy->append_statement(pragmaEndDecl);
     pragmaEndDecl->set_parent(funbody_copy);
#endif

     ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
     replaceExpressionWithStatement(funcall, &previsitor);

     // Make sure the AST is consistent. To save time, we'll just fix things that we know can go wrong. For instance, the
     // SgAsmExpression.p_lvalue data member is required to be true for certain operators and is set to false in other
     // situations. Since we've introduced new expressions into the AST we need to adjust their p_lvalue according to the
     // operators where they were inserted.
     markLhsValues(targetFunction);
#ifdef NDEBUG
     AstTests::runAllTests(SageInterface::getProject());
#endif

#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

  // DQ (4/7/2015): This fixes something I was required to fix over the weekend and which is fixed more directly, I think.
  // Mark the things we insert as being transformations so they get inserted into the output by backend()
     markAsTransformation(funbody_copy);

     return true;
   }
Пример #8
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
{
    SgExpression* funname = funcall->get_function();
    SgExpression* funname2 = isSgFunctionRefExp(funname);
    SgDotExp* dotexp = isSgDotExp(funname);
    SgArrowExp* arrowexp = isSgArrowExp(funname);
    SgExpression* thisptr = 0;
    if (dotexp || arrowexp)
    {
        funname2 = isSgBinaryOp(funname)->get_rhs_operand();
        if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
                SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
                ROSE_ASSERT (isSgInitializer(ai->get_operand()));
                SgInitializedName* in = isSgInitializedName(ai->get_parent());
                ROSE_ASSERT (in);
                removeRedundantCopyInConstruction(in);
                lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
        } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
        } else {
            assert (false);
        }
    }

    if (!funname2)
    {
        // std::cout << "Inline failed: not a call to a named function" << std::endl;
        return false; // Probably a call through a fun ptr
    }

    SgFunctionSymbol* funsym = 0;
    if (isSgFunctionRefExp(funname2))
        funsym = isSgFunctionRefExp(funname2)->get_symbol();
    else if (isSgMemberFunctionRefExp(funname2))
        funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
    else
        assert (false);

    assert (funsym);
    if (isSgMemberFunctionSymbol(funsym) && isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
    {
        // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
        return false;
    }

    SgFunctionDeclaration* fundecl = funsym->get_declaration();
    SgFunctionDefinition* fundef = fundecl->get_definition();
    if (!fundef)
    {
        // std::cout << "Inline failed: no definition is visible" << std::endl;
        return false; // No definition of the function is visible
    }
    if (!allowRecursion)
    {
        SgNode* my_fundef = funcall;
        while (my_fundef && !isSgFunctionDefinition(my_fundef))
        {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
            my_fundef = my_fundef->get_parent();
            ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        }
        // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        assert (isSgFunctionDefinition(my_fundef));
        if (isSgFunctionDefinition(my_fundef) == fundef)
        {
            std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
            return false;
        }
    }

    SgVariableDeclaration* thisdecl = 0;
    SgName thisname("this__");
    thisname << ++gensym_counter;
    SgInitializedName* thisinitname = 0;
    if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
    {
        assert (thisptr != NULL);
        SgType* thisptrtype = thisptr->get_type();
        const SgSpecialFunctionModifier& specialMod =
            funsym->get_declaration()->get_specialFunctionModifier();
        if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
        }
        SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
        // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
        thisptrtype = new SgModifierType(thisptrtype);
        isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
        // }
        // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
        SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
        assignInitializer->set_endOfConstruct(SgNULL_FILE);
        // thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, new SgAssignInitializer(SgNULL_FILE, thisptr));
        thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
        thisdecl->set_endOfConstruct(SgNULL_FILE);
        thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
        thisdecl->set_definingDeclaration(thisdecl);

        thisinitname = (thisdecl->get_variables()).back();
        //thisinitname = lastElementOfContainer(thisdecl->get_variables());
        // thisinitname->set_endOfConstruct(SgNULL_FILE);
        assignInitializer->set_parent(thisinitname);

        // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

        // DQ (6/23/2006): New test
        ROSE_ASSERT(assignInitializer->get_parent() != NULL);
    }

    std::cout << "Trying to inline function " << fundecl->get_name().str() << std::endl;
    SgBasicBlock* funbody_raw = fundef->get_body();
    SgInitializedNamePtrList& params = fundecl->get_args();
    SgInitializedNamePtrList::iterator i;
    SgExpressionPtrList& funargs = funcall->get_args()->get_expressions();
    SgExpressionPtrList::iterator j;
    //int ctr; // unused variable, Liao
    std::vector<SgInitializedName*> inits;
    SgTreeCopy tc;
    SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
    ROSE_ASSERT (function_copy);
    SgBasicBlock* funbody_copy = function_copy->get_body();


    SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);

    renameLabels(funbody_copy, targetFunction);
    std::cout << "Original symbol count: " << funbody_raw->get_symbol_table()->size() << std::endl;
    std::cout << "Copied symbol count: " << funbody_copy->get_symbol_table()->size() << std::endl;
    // std::cout << "Original symbol count f: " << fundef->get_symbol_table()->size() << std::endl;
    // std::cout << "Copied symbol count f: " << function_copy->get_symbol_table()->size() << std::endl;
    // We don't need to keep the copied function definition now that the
    // labels in it have been moved to the target function.  Having it in the
    // memory pool confuses the AST tests.
    function_copy->set_declaration(NULL);
    function_copy->set_body(NULL);
    delete function_copy;
    function_copy = NULL;
#if 0
    SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
    pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaBegin->set_parent(pragmaBeginDecl);
    pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
    funbody_copy->prepend_statement(pragmaBeginDecl);
    pragmaBeginDecl->set_parent(funbody_copy);
#endif
    ReplaceParameterUseVisitor::paramMapType paramMap;
    for (i = params.begin(), j = funargs.begin(); i != params.end() && j != funargs.end(); ++i, ++j)
    {
        SgAssignInitializer* ai = new SgAssignInitializer(SgNULL_FILE, *j, (*i)->get_type());
        ROSE_ASSERT(ai != NULL);
        ai->set_endOfConstruct(SgNULL_FILE);
        SgName shadow_name((*i)->get_name());
        shadow_name << "__" << ++gensym_counter;
        SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE,shadow_name,(*i)->get_type(),ai);
        vardecl->set_definingDeclaration(vardecl);
        vardecl->set_endOfConstruct(SgNULL_FILE);
        vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);

        printf ("Built new SgVariableDeclaration #2 = %p = %s initializer = %p \n",vardecl,shadow_name.str(),(*(vardecl->get_variables().begin()))->get_initializer());

        vardecl->set_parent(funbody_copy);
        SgInitializedName* init = (vardecl->get_variables()).back();
        // init->set_endOfConstruct(SgNULL_FILE);
        inits.push_back(init);
        ai->set_parent(init);
        init->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + (i - params.begin()), vardecl);
        SgVariableSymbol* sym = new SgVariableSymbol(init);
        paramMap[*i] = sym;
        funbody_copy->insert_symbol(shadow_name, sym);
        sym->set_parent(funbody_copy->get_symbol_table());
    }

    if (thisdecl)
    {
        thisdecl->set_parent(funbody_copy);
        thisinitname->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
        SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
        funbody_copy->insert_symbol(thisname, thisSym);
        thisSym->set_parent(funbody_copy->get_symbol_table());
        ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
    }
    ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

    SgName end_of_inline_name = "rose_inline_end__";
    end_of_inline_name << ++gensym_counter;
    SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
    end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
    printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

    // Need to set the parent of funbody_copy to avoid error.
    funbody_copy->set_parent(funbody_raw->get_parent());

    printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

    printf ("funbody_raw->get_statements().size()  = %zu \n",funbody_raw->get_statements().size());
    printf ("funbody_copy->get_statements().size() = %zu \n",funbody_copy->get_statements().size());

    printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
    printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

    printf ("Output the symbol table for funbody_raw \n");
    funbody_raw->get_symbol_table()->print("debugging copy problem");

    // printf ("Output the symbol table for funbody_copy \n");
    // funbody_copy->get_symbol_table()->print("debugging copy problem");

    SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
    ROSE_ASSERT(project_copy != NULL);

    const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
    generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

    // printf ("Exiting as a test after testing the symbol table \n");
    // ROSE_ASSERT(false);

    funbody_copy->append_statement(end_of_inline_label);
    end_of_inline_label->set_scope(targetFunction);
    SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
    end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
    targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);
    // To ensure that there is some statement after the label
    SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
    dummyStatement->set_endOfConstruct(SgNULL_FILE);
    funbody_copy->append_statement(dummyStatement);
    dummyStatement->set_parent(funbody_copy);
#if 0
    SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
    pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaEnd->set_parent(pragmaEndDecl);
    pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
    funbody_copy->append_statement(pragmaEndDecl);
    pragmaEndDecl->set_parent(funbody_copy);
#endif
    // std::cout << "funbody_copy is " << funbody_copy->unparseToString() << std::endl;

    ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
    // std::cout << "funbody_copy 2 is " << funbody_copy->unparseToString() << std::endl;
    replaceExpressionWithStatement(funcall, &previsitor);
    // std::cout << "Inline succeeded " << funcall->get_parent()->unparseToString() << std::endl;
    return true;
}
Пример #9
0
//searches for locations where types may be connected through assignment, passing as argument and returns
//then passes the associated node along with the expression to link variables.
int Analysis::variableSetAnalysis(SgProject* project, SgType* matchType, bool base){
  RoseAst wholeAST(project);
  list<SgVariableDeclaration*> listOfGlobalVars = SgNodeHelper::listOfGlobalVars(project);
  if(listOfGlobalVars.size() > 0){
    for(auto varDec : listOfGlobalVars){
      SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDec);
      if(!initName) continue;
      SgInitializer* init = initName->get_initializer();
      if(!init) continue;
      SgType* keyType = initName->get_type();
      if(!checkMatch(base, keyType, matchType)) continue;
      addToMap(varDec, varDec);  
      if(!isArrayPointerType(keyType)) continue;
      SgExpression* exp = init;
      linkVariables(varDec, keyType, exp);
    }
  }
  list<SgFunctionDefinition*> listOfFunctionDefinitions = SgNodeHelper::listOfFunctionDefinitions(project);
  for(auto funDef : listOfFunctionDefinitions){  
    SgInitializedNamePtrList& initNameList = SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef);
    SgFunctionDeclaration* funDec = funDef->get_declaration();
    if(checkMatch(base, funDec->get_type()->get_return_type(), matchType)) addToMap(funDec, funDec);
    for(auto init : initNameList) if(checkMatch(base, init->get_type(), matchType)) addToMap(init, init);
    RoseAst ast(funDef);
    for(RoseAst::iterator i = ast.begin(); i!=ast.end(); i++){
      SgNode* key = nullptr;
      SgType* keyType = nullptr;
      SgExpression* exp = nullptr;
      if(SgAssignOp* assignOp = isSgAssignOp(*i)){
        SgExpression* lhs = assignOp->get_lhs_operand();
        if(SgVarRefExp* varRef = isSgVarRefExp(lhs)){
          keyType = varRef->get_type();
          if(!isArrayPointerType(keyType)) continue;    
          SgVariableSymbol* varSym = varRef->get_symbol();
	  key = varSym->get_declaration()->get_declaration();
        }
        exp = assignOp->get_rhs_operand();
      }
      else if(SgVariableDeclaration* varDec = isSgVariableDeclaration(*i)){
        SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDec);
        if(!initName) continue;
        if(checkMatch(base, matchType, initName->get_type())) addToMap(varDec, varDec);
        SgInitializer* init = initName->get_initializer();
        if(!init) continue;
        keyType = initName->get_type();
        if(!isArrayPointerType(keyType)) continue;
        key = initName->get_declaration();
        exp = init;
      }
      else if(SgFunctionCallExp* callExp = isSgFunctionCallExp(*i)){
        SgFunctionDefinition* funDef = SgNodeHelper::determineFunctionDefinition(callExp);
        if(!funDef) continue;
        SgInitializedNamePtrList& initNameList = SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef);
        SgExpressionPtrList& expList = callExp->get_args()->get_expressions();
        auto initIter = initNameList.begin();
        auto expIter  = expList.begin(); 
        while(initIter != initNameList.end()){
          if(isArrayPointerType((*initIter)->get_type())){
            if(checkMatch(base, matchType, (*initIter)->get_type())) linkVariables((*initIter), (*initIter)->get_type(), (*expIter));
          }
          ++initIter;
          ++expIter;
        }
      }
      else if(SgReturnStmt* ret = isSgReturnStmt(*i)){
        exp = ret->get_expression();
        keyType = exp->get_type();
        if(!isArrayPointerType(keyType)) continue;
        key = funDec;
         
      }
      if(!checkMatch(base, keyType, matchType)) continue;
      if(key && keyType && exp) linkVariables(key, keyType, exp);
    }
  }
  for(auto i = setMap.begin(); i != setMap.end(); ++i){
    bool intersect = false;
    set<SgNode*>* found = nullptr;
    for(auto j = listSets.begin(); j != listSets.end(); ++j){
      intersect = setIntersect(*j, i->second);
      if((*j)->count(i->first)) intersect = true;
      if(found != nullptr && intersect){ 
        inPlaceUnion(found, i->second);
        inPlaceUnion(found, *j);
        (found)->insert(i->first);
        j = listSets.erase(j);
        ++j;
      }
      else if(intersect){
        inPlaceUnion(*j, i->second);
        (*j)->insert(i->first);
        found = *j;
      }
    }
    if(!intersect){
      set<SgNode*>* copy = copySet(i->second);
      copy->insert(i->first);
      listSets.push_back(copy);
    }
  }
  return 0;
}
bool isMethodCall(SgFunctionCallExp *functionCall, bool &isDotExp, bool &lhsIsRefOrPtr)
{
  ROSE_ASSERT(functionCall != NULL);

  SgExpression *expression = functionCall->get_function();
  ROSE_ASSERT(expression != NULL);

  bool isMethod = false;
  isDotExp = false;
  lhsIsRefOrPtr = false;

  switch(expression->variantT()) {
  case V_SgDotExp:
    {
      isMethod = true;

      SgDotExp *dotExp = isSgDotExp(expression);
      ROSE_ASSERT(dotExp != NULL);
	  
      SgExpression *lhs = dotExp->get_lhs_operand();
      ROSE_ASSERT(lhs != NULL);
	  
      SgPointerDerefExp *pointerDerefExp =
	isSgPointerDerefExp(lhs);
	  
      if ( pointerDerefExp != NULL ) {
	;
      } else {
	isDotExp = true;
      }

      lhsIsRefOrPtr = isSgReferenceType(lhs->get_type());

      break;
    }
  case V_SgArrowExp:
    {
      isMethod = true;
      lhsIsRefOrPtr = true;
      break;
    }
  case V_SgMemberFunctionRefExp:
    {
      isMethod = true;
      break;
    }
  case V_SgFunctionRefExp:
  case V_SgPointerDerefExp:
    {
      isMethod = false;
      break;
    }
  default:
    {
      std::cerr << "Was not expecting an " << expression->sage_class_name() << std::endl;
      std::cerr << "in a function call." << std::endl;
      ROSE_ABORT();
    }
  }

  return isMethod;
}