C++/NDK backends reorder nested type decls.
In the following example, C is declared before B.
parcelabe A {
parcelabe B {
C c;
}
parcelable C {}
}
Otherwise, C++ compiler will complain about undefined symbols.
Still we can't define nested types with cyclic references because decl
order is not determined for C++/NDK backends.
Bug: 201376182
Test: golden_test.sh check
Test: aidl_unittests
Change-Id: I8340dc33e3f745aa51dca038af0ad55893c3aa05
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index a7f13f9..78739b4 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -1753,6 +1753,84 @@
EXPECT_EQ("p/IFoo.h", cpp::CppHeaderForType(*result));
}
+TEST_F(AidlTest, ReorderNestedTypesForCppOutput) {
+ const string input_path = "p/IFoo.aidl";
+ const string input = R"(
+ package p;
+ interface IFoo {
+ // partial orderings for [A, D, G]:
+ // D - A
+ // A - G
+ parcelable A {
+ // partial orderings for [B, C]:
+ // C - B
+ parcelable B {
+ C c;
+ D.E d;
+ }
+ parcelable C {}
+ }
+ parcelable D {
+ // partial orderings for [E, F]:
+ // F - E
+ parcelable E {
+ F f;
+ }
+ parcelable F {}
+ }
+ parcelable G {
+ A.B b;
+ }
+ }
+ )";
+ Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
+ io_delegate_.SetFileContents(input_path, input);
+ CaptureStderr();
+ EXPECT_TRUE(compile_aidl(options, io_delegate_));
+ EXPECT_EQ(GetCapturedStderr(), "");
+
+ string code;
+ EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/IFoo.h", &code));
+ // check partial orderings: a should comes before b
+ EXPECT_LE(code.find("class D"), code.find("class A"));
+ EXPECT_LE(code.find("class A"), code.find("class G"));
+ EXPECT_LE(code.find("class C"), code.find("class B"));
+ EXPECT_LE(code.find("class F"), code.find("class E"));
+}
+
+TEST_F(AidlTest, RejectsNestedTypesWithCyclicDeps) {
+ const string input_path = "p/IFoo.aidl";
+ const string input = R"(
+ package p;
+ interface IFoo {
+ // Cycles:
+ // D - A
+ // A - G
+ // G - D
+ parcelable A {
+ parcelable B {
+ C c;
+ }
+ }
+ parcelable C {
+ parcelable D {
+ E e;
+ }
+ }
+ parcelable E {
+ parcelable F {
+ A a;
+ }
+ }
+ }
+ )";
+ Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
+ io_delegate_.SetFileContents(input_path, input);
+ CaptureStderr();
+ EXPECT_FALSE(compile_aidl(options, io_delegate_));
+ EXPECT_THAT(GetCapturedStderr(), HasSubstr("IFoo has nested types with cyclic references."));
+}
+
TEST_F(AidlTest, CppNameOf_GenericType) {
const string input_path = "p/Wrapper.aidl";
const string input = "package p; parcelable Wrapper<T> {}";