"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "projects/CodeThorn/src/FunctionCallMapping2.C" between
rose-0.11.53.0.tar.gz and rose-0.11.54.0.tar.gz

About: ROSE is a compiler infrastructure to build source-to-source program transformation and analysis tools for large-scale C, C++, UPC, Fortran, OpenMP, Java, Python and PHP applications.

FunctionCallMapping2.C  (rose-0.11.53.0):FunctionCallMapping2.C  (rose-0.11.54.0)
skipping to change at line 15 skipping to change at line 15
#include "FunctionIdMapping.h" #include "FunctionIdMapping.h"
#include "RoseAst.h" #include "RoseAst.h"
#include "CallGraph.h" #include "CallGraph.h"
#include "CodeThornException.h" #include "CodeThornException.h"
#include "FunctionCallMapping2.h" #include "FunctionCallMapping2.h"
#include <sstream> #include <sstream>
#include <map> #include <map>
#include "AstTerm.h" #include "AstTerm.h"
namespace CodeThorn namespace CodeThorn
{ {
namespace namespace
{ {
Sawyer::Message::Facility logger;
auto logWarn() -> decltype(logger[Sawyer::Message::WARN])
{
return logger[Sawyer::Message::WARN];
}
auto logInfo() -> decltype(logger[Sawyer::Message::INFO])
{
return logger[Sawyer::Message::INFO];
}
struct Ternary struct Ternary
{ {
enum value { unknown, trueval, falseval }; enum value { unknown, trueval, falseval };
}; };
struct IsTemplate : sg::DispatchHandler<Ternary::value> struct IsTemplate : sg::DispatchHandler<Ternary::value>
{ {
typedef sg::DispatchHandler<Ternary::value> base; typedef sg::DispatchHandler<Ternary::value> base;
IsTemplate() IsTemplate()
skipping to change at line 73 skipping to change at line 62
// \note this is a using declaration, thus could be outside template // \note this is a using declaration, thus could be outside template
void handle(const SgTemplateTypedefDeclaration& n) void handle(const SgTemplateTypedefDeclaration& n)
{ {
if (n.get_templateParameters().size()) if (n.get_templateParameters().size())
yes(); yes();
else else
nope(); nope();
} }
}; };
// cloned and mildly modified from CallGraph.C
SgExpression*
getTargetExpression(SgCallExpression* sgFunCallExp)
{
SgExpression* res = sgFunCallExp->get_function();
while (SgCommaOpExp* comma = isSgCommaOpExp(res))
res = comma->get_rhs_operand();
ROSE_ASSERT(res);
return res;
}
struct CallTargetFinder : sg::DispatchHandler< std::vector<SgFunctionDeclarati
on*> >
{
using base = sg::DispatchHandler< std::vector<SgFunctionDeclaration*> >;
CallTargetFinder(VirtualFunctionAnalysis& vfuncs, SgCallExpression& call)
: base(), vfa(vfuncs), callexp(call)
{}
void objectCall(const SgBinaryOp& n);
void handle(const SgNode& n) { SG_UNEXPECTED_NODE(n); }
void handle(const SgExpression& n) { CallTargetSet::getPropertiesForExpres
sion(&callexp, nullptr /*classHierarchy*/, res); }
//~ void handle(const SgDotExp& n) { objectCall(n); }
//~ void handle(const SgArrowExp& n) { objectCall(n); }
private:
VirtualFunctionAnalysis& vfa;
SgCallExpression& callexp;
};
void CallTargetFinder::objectCall(const SgBinaryOp& n)
{
SgExpression& obj = SG_DEREF(n.get_lhs_operand());
SgType& objType = SG_DEREF(obj.get_type());
// \todo
}
// \note SgConstructorInitializer should not be handled through CallGraph.. // \note SgConstructorInitializer should not be handled through CallGraph..
std::vector<SgFunctionDeclaration*> std::vector<SgFunctionDeclaration*>
callTargets(SgCallExpression* callexp, ClassHierarchyWrapper* classHierarchy) callTargets(SgCallExpression* callexp, VirtualFunctionAnalysis* vfa)
{ {
std::vector<SgFunctionDeclaration*> targets; ASSERT_not_null(callexp); ASSERT_not_null(vfa);
ROSE_ASSERT(callexp); SgExpression* calltgt = getTargetExpression(callexp);
CallTargetSet::getPropertiesForExpression(callexp, classHierarchy, targets); return sg::dispatch(CallTargetFinder{*vfa, *callexp}, calltgt);
//~ if (targets.size() == 0)
//~ logWarn() << typeid(*callexp).name() << " - "
//~ << sg::ancestor<SgStatement>(callexp)->unparseToString()
//~ << ": found = " << targets.size()
//~ << std::endl;
// no result indicates an error, which is logged in the caller
//~ ROSE_ASSERT(targets.size());
//return std::move(targets); MS: pessimizing move
return targets;
} }
std::string typeRep(SgExpression& targetexp) std::string typeRep(SgExpression& targetexp)
{ {
ROSE_ASSERT(targetexp.get_type()); ROSE_ASSERT(targetexp.get_type());
SgFunctionType* funty = isSgFunctionType( targetexp.get_type()->findBaseType () ); SgFunctionType* funty = isSgFunctionType( targetexp.get_type()->findBaseType () );
ROSE_ASSERT(funty); ROSE_ASSERT(funty);
return funty->get_mangled().getString(); return funty->get_mangled().getString();
skipping to change at line 151 skipping to change at line 172
namespace namespace
{ {
inline inline
float percent(int part, int whole) { return (part*100.0)/whole; } float percent(int part, int whole) { return (part*100.0)/whole; }
} }
void FunctionCallMapping2::computeFunctionCallMapping(SgProject* root) void FunctionCallMapping2::computeFunctionCallMapping(SgProject* root)
{ {
typedef std::unordered_map<Label, FunctionCallTargetSet, HashLabel>::mapped_ty pe map_entry_t; typedef std::unordered_map<Label, FunctionCallTargetSet, HashLabel>::mapped_ty pe map_entry_t;
ROSE_ASSERT(labeler && root); ROSE_ASSERT(_labeler && root);
initDiagnostics();
std::multimap<std::string, SgFunctionDeclaration*> funDecls; std::multimap<std::string, SgFunctionDeclaration*> funDecls;
for(auto node : RoseAst(root)) { for(auto node : RoseAst(root)) {
if(SgFunctionDeclaration* funDecl = isSgFunctionDeclaration(node)) { if(SgFunctionDeclaration* funDecl = isSgFunctionDeclaration(node)) {
funDecls.emplace(funDecl->get_type()->get_mangled().getString(), funDecl); funDecls.emplace(funDecl->get_type()->get_mangled().getString(), funDecl);
} }
} }
int numCalls = 0; int numCalls = 0;
int unresolvedFunptrCall = 0; // could correctly remain unresolved int unresolvedFunptrCall = 0; // could correctly remain unresolved
for (Label lbl : *labeler) for (Label lbl : *_labeler)
{ {
if (!labeler->isFunctionCallLabel(lbl)) if (!_labeler->isFunctionCallLabel(lbl))
continue; continue;
SgNode* theNode = labeler->getNode(lbl); SgNode* theNode = _labeler->getNode(lbl);
//~ Goal: ROSE_ASSERT(!insideTemplatedCode(theNode)); // should not be reach able //~ Goal: ROSE_ASSERT(!insideTemplatedCode(theNode)); // should not be reach able
// filtering for templated code is not strictly necessary // filtering for templated code is not strictly necessary
// but it avoids misleading logging output // but it avoids misleading logging output
// and diluted resolution numbers. // and diluted resolution numbers.
if (insideTemplatedCode(theNode)) if (insideTemplatedCode(theNode))
{ {
// \todo shall we mark the entry as templated? // \todo shall we mark the entry as templated?
continue; continue;
skipping to change at line 216 skipping to change at line 235
mapping.erase(lbl); mapping.erase(lbl);
++unresolvedFunptrCall; ++unresolvedFunptrCall;
logWarn() << "unresolved pointer call (possibly no function with that ty pe exists): " logWarn() << "unresolved pointer call (possibly no function with that ty pe exists): "
<< callinfo.callExpression()->unparseToString() << callinfo.callExpression()->unparseToString()
<< std::endl; << std::endl;
} }
} }
else if (SgCallExpression* callexpr = callinfo.callExpression()) else if (SgCallExpression* callexpr = callinfo.callExpression())
{ {
// handles explicit function calls (incl. virtual functions) // handles explicit function calls (incl. virtual functions)
std::vector<SgFunctionDeclaration*> tgts(callTargets(callexpr, classHierar chy)); std::vector<SgFunctionDeclaration*> tgts{callTargets(callexpr, _virtualFun ctions)};
map_entry_t& map_entry = mapping[lbl]; map_entry_t& map_entry = mapping[lbl];
for (SgFunctionDeclaration* fdcl : tgts) for (SgFunctionDeclaration* fdcl : tgts)
{ {
addEntry(map_entry, fdcl); addEntry(map_entry, fdcl);
} }
if (tgts.size() == 0) if (tgts.size() == 0)
{ {
mapping.erase(lbl); mapping.erase(lbl);
skipping to change at line 259 skipping to change at line 278
} }
const int resolved = unresolvedFunptrCall + mapping.size(); const int resolved = unresolvedFunptrCall + mapping.size();
logInfo() << "Resolved " << mapping.size() << " (" << percent(resolved, numCal ls) << "%) function calls." logInfo() << "Resolved " << mapping.size() << " (" << percent(resolved, numCal ls) << "%) function calls."
<< std::endl; << std::endl;
} }
std::string FunctionCallMapping2::toString() std::string FunctionCallMapping2::toString()
{ {
ROSE_ASSERT(labeler); ROSE_ASSERT(_labeler);
std::stringstream ss; std::stringstream ss;
for(auto fcall : mapping) for(auto fcall : mapping)
{ {
SgLocatedNode* callNode = isSgLocatedNode(labeler->getNode(fcall.first)); SgLocatedNode* callNode = isSgLocatedNode(_labeler->getNode(fcall.first));
ROSE_ASSERT(callNode); ROSE_ASSERT(callNode);
ss<<SgNodeHelper::sourceFilenameLineColumnToString(callNode)<<" : "<<callNod e->unparseToString()<<" RESOLVED TO "; ss<<SgNodeHelper::sourceFilenameLineColumnToString(callNode)<<" : "<<callNod e->unparseToString()<<" RESOLVED TO ";
for(auto target : fcall.second) { for(auto target : fcall.second) {
ss<<target.toString()<<" "; ss<<target.toString()<<" ";
} }
ss<<std::endl; ss<<std::endl;
} }
return ss.str(); return ss.str();
} }
void FunctionCallMapping2::initDiagnostics() {
static bool initialized = false;
if (!initialized) {
initialized = true;
logger = Sawyer::Message::Facility("CodeThorn::FunctionCallMapping2", Rose::
Diagnostics::destination);
Rose::Diagnostics::mfacilities.insertAndAdjust(logger);
}
}
FunctionCallTargetSet FunctionCallMapping2::resolveFunctionCall(Label callLabel) FunctionCallTargetSet FunctionCallMapping2::resolveFunctionCall(Label callLabel)
{ {
//SAWYER_MESG(logger[TRACE]) << "DEBUG: @FunctionCallMapping2::resolveFunction Call:"<<funCall->unparseToString()<<endl; //SAWYER_MESG(logger[TRACE]) << "DEBUG: @FunctionCallMapping2::resolveFunction Call:"<<funCall->unparseToString()<<endl;
auto iter=mapping.find(callLabel); auto iter=mapping.find(callLabel);
if(iter!=mapping.end()) { if(iter!=mapping.end()) {
return (*iter).second; return (*iter).second;
} }
return FunctionCallTargetSet(); return FunctionCallTargetSet{};
} }
bool insideTemplatedCode(const SgNode* n) bool insideTemplatedCode(const SgNode* n)
{ {
Ternary::value res = sg::dispatch(IsTemplate(), n); Ternary::value res = sg::dispatch(IsTemplate{}, n);
if (res != Ternary::unknown) return res == Ternary::trueval; if (res != Ternary::unknown) return res == Ternary::trueval;
return insideTemplatedCode(n->get_parent()); return insideTemplatedCode(n->get_parent());
} }
} // namespace CodeThorn } // namespace CodeThorn
 End of changes. 17 change blocks. 
49 lines changed or deleted 59 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)