Skip to content

Commit

Permalink
Adjust attribute filters to not apply to tagged type analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
KennethLamar committed May 23, 2024
1 parent 52aaf6e commit a1e2990
Showing 1 changed file with 95 additions and 30 deletions.
125 changes: 95 additions & 30 deletions include/traverse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ static T GetScope(AType n) {

template <typename C>
std::vector<C> GetRecords(SgNode* n) {
LOG(DEBUG) << "Finding additional records for " << NPrint::p(n) << std::endl;
std::vector<C> owningClassIds;
// Tagged records approach.
// Functions/procedures that are tied to a tagged record will list the tagged
Expand All @@ -266,6 +267,8 @@ std::vector<C> GetRecords(SgNode* n) {
}
}
}
LOG(DEBUG) << "Found " << owningClassIds.size() << " additional records for "
<< NPrint::p(n) << std::endl;
return owningClassIds;
}

Expand All @@ -282,6 +285,7 @@ void GetClassIdsHelper(SgNode* n, std::vector<C>& owningClassIds,
template <typename C>
void GetClassIdsHelper(SgNode* n, std::vector<C>& owningClassIds,
std::false_type) {
LOG(DEBUG) << "No additional records to add." << std::endl;
// Do nothing.
return;
}
Expand Down Expand Up @@ -316,24 +320,13 @@ std::vector<C> GetClassIds(SgNode* n) {
bool IsClassOwner(SgExpression* id, const MType& mId) {
const std::vector<SgClassDeclaration*> owningClassIds =
GetRecords<SgClassDeclaration*>(mId);
// Peter: use sageinterface ada type of expression instead of get_type
// Peter: Could cast type to a SgClassType or SgNamedType, which will have a
// good get_declaration method.
SgDeclarationStatement* declPeter =
is<SgClassType>(SageInterface::Ada::typeOfExpr(id).typerep())
->get_declaration();
SgDeclarationStatement* decl = id->get_type()->getAssociatedDeclaration();
LOG(TRACE) << "declPeter=" << declPeter << "\tdecl=" << decl << "\t"
<< (decl == declPeter) << std::endl;

if (SgClassDeclaration* classRefId = is<SgClassDeclaration>(decl)) {
for (const auto& classId : owningClassIds) {
// Peter: Try pointer for first nondefining declaration instead of
// getname.
if (classId->get_firstNondefiningDeclaration() ==
classRefId->get_firstNondefiningDeclaration()) {
LOG(TRACE) << "Found a match for " << NPrint::p(classRefId)
<< std::endl;
LOG(TRACE) << "Match found for " << NPrint::p(classRefId) << std::endl;
return true;
}
}
Expand Down Expand Up @@ -420,6 +413,26 @@ class Class : public Component<C> {
os << NPrint::p(c.id);
return os;
}
// Filter attributes for non-tagged type classes.
void FilterAttributes(Method<C>* method, std::false_type) {
if (!method) return;
auto& attributes = method->attributes;
for (auto j = attributes.begin(); j != attributes.end();) {
const auto& attribute = std::get<1>(*j);
// Remove foreign attributes.
if (attribute->owningClass.GetId() != this->GetId()) {
LOG(DEBUG) << "Removing " << attribute << " from " << *this
<< " because " << NPrint::p(attribute->owningClass.GetId())
<< " != " << NPrint::p(this->GetId()) << std::endl;
j = attributes.erase(j);
} else {
++j;
}
}
}
// Tagged types. Do nothing, for now.
void FilterAttributes(Method<C>* method, std::true_type) { return; }

// Filter out class data we don't want in the final analysis.
void Filter() {
LOG(DEBUG) << "Filtering out foreign data for class " << *this << std::endl;
Expand All @@ -439,20 +452,11 @@ class Class : public Component<C> {
++i;
}

auto& attributes = method->attributes;
for (auto j = attributes.begin(); j != attributes.end();) {
const auto& attribute = std::get<1>(*j);
// TODO: This is a hack. The right way to do this is to recognize that an
// attribute could be associated with multiple classes and track them all.
// For now, we will keep it disabled for tagged types analysis.
FilterAttributes(method, std::is_same<C, SgClassDeclaration*>());

// Remove foreign attributes.
if (attribute->owningClass.GetId() != this->GetId()) {
LOG(DEBUG) << "Removing " << attribute << " from " << *this
<< " because " << NPrint::p(attribute->owningClass.GetId())
<< " != " << NPrint::p(this->GetId()) << std::endl;
j = attributes.erase(j);
} else {
++j;
}
}
auto& calledMethods = method->calledMethods;
for (auto j = calledMethods.begin(); j != calledMethods.end();) {
const auto& cmId = std::get<0>(*j);
Expand Down Expand Up @@ -722,6 +726,7 @@ T GetBaseRootExp(SgExpression* id) {

template <typename C>
Class<C>* GetOwningClass(SgNode* n) {
LOG(TRACE) << "Getting Owning Class for " << NPrint::p(n) << std::endl;
const std::vector<C> owningClassIds = GetClassIds<C>(n);

// TODO: Not a safe assumption, but we will see how much damage this causes.
Expand Down Expand Up @@ -869,20 +874,74 @@ class VisitorTraversal : public AstTopDownProcessing<IA<C>> {
return IA<C>(ia);
}

// TODO: Actually use this to store additional classes associated with an
// attribute.
static bool HandleSgVarRefExpTaggedTypeHelper(Class<C>& owningClass,
AType aDecl, std::true_type) {
LOG(TRACE) << "Attempting to find all inherited classes associated with "
<< owningClass << "." << std::endl;
// Associate the attribute with all classes in the tagged type hierarchy.
if (SgClassDeclaration* classDeclId =
is<SgClassDeclaration>(owningClass.GetId())) {
SgClassDefinition* classDefId = classDeclId->get_definition();
if (!classDefId) {
LOG(WARNING) << "classDefId for " << NPrint::p(classDeclId)
<< " was NULL. Ignoring." << std::endl;
return false;
}
const std::vector<SgBaseClass*> inheritanceList =
classDefId->get_inheritances();
for (const auto& inherit : inheritanceList) {
SgClassDeclaration* baseClassDecl = inherit->get_base_class();
// NOTE: Currently ignoring discriminated types. We can deal with it
// later.
if (baseClassDecl) {
Class<C>& baseClass = IA<C>::classData.at(baseClassDecl);
bool success =
IA<C>::attributeData
.emplace(aDecl, std::move(Attribute<C>(aDecl, baseClass)))
.second;
if (!success) {
LOG(WARNING) << "Failed to emplace." << std::endl;
}
}
}
}
return true;
}

static bool HandleSgVarRefExpTaggedTypeHelper(Class<C>& owningClass,
AType aDecl, std::false_type) {
return true;
}

// For tagged types.
static Class<C>* HandleSgVarRefExpGetClass(SgVarRefExp* baseRootExp,
Method<C>& owningMethod,
std::true_type) {
return &owningMethod.owningClass;
}
// For everything else.
static Class<C>* HandleSgVarRefExpGetClass(SgVarRefExp* baseRootExp,
Method<C>& owningMethod,
std::false_type) {
return GetOwningClass<C>(baseRootExp);
}

static IA<C> HandleSgVarRefExp(SgExpression* id, IA<C> ia) {
// Get the root expression. This resolves renamings, fields, and pointers.
std::vector<SgExpression*> root = GetRootExp(id);
SgVarRefExp* baseRootExp = is<SgVarRefExp>(GetBaseRootExp(root));

Class<C>* cPtr = GetOwningClass<C>(baseRootExp);
if (!cPtr) return IA<C>(ia);
Class<C>& owningClass = *cPtr;

Method<C>* mPtr = GetOwningMethod<C>(baseRootExp);
if (!mPtr) return IA<C>(ia);
Method<C>& owningMethod = *mPtr;

// Class<C>& owningClass = owningMethod.owningClass;
// Class<C>* cPtr = GetOwningClass<C>(baseRootExp);
Class<C>* cPtr = HandleSgVarRefExpGetClass(
baseRootExp, owningMethod, std::is_same<C, SgClassDeclaration*>());
if (!cPtr) return IA<C>(ia);
Class<C>& owningClass = *cPtr;

std::vector<AType::T> decl = AType::ToAttrList(root);

Expand Down Expand Up @@ -916,6 +975,8 @@ class VisitorTraversal : public AstTopDownProcessing<IA<C>> {
}
// Build up a vector of all records leading to this specific field in
// a record.
// TODO: Figure out why tagged types repeat the same attribute ID twice
// in the list.
do {
SgExpression* rhs = parent->get_rhs_operand();
std::vector<SgExpression*> exps = GetRootExp(rhs);
Expand All @@ -942,6 +1003,10 @@ class VisitorTraversal : public AstTopDownProcessing<IA<C>> {
"by HandleSgAdaRenamingDecl(). This is not a problem."
<< std::endl;

// HandleSgVarRefExpTaggedTypeHelper(owningClass, aDecl,
// std::is_same<C,
// SgClassDeclaration*>());

// Associate it with the calling method.
success =
owningMethod.attributes.emplace(aDecl, &IA<C>::attributeData.at(aDecl))
Expand Down

0 comments on commit a1e2990

Please sign in to comment.