"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "projects/CodeThorn/src/ClassHierarchyAnalysis.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.

ClassHierarchyAnalysis.C  (rose-0.11.53.0):ClassHierarchyAnalysis.C  (rose-0.11.54.0)
skipping to change at line 28 skipping to change at line 28
{ {
return keyval.first; return keyval.first;
} }
template <class... Elems> template <class... Elems>
auto key(const std::tuple<Elems...>& keydata) -> decltype( std::get<0>(keydata ) ) auto key(const std::tuple<Elems...>& keydata) -> decltype( std::get<0>(keydata ) )
{ {
return std::get<0>(keydata); return std::get<0>(keydata);
} }
auto key(ct::FunctionId keydata) -> ct::FunctionId auto key(ct::FunctionKeyType keydata) -> ct::FunctionKeyType
{ {
return keydata; return keydata;
} }
/// \brief traverses two ordered associative sequences in order of their elem ents. /// \brief traverses two ordered associative sequences in order of their elem ents.
/// The elements in the sequences must be convertible. A merge object /// The elements in the sequences must be convertible. A merge object
/// is called with sequence elements in order of their keys in [aa1, z z1) and [aa2, zz2). /// is called with sequence elements in order of their keys in [aa1, z z1) and [aa2, zz2).
/// \tparam _Iterator1 an iterator of an ordered associative container /// \tparam _Iterator1 an iterator of an ordered associative container
/// \tparam _Iterator2 an iterator of an ordered associative container /// \tparam _Iterator2 an iterator of an ordered associative container
/// \tparam BinaryOperator a merge object that provides three operator() /// \tparam BinaryOperator a merge object that provides three operator()
skipping to change at line 105 skipping to change at line 105
{ {
void void
ClassAnalysis::addInheritanceEdge(value_type& descendantEntry, ClassKeyType ance storKey, bool virtualEdge, bool directEdge) ClassAnalysis::addInheritanceEdge(value_type& descendantEntry, ClassKeyType ance storKey, bool virtualEdge, bool directEdge)
{ {
ClassKeyType descendantKey = descendantEntry.first; ClassKeyType descendantKey = descendantEntry.first;
ClassData& descendant = descendantEntry.second; ClassData& descendant = descendantEntry.second;
ClassData& ancestor = this->at(ancestorKey); ClassData& ancestor = this->at(ancestorKey);
descendant.ancestors().emplace_back(ancestorKey, virtualEdge, directEdge); descendant.ancestors().emplace_back(ancestorKey, virtualEdge, directEdge);
ancestor.descendants(). emplace_back(descendantKey, virtualEdge, directEdge); ancestor.descendants().emplace_back(descendantKey, virtualEdge, directEdge);
} }
void void
ClassAnalysis::addInheritanceEdge(value_type& descendant, const InheritanceDesc& ancestor) ClassAnalysis::addInheritanceEdge(value_type& descendant, const InheritanceDesc& ancestor)
{ {
addInheritanceEdge(descendant, ancestor.getClass(), ancestor.isVirtual(), ance stor.isDirect()); addInheritanceEdge(descendant, ancestor.getClass(), ancestor.isVirtual(), ance stor.isDirect());
} }
bool bool
ClassAnalysis::areBaseDerived(ClassKeyType ancestorKey, ClassKeyType descendantK ey) const ClassAnalysis::areBaseDerived(ClassKeyType ancestorKey, ClassKeyType descendantK ey) const
skipping to change at line 253 skipping to change at line 253
while (aa != zz && !classes.at(aa->getClass()).hasVirtualFunctions()) while (aa != zz && !classes.at(aa->getClass()).hasVirtualFunctions())
++aa; ++aa;
return aa != zz; return aa != zz;
} }
void integrateIndirectInheritance(ClassAnalysis& classes, ClassAnalysis::value _type& entry) void integrateIndirectInheritance(ClassAnalysis& classes, ClassAnalysis::value _type& entry)
{ {
std::vector<InheritanceDesc> tmp; std::vector<InheritanceDesc> tmp;
// collect addition ancestors // collect additional ancestors
for (InheritanceDesc& parent : entry.second.ancestors()) for (InheritanceDesc& parent : entry.second.ancestors())
for (InheritanceDesc ancestor : classes.at(parent.getClass()).ancestors()) for (InheritanceDesc ancestor : classes.at(parent.getClass()).ancestors())
{ {
// skip virtual bases (they have already been propagated to derived) // skip virtual bases (they have already been propagated to derived)
if (ancestor.isVirtual()) continue; if (ancestor.isVirtual()) continue;
ancestor.setDirect(false); ancestor.setDirect(false);
tmp.push_back(ancestor); tmp.push_back(ancestor);
} }
skipping to change at line 334 skipping to change at line 334
// add additional ancestors // add additional ancestors
std::for_each( tmp.begin(), zz, std::for_each( tmp.begin(), zz,
[&classes, &entry](const InheritanceDesc& ancestor) -> void [&classes, &entry](const InheritanceDesc& ancestor) -> void
{ {
if (!ancestor.isDirect()) if (!ancestor.isDirect())
classes.addInheritanceEdge(entry, ancestor); classes.addInheritanceEdge(entry, ancestor);
} }
); );
} }
void computeVirtualBaseInitializationOrder(ClassAnalysis& classes, ClassAnalys
is::value_type& entry)
{
std::set<ClassKeyType> alreadySeen;
std::vector<ClassKeyType>& initorder = entry.second.virtualBaseClassOrder();
// traverse direct ancestors and collect their initialization orders
for (InheritanceDesc& parentDesc : entry.second.ancestors())
{
if (!parentDesc.isDirect()) continue;
ClassKeyType parent = parentDesc.getClass();
const std::vector<ClassKeyType>& parentInit = classes.at(parent).virtualBa
seClassOrder();
// add the virtual bases that had not been seen before
for (ClassKeyType vbase : parentInit)
if (alreadySeen.insert(vbase).second)
initorder.push_back(vbase);
if (parentDesc.isVirtual() && alreadySeen.insert(parent).second)
initorder.push_back(parent);
}
}
void analyzeClassRelationships(ClassAnalysis& all) void analyzeClassRelationships(ClassAnalysis& all)
{ {
logTrace() << all.size() << std::endl; logTrace() << all.size() << std::endl;
auto propagateVirtualInheritance = auto propagateVirtualInheritance =
[&all](ClassAnalysis::value_type& rep) -> void [&all](ClassAnalysis::value_type& rep) -> void
{ {
copyVirtualInhertanceToDerived(all, rep); copyVirtualInhertanceToDerived(all, rep);
}; };
topDownTraversal(all, propagateVirtualInheritance); topDownTraversal(all, propagateVirtualInheritance);
auto computeVirtualBaseClassInitializationOrder =
[&all](ClassAnalysis::value_type& rep) -> void
{
computeVirtualBaseInitializationOrder(all, rep);
};
topDownTraversal(all, computeVirtualBaseClassInitializationOrder);
auto flattenInheritance = auto flattenInheritance =
[&all](ClassAnalysis::value_type& rep) -> void [&all](ClassAnalysis::value_type& rep) -> void
{ {
integrateIndirectInheritance(all, rep); integrateIndirectInheritance(all, rep);
}; };
topDownTraversal(all, flattenInheritance); topDownTraversal(all, flattenInheritance);
auto analyzeInheritedVirtualMethod = auto analyzeInheritedVirtualMethod =
[&all](ClassAnalysis::value_type& rep) -> void [&all](ClassAnalysis::value_type& rep) -> void
{ {
skipping to change at line 378 skipping to change at line 408
classes.addInheritanceEdge(elem, parent, virt, true /* direct ancestor */); classes.addInheritanceEdge(elem, parent, virt, true /* direct ancestor */);
} }
); );
} }
} }
// returns true iff lhs < rhs // returns true iff lhs < rhs
struct VFNameTypeOrder struct VFNameTypeOrder
{ {
bool operator()(FunctionId lhs, FunctionId rhs) const bool operator()(FunctionKeyType lhs, FunctionKeyType rhs) const
{ {
static constexpr bool firstDecisiveComparison = false; static constexpr bool firstDecisiveComparison = false;
int res = 0; int res = 0;
firstDecisiveComparison firstDecisiveComparison
|| (res = rcb.compareNames(lhs, rhs)) || (res = rcb.compareNames(lhs, rhs))
|| (res = rcb.compareTypes(lhs, rhs)) || (res = rcb.compareTypes(lhs, rhs))
; ;
return res < 0; return res < 0;
} }
template <class TupleWithFunctionId> template <class TupleWithFunctionKeyType>
bool operator()(const TupleWithFunctionId& lhs, const TupleWithFunctionId& r bool operator()(const TupleWithFunctionKeyType& lhs, const TupleWithFunction
hs) const KeyType& rhs) const
{ {
return (*this)(std::get<0>(lhs), std::get<0>(rhs)); return (*this)(std::get<0>(lhs), std::get<0>(rhs));
} }
const RoseCompatibilityBridge& rcb; const RoseCompatibilityBridge& rcb;
}; };
/* /*
VirtualFunctionContainer VirtualFunctionContainer
extractVirtualFunctionsFromClass(const RoseCompatibilityBridge& rcb, ClassKeyT ype clkey) extractVirtualFunctionsFromClass(const RoseCompatibilityBridge& rcb, ClassKeyT ype clkey)
skipping to change at line 424 skipping to change at line 454
for (const std::tuple<FunctionId, bool>& func : funcs) for (const std::tuple<FunctionId, bool>& func : funcs)
res.emplace_back(func); res.emplace_back(func);
return res; return res;
} }
*/ */
} }
struct ComputeVFunctionRelation struct ComputeVFunctionRelation
{ {
void operator()(FunctionId drv, FunctionId bas) const void operator()(FunctionKeyType drv, FunctionKeyType bas) const
{ {
using ReturnTypeRelation = RoseCompatibilityBridge::ReturnTypeRelation; using ReturnTypeRelation = RoseCompatibilityBridge::ReturnTypeRelation;
const ReturnTypeRelation rel = rcb.haveSameOrCovariantReturn(classes, bas, d rv); const ReturnTypeRelation rel = rcb.haveSameOrCovariantReturn(classes, bas, d rv);
ROSE_ASSERT(rel != RoseCompatibilityBridge::unrelated); ROSE_ASSERT(rel != RoseCompatibilityBridge::unrelated);
if (rel == RoseCompatibilityBridge::unrelated) if (rel == RoseCompatibilityBridge::unrelated)
{ {
logError() << "oops, covariant return assertion failed: " logError() << "oops, covariant return assertion failed: "
<< rcb.nameOf(bas) << " <> " << rcb.nameOf(drv) << rcb.nameOf(bas) << " <> " << rcb.nameOf(drv)
<< std::endl; << std::endl;
return; return;
} }
const bool covariant = rel == RoseCompatibilityBridge::covaria nt; const bool covariant = rel == RoseCompatibilityBridge::covaria nt;
vfunAnalysis.at(drv).overridden().emplace_back(bas, covariant); vfunAnalysis.at(drv).overridden().emplace_back(bas, covariant);
vfunAnalysis.at(bas).overriders().emplace_back(drv, covariant); vfunAnalysis.at(bas).overriders().emplace_back(drv, covariant);
} }
void operator()(FunctionId, unavailable_t) const {} void operator()(FunctionKeyType, unavailable_t) const {}
void operator()(unavailable_t, FunctionId) const {} void operator()(unavailable_t, FunctionKeyType) const {}
// data members // data members
const RoseCompatibilityBridge& rcb; const RoseCompatibilityBridge& rcb;
const ClassAnalysis& classes; const ClassAnalysis& classes;
VirtualFunctionAnalysis& vfunAnalysis; VirtualFunctionAnalysis& vfunAnalysis;
ClassKeyType ancestor; ClassKeyType ancestor;
ClassKeyType descendant; ClassKeyType descendant;
}; };
using SortedVirtualMemberFunctions = std::unordered_map<ClassKeyType, ClassData: :VirtualFunctionContainer>; using SortedVirtualMemberFunctions = std::unordered_map<ClassKeyType, ClassData: :VirtualFunctionContainer>;
skipping to change at line 477 skipping to change at line 507
// create a new entry // create a new entry
VirtualFunctionContainer& vfunSorted = sortedVFunMap[entry.first]; VirtualFunctionContainer& vfunSorted = sortedVFunMap[entry.first];
ROSE_ASSERT(vfunSorted.empty()); ROSE_ASSERT(vfunSorted.empty());
vfunSorted = entry.second.virtualFunctions(); vfunSorted = entry.second.virtualFunctions();
std::sort(vfunSorted.begin(), vfunSorted.end(), VFNameTypeOrder{ rcb }); std::sort(vfunSorted.begin(), vfunSorted.end(), VFNameTypeOrder{ rcb });
std::for_each( vfunSorted.begin(), vfunSorted.end(), std::for_each( vfunSorted.begin(), vfunSorted.end(),
[&vfunAnalysis, &entry, &rcb](FunctionId id) -> void [&vfunAnalysis, &entry, &rcb](FunctionKeyType id) -> void
{ {
vfunAnalysis.emplace(id, VirtualFunctionDesc{entry.first, rcb .isPureVirtual(id)}); vfunAnalysis.emplace(id, VirtualFunctionDesc{entry.first, rcb .isPureVirtual(id)});
} }
); );
for (const InheritanceDesc& parentDesc : entry.second.ancestors()) for (const InheritanceDesc& parentDesc : entry.second.ancestors())
{ {
VirtualFunctionContainer& parentVFunSorted = sortedVFunMap.at(parentDesc.get Class()); VirtualFunctionContainer& parentVFunSorted = sortedVFunMap.at(parentDesc.get Class());
merge_keys( vfunSorted.begin(), vfunSorted.end(), merge_keys( vfunSorted.begin(), vfunSorted.end(),
parentVFunSorted.begin(), parentVFunSorted.end(), parentVFunSorted.begin(), parentVFunSorted.end(),
ComputeVFunctionRelation{rcb, classes, vfunAnalysis, entry.first , parentDesc.getClass()}, ComputeVFunctionRelation{rcb, classes, vfunAnalysis, entry.first , parentDesc.getClass()},
VFNameTypeOrder{rcb} VFNameTypeOrder{rcb}
); );
} }
} }
VirtualFunctionAnalysis VirtualFunctionAnalysis
virtualFunctionAnalysis(const RoseCompatibilityBridge& rcb, const ClassAnalysis& all) analyzeVirtualFunctions(const RoseCompatibilityBridge& rcb, const ClassAnalysis& all)
{ {
VirtualFunctionAnalysis res; VirtualFunctionAnalysis res;
SortedVirtualMemberFunctions tmpSorted; SortedVirtualMemberFunctions tmpSorted;
topDownTraversal( all, topDownTraversal( all,
[&rcb, &all, &res, &tmpSorted] [&rcb, &all, &res, &tmpSorted]
(const ClassAnalysis::value_type& clrep) -> void (const ClassAnalysis::value_type& clrep) -> void
{ {
computeOverriders(rcb, all, res, clrep, tmpSorted); computeOverriders(rcb, all, res, clrep, tmpSorted);
} }
); );
return res; return res;
} }
VirtualFunctionAnalysis
analyzeVirtualFunctions(const ClassAnalysis& all)
{
return analyzeVirtualFunctions(RoseCompatibilityBridge{}, all);
}
AnalysesTuple AnalysesTuple
analyzeClassesAndCasts(const RoseCompatibilityBridge& rcb, ASTRootType n) analyzeClassesAndCasts(const RoseCompatibilityBridge& rcb, ASTRootType n)
{ {
ClassAnalysis classes; ClassAnalysis classes;
CastAnalysis casts; CastAnalysis casts;
rcb.extractFromProject(classes, casts, n); rcb.extractFromProject(classes, casts, n);
inheritanceRelations(classes); inheritanceRelations(classes);
analyzeClassRelationships(classes); analyzeClassRelationships(classes);
return AnalysesTuple{std::move(classes), std::move(casts)}; return AnalysesTuple{std::move(classes), std::move(casts)};
} }
ClassAnalysis ClassAnalysis
analyzeClasses(const RoseCompatibilityBridge& rcb, ASTRootType n) analyzeClasses(const RoseCompatibilityBridge& rcb, ASTRootType n)
{ {
return std::move(analyzeClassesAndCasts(rcb, n).classAnalysis()); return std::move(analyzeClassesAndCasts(rcb, n).classAnalysis());
} }
ClassAnalysis
analyzeClasses(ASTRootType n)
{
return analyzeClasses(RoseCompatibilityBridge{}, n);
}
} }
 End of changes. 14 change blocks. 
12 lines changed or deleted 56 lines changed or added

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