Make recursive methods in Type work with cyclic AST
Fixes Type::canCheckEquality, Type::needsResolveReferences,
Type::isJavaCompatible, Type:containsPointer.
Adds set of visited Types to these functions to prevent
infinite recursion.
deep versions of these functions *do not* guarantee the correct
return value, but non-deep versions do:
We need to find al least one path from requested vertex
to "bad" vertex (ie. which is not java compatible).
Fixes a bug with containsPointer (containsPointer returned true
if inner type contained a pointer), so more structures get
__attribute__ aligned and static_assert generated for
struct fields.
This change is required for forward reference, as current
implementations assume that the graph is acyclic.
Potential future work: to reduce theoretical complexity of
described actions (square to linear).
Bug: 31827278
Test: mma
Test: output not changed in
out/soong/.intermediates/hardware/interfaces
Change-Id: I3dbdd1605f9317637241057b12de6031125abf7b
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 0254a6c..d70bc78 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -91,12 +91,12 @@
return true;
}
-bool CompoundType::canCheckEquality() const {
+bool CompoundType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
if (mStyle == STYLE_UNION) {
return false;
}
- for (const auto &field : *mFields) {
- if (!field->type().canCheckEquality()) {
+ for (const auto* field : *mFields) {
+ if (!field->get()->canCheckEquality(visited)) {
return false;
}
}
@@ -988,18 +988,18 @@
return false;
}
-bool CompoundType::needsResolveReferences() const {
+bool CompoundType::deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const {
if (mStyle != STYLE_STRUCT) {
return false;
}
for (const auto &field : *mFields) {
- if (field->type().needsResolveReferences()) {
+ if (field->type().needsResolveReferences(visited)) {
return true;
}
}
- return false;
+ return Scope::deepNeedsResolveReferences(visited);
}
bool CompoundType::resultNeedsDeref() const {
@@ -1066,32 +1066,28 @@
return OK;
}
-bool CompoundType::isJavaCompatible() const {
- if (mStyle != STYLE_STRUCT || !Scope::isJavaCompatible()) {
+bool CompoundType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
+ if (mStyle != STYLE_STRUCT) {
return false;
}
- for (const auto &field : *mFields) {
- if (!field->type().isJavaCompatible()) {
+ for (const auto* field : *mFields) {
+ if (!field->get()->isJavaCompatible(visited)) {
return false;
}
}
- return true;
+ return Scope::deepIsJavaCompatible(visited);
}
-bool CompoundType::containsPointer() const {
- if (Scope::containsPointer()) {
- return true;
- }
-
- for (const auto &field : *mFields) {
- if (field->type().containsPointer()) {
+bool CompoundType::deepContainsPointer(std::unordered_set<const Type*>* visited) const {
+ for (const auto* field : *mFields) {
+ if (field->get()->containsPointer(visited)) {
return true;
}
}
- return false;
+ return Scope::deepContainsPointer(visited);
}
void CompoundType::getAlignmentAndSize(size_t *align, size_t *size) const {