Pointer support and embedded types in HIDL.

* Pointers work per transaction. Don't work
  across transactions.
* ref<T> in HIDL translates to T const* in C++.
* No Java support.
* Embedded types like ref<vec<vec<int32_t>>>
  or vec<ref<T>> is supported. Pointers to
  pointers like ref<ref<ref<T>>> is supported.
* Array of pointers and pointer to array supported.
* Pointer inside a union is NOT supported.

Test: `mma`
Test: `make hidl_test && adb sync && adb shell hidl_test`
      Note that this only works with a kernel patch.

Bug: 31300815
Bug: 31349114

Change-Id: I15b74ca74a801009cc8bdc7132bd53d0185dbcbf
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 9968635..3b9320a 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -894,6 +894,27 @@
             mode);
 }
 
+void AST::emitCppResolveReferences(
+        Formatter &out,
+        const std::string &parcelObj,
+        bool parcelObjIsPointer,
+        const TypedVar *arg,
+        bool isReader,
+        Type::ErrorMode mode,
+        bool addPrefixToName) const {
+    const Type &type = arg->type();
+    if(type.needsResolveReferences()) {
+        type.emitResolveReferences(
+                out,
+                addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
+                isReader, // nameIsPointer
+                parcelObj,
+                parcelObjIsPointer,
+                isReader,
+                mode);
+    }
+}
+
 status_t AST::generateProxySource(
         Formatter &out, const std::string &baseName) const {
     const std::string klassName = "Bp" + baseName;
@@ -954,6 +975,7 @@
 
             out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
 
+            // First DFS: write all buffers and resolve pointers for parent
             for (const auto &arg : method->args()) {
                 emitCppReaderWriter(
                         out,
@@ -965,6 +987,18 @@
                         false /* addPrefixToName */);
             }
 
+            // Second DFS: resolve references.
+            for (const auto &arg : method->args()) {
+                emitCppResolveReferences(
+                        out,
+                        "_hidl_data",
+                        false /* parcelObjIsPointer */,
+                        arg,
+                        false /* reader */,
+                        Type::ErrorMode_Goto,
+                        false /* addPrefixToName */);
+            }
+
             out << "_hidl_err = remote()->transact("
                       << superInterface->fqName().cppNamespace()
                       << "::IHw"
@@ -984,6 +1018,8 @@
                 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
                 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
 
+
+                // First DFS: write all buffers and resolve pointers for parent
                 for (const auto &arg : method->results()) {
                     emitCppReaderWriter(
                             out,
@@ -995,6 +1031,18 @@
                             true /* addPrefixToName */);
                 }
 
+                // Second DFS: resolve references.
+                for (const auto &arg : method->results()) {
+                    emitCppResolveReferences(
+                            out,
+                            "_hidl_reply",
+                            false /* parcelObjIsPointer */,
+                            arg,
+                            true /* reader */,
+                            Type::ErrorMode_Goto,
+                            true /* addPrefixToName */);
+                }
+
                 if (returnsValue && elidedReturn == nullptr) {
                     out << "if (_hidl_cb != nullptr) {\n";
                     out.indent();
@@ -1204,6 +1252,7 @@
 
     declareCppReaderLocals(out, method->args(), false /* forResults */);
 
+    // First DFS: write buffers
     for (const auto &arg : method->args()) {
         emitCppReaderWriter(
                 out,
@@ -1215,6 +1264,18 @@
                 false /* addPrefixToName */);
     }
 
+    // Second DFS: resolve references
+    for (const auto &arg : method->args()) {
+        emitCppResolveReferences(
+                out,
+                "_hidl_data",
+                false /* parcelObjIsPointer */,
+                arg,
+                true /* reader */,
+                Type::ErrorMode_Break,
+                false /* addPrefixToName */);
+    }
+
     out << "if (UNLIKELY(enableInstrumentation)) {\n";
     out.indent();
     out << "std::vector<void *> args;\n";
@@ -1273,6 +1334,15 @@
                 false, /* isReader */
                 Type::ErrorMode_Ignore);
 
+        emitCppResolveReferences(
+                out,
+                "_hidl_reply",
+                true /* parcelObjIsPointer */,
+                elidedReturn,
+                false /* reader */,
+                Type::ErrorMode_Ignore,
+                false /* addPrefixToName */);
+
         out << "if (UNLIKELY(enableInstrumentation)) {\n";
         out.indent();
         out << "std::vector<void *> results;\n";
@@ -1338,6 +1408,7 @@
             out << "::android::hardware::Status::ok()"
                       << ".writeToParcel(_hidl_reply);\n\n";
 
+            // First DFS: buffers
             for (const auto &arg : method->results()) {
                 emitCppReaderWriter(
                         out,
@@ -1349,6 +1420,18 @@
                         false /* addPrefixToName */);
             }
 
+            // Second DFS: resolve references
+            for (const auto &arg : method->results()) {
+                emitCppResolveReferences(
+                        out,
+                        "_hidl_reply",
+                        true /* parcelObjIsPointer */,
+                        arg,
+                        false /* reader */,
+                        Type::ErrorMode_Ignore,
+                        false /* addPrefixToName */);
+            }
+
             out << "if (UNLIKELY(enableInstrumentation)) {\n";
             out.indent();
             out << "std::vector<void *> results;\n";