Introduce locals to be read from a parcel ahead of time

so that error handling no longer crosses variable declarations.

Bug: 30570468
Change-Id: I365fec3cc33a8fdcd03a84bcbe05848ba290c475
diff --git a/AST.h b/AST.h
index da8f655..83c5d6d 100644
--- a/AST.h
+++ b/AST.h
@@ -97,6 +97,9 @@
     status_t generateStubSourceForMethod(
             Formatter &out, const Interface *iface, const Method *method) const;
 
+    void declareCppReaderLocals(
+            Formatter &out, const std::vector<TypedVar *> &arg) const;
+
     void emitCppReaderWriter(
             Formatter &out,
             const std::string &parcelObj,
diff --git a/Interface.cpp b/Interface.cpp
index 42186af..2c65865 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -62,6 +62,9 @@
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
     if (isReader) {
+        out << "{\n";
+        out.indent();
+
         const std::string binderName = "_hidl_" + name + "_binder";
 
         out << "::android::sp<::android::hardware::IBinder> "
@@ -81,6 +84,9 @@
             << "::asInterface("
             << binderName
             << ");\n";
+
+        out.unindent();
+        out << "}\n\n";
     } else {
         out << "_hidl_err = ";
         out << parcelObjDeref
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 1fc98bf..0985fb2 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -531,6 +531,26 @@
     return mRootScope->emitTypeDefinitions(out, ifaceName);
 }
 
+void AST::declareCppReaderLocals(
+        Formatter &out, const std::vector<TypedVar *> &args) const {
+    if (args.empty()) {
+        return;
+    }
+
+    for (const auto &arg : args) {
+        const Type &type = arg->type();
+
+        std::string extra;
+        out << type.getCppResultType(&extra)
+            << " "
+            << arg->name()
+            << extra
+            << ";\n";
+    }
+
+    out << "\n";
+}
+
 void AST::emitCppReaderWriter(
         Formatter &out,
         const std::string &parcelObj,
@@ -540,15 +560,6 @@
         Type::ErrorMode mode) const {
     const Type &type = arg->type();
 
-    if (isReader) {
-        std::string extra;
-        out << type.getCppResultType(&extra)
-            << " "
-            << arg->name()
-            << extra
-            << ";\n";
-    }
-
     type.emitReaderWriter(
             out,
             arg->name(),
@@ -614,8 +625,10 @@
 
             out << "::android::hardware::Parcel _hidl_data;\n";
             out << "::android::hardware::Parcel _hidl_reply;\n";
-            out << "::android::status_t _hidl_err;\n\n";
-            out << "::android::hardware::Status _hidl_status;\n";
+            out << "::android::status_t _hidl_err;\n";
+            out << "::android::hardware::Status _hidl_status;\n\n";
+
+            declareCppReaderLocals(out, method->results());
 
             out << "_hidl_err = _hidl_data.writeInterfaceToken("
                 << superInterface->fullName()
@@ -821,6 +834,8 @@
     out.unindent();
     out << "}\n\n";
 
+    declareCppReaderLocals(out, method->args());
+
     for (const auto &arg : method->args()) {
         emitCppReaderWriter(
                 out,