Revert "Revert "Add Reference type""

This reverts commit 6f2f2c026b0b6e372194794e171208a91d74f852.

Reason for revert: mac build problem could be easily fixed

Mac build failure was caused by not declaring template specialization
in header file. Unfortunately, it cannot be easily declared there,
as that would cause cyclic declaration.

The reason why Reference<T>(Reference<O>) constructor could get only
unresolved references is because there is no way to check that the
requested conversion is valid (without specialization or rtti).

However, the appeared messy solution is to be deleted with moving
lookup calls outside of the parser.

Test: builds, hidl_test
Test: builds on mac

Change-Id: Icb24e2ad52563f659e758a186d90e414ab7f1c59
diff --git a/Interface.cpp b/Interface.cpp
index 1adf92d..805d81c 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -68,8 +68,10 @@
 };
 
 Interface::Interface(const char* localName, const Location& location, Scope* parent,
-                     Interface* super)
-    : Scope(localName, location, parent), mSuperType(super), mIsJavaCompatibleInProgress(false) {}
+                     const Reference<Interface>& superType)
+    : Scope(localName, location, parent),
+      mSuperType(superType),
+      mIsJavaCompatibleInProgress(false) {}
 
 std::string Interface::typeName() const {
     return "interface " + localName();
@@ -461,7 +463,7 @@
 
     serial += userDefinedMethods().size();
 
-    const Interface *ancestor = mSuperType;
+    const Interface* ancestor = superType();
     while (ancestor != nullptr) {
         serial += ancestor->userDefinedMethods().size();
         ancestor = ancestor->superType();
@@ -510,8 +512,8 @@
     return true;
 }
 
-const Interface *Interface::superType() const {
-    return mSuperType;
+const Interface* Interface::superType() const {
+    return isIBase() ? nullptr : mSuperType;
 }
 
 std::vector<const Interface *> Interface::typeChain() const {
@@ -519,13 +521,13 @@
     const Interface *iface = this;
     while (iface != nullptr) {
         v.push_back(iface);
-        iface = iface->mSuperType;
+        iface = iface->superType();
     }
     return v;
 }
 
 std::vector<const Interface *> Interface::superTypeChain() const {
-    return superType()->typeChain(); // should work even if superType is nullptr
+    return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
 }
 
 bool Interface::isElidableType() const {
@@ -890,7 +892,7 @@
         return true;
     }
 
-    if (mSuperType != nullptr && !mSuperType->isJavaCompatible()) {
+    if (superType() != nullptr && !superType()->isJavaCompatible()) {
         mIsJavaCompatibleInProgress = false;
         return false;
     }