Add parent to every type

Parent is needed for lookups:
scope = isScope() ? this : parent()
for ref : getReferences() {
    AST->lookup...(ref, scope)
}

Bug: 31827278
Test: mma
Change-Id: I1bde29de43d224634d80949d719adc8de9cc8896
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 1e2693d..6c65db1 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -23,14 +23,13 @@
 
 namespace android {
 
-ArrayType::ArrayType(ArrayType *srcArray, ConstantExpression *size)
-    : mElementType(srcArray->mElementType),
-      mSizes(srcArray->mSizes) {
+ArrayType::ArrayType(ArrayType* srcArray, ConstantExpression* size, Scope* parent)
+    : Type(parent), mElementType(srcArray->mElementType), mSizes(srcArray->mSizes) {
     prependDimension(size);
 }
 
-ArrayType::ArrayType(const Reference<Type>& elementType, ConstantExpression* size)
-    : mElementType(elementType) {
+ArrayType::ArrayType(const Reference<Type>& elementType, ConstantExpression* size, Scope* parent)
+    : Type(parent), mElementType(elementType) {
     CHECK(!elementType.isEmptyReference());
     prependDimension(size);
 }
diff --git a/ArrayType.h b/ArrayType.h
index 45f46e0..d0498c3 100644
--- a/ArrayType.h
+++ b/ArrayType.h
@@ -29,9 +29,9 @@
 
 struct ArrayType : public Type {
     // Extends existing array by adding another dimension.
-    ArrayType(ArrayType *srcArray, ConstantExpression *size);
+    ArrayType(ArrayType* srcArray, ConstantExpression* size, Scope* parent);
 
-    ArrayType(const Reference<Type>& elementType, ConstantExpression* size);
+    ArrayType(const Reference<Type>& elementType, ConstantExpression* size, Scope* parent);
 
     bool isArray() const override;
     bool canCheckEquality() const override;
diff --git a/ConstantExpression.cpp b/ConstantExpression.cpp
index 4de9f0d..84b434f 100644
--- a/ConstantExpression.cpp
+++ b/ConstantExpression.cpp
@@ -59,7 +59,7 @@
 
 static inline bool isSupported(ScalarType::Kind kind) {
     // TODO(b/64358435) move isSupported to EnumValue
-    return SK(BOOL) == kind || ScalarType(kind).isValidEnumStorageType();
+    return SK(BOOL) == kind || ScalarType(kind, nullptr /* parent */).isValidEnumStorageType();
 }
 
 /* See docs at the end for details on integral promotion. */
@@ -386,9 +386,10 @@
     // -(uint64_t)9223372036854775808 == 9223372036854775808 could not
     // be narrowed to int64_t.
     if(castKind == SK(INT64) && (int64_t)mValue == INT64_MIN) {
-        return strdup(("static_cast<"
-            + ScalarType(SK(INT64)).getCppStackType() // "int64_t"
-            + ">(" + literal + "ull)").c_str());
+        return strdup(("static_cast<" +
+                       ScalarType(SK(INT64), nullptr /* parent */).getCppStackType()  // "int64_t"
+                       + ">(" + literal + "ull)")
+                          .c_str());
     }
 
     // add suffix if necessary.
diff --git a/DeathRecipientType.cpp b/DeathRecipientType.cpp
index 828f217..c057bf5 100644
--- a/DeathRecipientType.cpp
+++ b/DeathRecipientType.cpp
@@ -21,7 +21,7 @@
 
 namespace android {
 
-DeathRecipientType::DeathRecipientType() {}
+DeathRecipientType::DeathRecipientType(Scope* parent) : Type(parent) {}
 
 std::string DeathRecipientType::typeName() const {
     return "death recipient";
diff --git a/DeathRecipientType.h b/DeathRecipientType.h
index 386cec5..b36de9b 100644
--- a/DeathRecipientType.h
+++ b/DeathRecipientType.h
@@ -23,7 +23,7 @@
 namespace android {
 
 struct DeathRecipientType : public Type {
-    DeathRecipientType();
+    DeathRecipientType(Scope* parent);
 
     std::string getCppType(
             StorageMode mode,
diff --git a/EnumType.cpp b/EnumType.cpp
index 7363712..58f5407 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -29,7 +29,7 @@
 EnumType::EnumType(const char* localName, const Location& location,
                    const Reference<Type>& storageType, Scope* parent)
     : Scope(localName, location, parent), mValues(), mStorageType(storageType) {
-    BitFieldType* bitfieldType = new BitFieldType();
+    BitFieldType* bitfieldType = new BitFieldType(parent);
     bitfieldType->setElementType(Reference<Type>(this, Location()));
     mBitfieldType.set(bitfieldType);
 }
@@ -169,6 +169,8 @@
     return "TYPE_ENUM";
 }
 
+BitFieldType::BitFieldType(Scope* parent) : TemplatedType(parent) {}
+
 BitFieldType* EnumType::getBitfieldType() const {
     return mBitfieldType.get();
 }
diff --git a/EnumType.h b/EnumType.h
index cc1e6c1..fbcab93 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -157,6 +157,7 @@
 };
 
 struct BitFieldType : public TemplatedType {
+    BitFieldType(Scope* parent);
 
     std::string typeName() const override;
 
diff --git a/FmqType.cpp b/FmqType.cpp
index ec32bd0..8b5f77d 100644
--- a/FmqType.cpp
+++ b/FmqType.cpp
@@ -23,9 +23,8 @@
 
 namespace android {
 
-FmqType::FmqType(const char *nsp, const char *name)
-    : mNamespace(nsp), mName(name) {
-}
+FmqType::FmqType(const char* nsp, const char* name, Scope* parent)
+    : TemplatedType(parent), mNamespace(nsp), mName(name) {}
 
 std::string FmqType::typeName() const {
     return mName + " of " + mElementType->typeName();
diff --git a/FmqType.h b/FmqType.h
index ef2b216..27bb1ac 100644
--- a/FmqType.h
+++ b/FmqType.h
@@ -23,7 +23,7 @@
 namespace android {
 
 struct FmqType : public TemplatedType {
-    FmqType(const char *nsp, const char *name);
+    FmqType(const char* nsp, const char* name, Scope* parent);
 
     std::string fullName() const;
 
diff --git a/HandleType.cpp b/HandleType.cpp
index 0e198f6..bff7595 100644
--- a/HandleType.cpp
+++ b/HandleType.cpp
@@ -23,7 +23,7 @@
 
 namespace android {
 
-HandleType::HandleType() {}
+HandleType::HandleType(Scope* parent) : Type(parent) {}
 
 bool HandleType::isHandle() const {
     return true;
diff --git a/HandleType.h b/HandleType.h
index ad1f681..af48215 100644
--- a/HandleType.h
+++ b/HandleType.h
@@ -23,7 +23,7 @@
 namespace android {
 
 struct HandleType : public Type {
-    HandleType();
+    HandleType(Scope* parent);
 
     bool isHandle() const override;
 
diff --git a/MemoryType.cpp b/MemoryType.cpp
index 251691e..712cd55 100644
--- a/MemoryType.cpp
+++ b/MemoryType.cpp
@@ -23,7 +23,7 @@
 
 namespace android {
 
-MemoryType::MemoryType() {}
+MemoryType::MemoryType(Scope* parent) : Type(parent) {}
 
 std::string MemoryType::getCppType(StorageMode mode,
                                    bool specifyNamespaces) const {
diff --git a/MemoryType.h b/MemoryType.h
index cd7329a..bc46b98 100644
--- a/MemoryType.h
+++ b/MemoryType.h
@@ -23,7 +23,7 @@
 namespace android {
 
 struct MemoryType : public Type {
-    MemoryType();
+    MemoryType(Scope* parent);
 
     std::string typeName() const override;
 
diff --git a/NamedType.cpp b/NamedType.cpp
index f6d876f..c0c8450 100644
--- a/NamedType.cpp
+++ b/NamedType.cpp
@@ -19,7 +19,7 @@
 namespace android {
 
 NamedType::NamedType(const char* localName, const Location& loc, Scope* parent)
-    : mLocalName(localName), mLocation(loc), mParent(parent) {}
+    : Type(parent), mLocalName(localName), mLocation(loc) {}
 
 bool NamedType::isNamedType() const {
     return true;
@@ -53,10 +53,6 @@
     return mLocation;
 }
 
-Scope* NamedType::parent() const {
-    return mParent;
-}
-
 void NamedType::emitDump(
         Formatter &out,
         const std::string &streamName,
diff --git a/NamedType.h b/NamedType.h
index f655a28..f666ba1 100644
--- a/NamedType.h
+++ b/NamedType.h
@@ -27,8 +27,6 @@
 
 namespace android {
 
-struct Scope;
-
 struct NamedType : public Type {
     NamedType(const char* localName, const Location& loc, Scope* parent);
 
@@ -54,13 +52,10 @@
             const std::string &streamName,
             const std::string &name) const override;
 
-    Scope* parent() const;
-
    private:
     const std::string mLocalName;
     FQName mFullName;
     const Location mLocation;
-    Scope* const mParent;
 
     DISALLOW_COPY_AND_ASSIGN(NamedType);
 };
diff --git a/PointerType.cpp b/PointerType.cpp
index 8684e4e..dca3fdd 100644
--- a/PointerType.cpp
+++ b/PointerType.cpp
@@ -21,7 +21,7 @@
 
 namespace android {
 
-PointerType::PointerType() {}
+PointerType::PointerType(Scope* parent) : Type(parent) {}
 
 bool PointerType::isPointer() const {
     return true;
diff --git a/PointerType.h b/PointerType.h
index 4fb6a2f..c941bf7 100644
--- a/PointerType.h
+++ b/PointerType.h
@@ -23,7 +23,7 @@
 namespace android {
 
 struct PointerType : public Type {
-    PointerType();
+    PointerType(Scope* parent);
 
     bool isPointer() const override;
 
diff --git a/RefType.cpp b/RefType.cpp
index 3783438..cba02b2 100644
--- a/RefType.cpp
+++ b/RefType.cpp
@@ -24,8 +24,7 @@
 
 namespace android {
 
-RefType::RefType() {
-}
+RefType::RefType(Scope* parent) : TemplatedType(parent) {}
 
 std::string RefType::typeName() const {
     return "ref of " + mElementType->typeName();
diff --git a/RefType.h b/RefType.h
index 6445207..58ed4cf 100644
--- a/RefType.h
+++ b/RefType.h
@@ -26,7 +26,7 @@
 namespace android {
 
 struct RefType : public TemplatedType {
-    RefType();
+    RefType(Scope* parent);
 
     std::string typeName() const override;
     bool isCompatibleElementType(Type *elementType) const override;
diff --git a/ScalarType.cpp b/ScalarType.cpp
index fefd418..fb2abfb 100644
--- a/ScalarType.cpp
+++ b/ScalarType.cpp
@@ -20,9 +20,7 @@
 
 namespace android {
 
-ScalarType::ScalarType(Kind kind)
-    : mKind(kind) {
-}
+ScalarType::ScalarType(Kind kind, Scope* parent) : Type(parent), mKind(kind) {}
 
 const ScalarType *ScalarType::resolveToScalarType() const {
     return this;
diff --git a/ScalarType.h b/ScalarType.h
index 737da9a..d919929 100644
--- a/ScalarType.h
+++ b/ScalarType.h
@@ -37,7 +37,7 @@
         KIND_DOUBLE,
     };
 
-    ScalarType(Kind kind);
+    ScalarType(Kind kind, Scope* parent);
 
     bool isScalar() const override;
 
diff --git a/StringType.cpp b/StringType.cpp
index 7a60277..840bd23 100644
--- a/StringType.cpp
+++ b/StringType.cpp
@@ -22,7 +22,7 @@
 
 namespace android {
 
-StringType::StringType() {}
+StringType::StringType(Scope* parent) : Type(parent) {}
 
 bool StringType::isString() const {
     return true;
diff --git a/StringType.h b/StringType.h
index 36299f7..209aed2 100644
--- a/StringType.h
+++ b/StringType.h
@@ -23,7 +23,7 @@
 namespace android {
 
 struct StringType : public Type {
-    StringType();
+    StringType(Scope* parent);
 
     bool isString() const override;
 
diff --git a/Type.cpp b/Type.cpp
index 1fb19bc..ecaca13 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -19,6 +19,7 @@
 #include "ConstantExpression.h"
 #include "NamedType.h"
 #include "ScalarType.h"
+#include "Scope.h"
 
 #include <android-base/logging.h>
 #include <hidl-util/Formatter.h>
@@ -26,7 +27,7 @@
 
 namespace android {
 
-Type::Type() {}
+Type::Type(Scope* parent) : mParent(parent) {}
 
 Type::~Type() {}
 
@@ -280,6 +281,10 @@
     mIsPostParseCompleted = true;
 }
 
+Scope* Type::parent() {
+    return mParent;
+}
+
 std::string Type::getCppType(StorageMode, bool) const {
     CHECK(!"Should not be here");
     return std::string();
@@ -625,7 +630,7 @@
 
 ////////////////////////////////////////
 
-TemplatedType::TemplatedType() {}
+TemplatedType::TemplatedType(Scope* parent) : Type(parent) {}
 
 void TemplatedType::setElementType(const Reference<Type>& elementType) {
     // can only be set once.
diff --git a/Type.h b/Type.h
index 1338ffb..57a77cf 100644
--- a/Type.h
+++ b/Type.h
@@ -33,9 +33,10 @@
 struct Formatter;
 struct FQName;
 struct ScalarType;
+struct Scope;
 
 struct Type {
-    Type();
+    Type(Scope* parent);
     virtual ~Type();
 
     virtual bool isArray() const;
@@ -118,6 +119,8 @@
     // Post parse passes must be proceeded during owner package parsing
     void setPostParseCompleted();
 
+    Scope* parent();
+
     enum StorageMode {
         StorageMode_Stack,
         StorageMode_Argument,
@@ -303,6 +306,7 @@
 
    private:
     bool mIsPostParseCompleted = false;
+    Scope* const mParent;
 
     DISALLOW_COPY_AND_ASSIGN(Type);
 };
@@ -324,7 +328,7 @@
     status_t emitVtsAttributeType(Formatter& out) const override;
 
    protected:
-    TemplatedType();
+    TemplatedType(Scope* parent);
     Reference<Type> mElementType;
 
    private:
diff --git a/VectorType.cpp b/VectorType.cpp
index 071e406..e279daf 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -25,8 +25,7 @@
 
 namespace android {
 
-VectorType::VectorType() {
-}
+VectorType::VectorType(Scope* parent) : TemplatedType(parent) {}
 
 std::string VectorType::typeName() const {
     return "vector of " + mElementType->typeName();
diff --git a/VectorType.h b/VectorType.h
index efd8798..edb5e1c 100644
--- a/VectorType.h
+++ b/VectorType.h
@@ -26,7 +26,7 @@
 namespace android {
 
 struct VectorType : public TemplatedType {
-    VectorType();
+    VectorType(Scope* parent);
 
     bool isVector() const override;
     bool isVectorOfBinders() const;
diff --git a/hidl-gen_l.ll b/hidl-gen_l.ll
index 13b69bf..6dee499 100644
--- a/hidl-gen_l.ll
+++ b/hidl-gen_l.ll
@@ -41,6 +41,7 @@
 #include "Method.h"
 #include "PointerType.h"
 #include "ScalarType.h"
+#include "Scope.h"
 #include "StringType.h"
 #include "VectorType.h"
 #include "RefType.h"
@@ -53,11 +54,14 @@
 using namespace android;
 using token = yy::parser::token;
 
-#define SCALAR_TYPE(kind)                                       \
-    do {                                                        \
-        yylval->type = new ScalarType(ScalarType::kind);        \
-        return token::TYPE;                                   \
-    } while (0)
+#define SCALAR_TYPE(kind)                                        \
+    {                                                            \
+        yylval->type = new ScalarType(ScalarType::kind, *scope); \
+        return token::TYPE;                                      \
+    }
+
+#define YY_DECL int yylex(YYSTYPE* yylval_param, YYLTYPE* yylloc_param,  \
+    yyscan_t yyscanner, android::Scope** const scope)
 
 #define YY_USER_ACTION yylloc->step(); yylloc->columns(yyleng);
 
@@ -95,9 +99,9 @@
 "struct"		{ return token::STRUCT; }
 "typedef"		{ return token::TYPEDEF; }
 "union"			{ return token::UNION; }
-"bitfield"		{ yylval->templatedType = new BitFieldType; return token::TEMPLATED; }
-"vec"			{ yylval->templatedType = new VectorType; return token::TEMPLATED; }
-"ref"			{ yylval->templatedType = new RefType; return token::TEMPLATED; }
+"bitfield"		{ yylval->templatedType = new BitFieldType(*scope); return token::TEMPLATED; }
+"vec"			{ yylval->templatedType = new VectorType(*scope); return token::TEMPLATED; }
+"ref"			{ yylval->templatedType = new RefType(*scope); return token::TEMPLATED; }
 "oneway"		{ return token::ONEWAY; }
 
 "bool"			{ SCALAR_TYPE(KIND_BOOL); }
@@ -112,14 +116,14 @@
 "float"			{ SCALAR_TYPE(KIND_FLOAT); }
 "double"		{ SCALAR_TYPE(KIND_DOUBLE); }
 
-"death_recipient"	{ yylval->type = new DeathRecipientType; return token::TYPE; }
-"handle"		{ yylval->type = new HandleType; return token::TYPE; }
-"memory"		{ yylval->type = new MemoryType; return token::TYPE; }
-"pointer"		{ yylval->type = new PointerType; return token::TYPE; }
-"string"		{ yylval->type = new StringType; return token::TYPE; }
+"death_recipient"	{ yylval->type = new DeathRecipientType(*scope); return token::TYPE; }
+"handle"		{ yylval->type = new HandleType(*scope); return token::TYPE; }
+"memory"		{ yylval->type = new MemoryType(*scope); return token::TYPE; }
+"pointer"		{ yylval->type = new PointerType(*scope); return token::TYPE; }
+"string"		{ yylval->type = new StringType(*scope); return token::TYPE; }
 
-"fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync"); return token::TEMPLATED; }
-"fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync"); return token::TEMPLATED; }
+"fmq_sync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorSync", *scope); return token::TEMPLATED; }
+"fmq_unsync" { yylval->type = new FmqType("::android::hardware", "MQDescriptorUnsync", *scope); return token::TEMPLATED; }
 
 "("			{ return('('); }
 ")"			{ return(')'); }
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 61372e2..da98df1 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -39,7 +39,7 @@
 
 using namespace android;
 
-extern int yylex(yy::parser::semantic_type*, yy::parser::location_type*, void*);
+extern int yylex(yy::parser::semantic_type*, yy::parser::location_type*, void*, Scope** const);
 
 void enterScope(AST* /* ast */, Scope** scope, Scope* container) {
     CHECK(container->parent() == (*scope));
@@ -206,6 +206,7 @@
 %parse-param { android::AST* const ast }
 %parse-param { android::Scope** const scope }
 %lex-param { void* scanner }
+%lex-param { android::Scope** const scope }
 %pure-parser
 %glr-parser
 %skeleton "glr.cc"
@@ -1033,9 +1034,9 @@
           Reference<Type> type = *$1;
 
           if (type.isResolved() && type->isArray()) {
-              $$ = new ArrayType(static_cast<ArrayType*>(type.get()), $3);
+              $$ = new ArrayType(static_cast<ArrayType*>(type.get()), $3, *scope);
           } else {
-              $$ = new ArrayType(type, $3);
+              $$ = new ArrayType(type, $3, *scope);
           }
       }
     | array_type '[' const_expr ']'