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/Interface.cpp b/Interface.cpp
index 0fcd081..2e0d931 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -71,9 +71,7 @@
Interface::Interface(const char* localName, const FQName& fullName, const Location& location,
Scope* parent, const Reference<Type>& superType)
- : Scope(localName, fullName, location, parent),
- mSuperType(superType),
- mIsJavaCompatibleInProgress(false) {}
+ : Scope(localName, fullName, location, parent), mSuperType(superType) {}
std::string Interface::typeName() const {
return "interface " + localName();
@@ -970,38 +968,18 @@
return false;
}
-bool Interface::isJavaCompatible() const {
- if (mIsJavaCompatibleInProgress) {
- // We're currently trying to determine if this Interface is
- // java-compatible and something is referencing this interface through
- // one of its methods. Assume we'll ultimately succeed, if we were wrong
- // the original invocation of Interface::isJavaCompatible() will then
- // return the correct "false" result.
- return true;
- }
-
- if (superType() != nullptr && !superType()->isJavaCompatible()) {
- mIsJavaCompatibleInProgress = false;
+bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
+ if (superType() != nullptr && !superType()->isJavaCompatible(visited)) {
return false;
}
- mIsJavaCompatibleInProgress = true;
-
- if (!Scope::isJavaCompatible()) {
- mIsJavaCompatibleInProgress = false;
- return false;
- }
-
- for (const auto &method : methods()) {
- if (!method->isJavaCompatible()) {
- mIsJavaCompatibleInProgress = false;
+ for (const auto* method : methods()) {
+ if (!method->deepIsJavaCompatible(visited)) {
return false;
}
}
- mIsJavaCompatibleInProgress = false;
-
- return true;
+ return Scope::isJavaCompatible(visited);
}
} // namespace android