Support for inheritance of interfaces.
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 889ac86..3f35c38 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -184,7 +184,18 @@
     if (isInterface) {
         out << "struct "
             << ifaceName
-            << " : public ::android::hidl::IInterface {\n";
+            << " : public ";
+
+        const Interface *iface = mRootScope->getInterface();
+        const Interface *superType = iface->superType();
+
+        if (superType != NULL) {
+            out << superType->fullName();
+        } else {
+            out << "::android::hidl::IInterface";
+        }
+
+        out << " {\n";
 
         out.indent();
 
@@ -202,6 +213,7 @@
 
     if (isInterface) {
         const Interface *iface = mRootScope->getInterface();
+        const Interface *superType = iface->superType();
 
         out << "enum Call {\n";
         out.indent();
@@ -211,13 +223,22 @@
             out << upcase(method->name());
 
             if (first) {
-                out << " = ::android::hidl::IBinder::FIRST_CALL_TRANSACTION";
+                out << " = ";
+                if (superType != NULL) {
+                    out << superType->fullName()
+                        << "::Call::CallCount";
+                } else {
+                    out << "::android::hidl::IBinder::FIRST_CALL_TRANSACTION";
+                }
+
                 first = false;
             }
 
             out << ",\n";
         }
 
+        out << "CallCount\n";
+
         out.unindent();
         out << "};\n\n";
 
@@ -421,23 +442,39 @@
 
     const Interface *iface = mRootScope->getInterface();
 
-    for (const auto &method : iface->methods()) {
-        const bool returnsValue = !method->results().empty();
+    std::vector<const Interface *> chain;
+    while (iface != NULL) {
+        chain.push_back(iface);
+        iface = iface->superType();
+    }
 
-        out << "::android::hidl::binder::Status "
-            << method->name()
-            << "("
-            << Method::GetSignature(method->args());
+    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
+        const Interface *superInterface = *it;
 
-        if (returnsValue) {
-            if (!method->args().empty()) {
-                out << ", ";
+        out << "// Methods from "
+            << superInterface->fullName()
+            << " follow.\n";
+
+        for (const auto &method : superInterface->methods()) {
+            const bool returnsValue = !method->results().empty();
+
+            out << "::android::hidl::binder::Status "
+                << method->name()
+                << "("
+                << Method::GetSignature(method->args());
+
+            if (returnsValue) {
+                if (!method->args().empty()) {
+                    out << ", ";
+                }
+
+                out << method->name() << "_cb _aidl_cb";
             }
 
-            out << method->name() << "_cb _aidl_cb";
+            out << ") override;\n";
         }
 
-        out << ") override;\n";
+        out << "\n";
     }
 
     out.unindent();
@@ -579,103 +616,114 @@
 
     const Interface *iface = mRootScope->getInterface();
 
-    for (const auto &method : iface->methods()) {
-        const bool returnsValue = !method->results().empty();
+    std::vector<const Interface *> chain;
+    while (iface != NULL) {
+        chain.push_back(iface);
+        iface = iface->superType();
+    }
 
-        out << "::android::hidl::binder::Status "
-            << klassName
-            << "::"
-            << method->name()
-            << "("
-            << Method::GetSignature(method->args());
+    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
+        const Interface *superInterface = *it;
 
-        if (returnsValue) {
-            if (!method->args().empty()) {
-                out << ", ";
-            }
+        for (const auto &method : superInterface->methods()) {
+            const bool returnsValue = !method->results().empty();
 
-            out << method->name() << "_cb _aidl_cb";
-        }
+            out << "::android::hidl::binder::Status "
+                << klassName
+                << "::"
+                << method->name()
+                << "("
+                << Method::GetSignature(method->args());
 
-        out << ") {\n";
-
-        out.indent();
-
-        out << "::android::hidl::Parcel _aidl_data;\n";
-        out << "::android::hidl::Parcel _aidl_reply;\n";
-        out << "::android::status_t _aidl_err;\n\n";
-        out << "::android::hidl::binder::Status _aidl_status;\n";
-
-        out << "_aidl_err = _aidl_data.writeInterfaceToken("
-               "getInterfaceDescriptor());\n";
-
-        out << "if (_aidl_err != ::android::OK) { goto _aidl_error; }\n\n";
-
-        for (const auto &arg : method->args()) {
-            emitCppReaderWriter(
-                    out,
-                    "_aidl_data",
-                    false /* parcelObjIsPointer */,
-                    arg,
-                    false /* reader */,
-                    Type::ErrorMode_Goto);
-        }
-
-        out << "_aidl_err = remote()->transact(I"
-                  << baseName
-                  << "::"
-                  << upcase(method->name())
-                  << ", _aidl_data, &_aidl_reply);\n";
-
-        out << "if (_aidl_err != ::android::OK) { goto _aidl_error; }\n\n";
-
-        out << "_aidl_err = _aidl_status.readFromParcel(_aidl_reply);\n";
-        out << "if (_aidl_err != ::android::OK) { goto _aidl_error; }\n\n";
-
-        out << "if (!_aidl_status.isOk()) { return _aidl_status; }\n\n";
-
-        for (const auto &arg : method->results()) {
-            emitCppReaderWriter(
-                    out,
-                    "_aidl_reply",
-                    false /* parcelObjIsPointer */,
-                    arg,
-                    true /* reader */,
-                    Type::ErrorMode_Goto);
-        }
-
-        if (returnsValue) {
-            out << "if (_aidl_cb != nullptr) {\n";
-            out.indent();
-            out << "_aidl_cb(";
-
-            bool first = true;
-            for (const auto &arg : method->results()) {
-                if (!first) {
+            if (returnsValue) {
+                if (!method->args().empty()) {
                     out << ", ";
                 }
 
-                if (arg->type().resultNeedsDeref()) {
-                    out << "*";
-                }
-                out << arg->name();
-
-                first = false;
+                out << method->name() << "_cb _aidl_cb";
             }
 
-            out << ");\n";
+            out << ") {\n";
+
+            out.indent();
+
+            out << "::android::hidl::Parcel _aidl_data;\n";
+            out << "::android::hidl::Parcel _aidl_reply;\n";
+            out << "::android::status_t _aidl_err;\n\n";
+            out << "::android::hidl::binder::Status _aidl_status;\n";
+
+            out << "_aidl_err = _aidl_data.writeInterfaceToken("
+                << superInterface->fullName()
+                << "::getInterfaceDescriptor());\n";
+
+            out << "if (_aidl_err != ::android::OK) { goto _aidl_error; }\n\n";
+
+            for (const auto &arg : method->args()) {
+                emitCppReaderWriter(
+                        out,
+                        "_aidl_data",
+                        false /* parcelObjIsPointer */,
+                        arg,
+                        false /* reader */,
+                        Type::ErrorMode_Goto);
+            }
+
+            out << "_aidl_err = remote()->transact(I"
+                      << baseName
+                      << "::"
+                      << upcase(method->name())
+                      << ", _aidl_data, &_aidl_reply);\n";
+
+            out << "if (_aidl_err != ::android::OK) { goto _aidl_error; }\n\n";
+
+            out << "_aidl_err = _aidl_status.readFromParcel(_aidl_reply);\n";
+            out << "if (_aidl_err != ::android::OK) { goto _aidl_error; }\n\n";
+
+            out << "if (!_aidl_status.isOk()) { return _aidl_status; }\n\n";
+
+            for (const auto &arg : method->results()) {
+                emitCppReaderWriter(
+                        out,
+                        "_aidl_reply",
+                        false /* parcelObjIsPointer */,
+                        arg,
+                        true /* reader */,
+                        Type::ErrorMode_Goto);
+            }
+
+            if (returnsValue) {
+                out << "if (_aidl_cb != nullptr) {\n";
+                out.indent();
+                out << "_aidl_cb(";
+
+                bool first = true;
+                for (const auto &arg : method->results()) {
+                    if (!first) {
+                        out << ", ";
+                    }
+
+                    if (arg->type().resultNeedsDeref()) {
+                        out << "*";
+                    }
+                    out << arg->name();
+
+                    first = false;
+                }
+
+                out << ");\n";
+                out.unindent();
+                out << "}\n\n";
+            }
+
+            out.unindent();
+            out << "_aidl_error:\n";
+            out.indent();
+            out << "_aidl_status.setFromStatusT(_aidl_err);\n"
+                      << "return _aidl_status;\n";
+
             out.unindent();
             out << "}\n\n";
         }
-
-        out.unindent();
-        out << "_aidl_error:\n";
-        out.indent();
-        out << "_aidl_status.setFromStatusT(_aidl_err);\n"
-                  << "return _aidl_status;\n";
-
-        out.unindent();
-        out << "}\n\n";
     }
 
     return OK;
@@ -713,18 +761,34 @@
 
     const Interface *iface = mRootScope->getInterface();
 
-    for (const auto &method : iface->methods()) {
-        out << "case Call::" << upcase(method->name()) << ":\n{\n";
-        out.indent();
+    std::vector<const Interface *> chain;
+    while (iface != NULL) {
+        chain.push_back(iface);
+        iface = iface->superType();
+    }
 
-        status_t err = generateStubSourceForMethod(out, method);
+    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
+        const Interface *superInterface = *it;
 
-        if (err != OK) {
-            return err;
+        for (const auto &method : superInterface->methods()) {
+            out << "case "
+                << superInterface->fullName()
+                << "::Call::"
+                << upcase(method->name())
+                << ":\n{\n";
+
+            out.indent();
+
+            status_t err =
+                generateStubSourceForMethod(out, superInterface, method);
+
+            if (err != OK) {
+                return err;
+            }
+
+            out.unindent();
+            out << "}\n\n";
         }
-
-        out.unindent();
-        out << "}\n\n";
     }
 
     out << "default:\n{\n";
@@ -775,8 +839,11 @@
 }
 
 status_t AST::generateStubSourceForMethod(
-        Formatter &out, const Method *method) const {
-    out << "if (!_aidl_data.checkInterface(this)) {\n";
+        Formatter &out, const Interface *iface, const Method *method) const {
+    out << "if (!_aidl_data.enforceInterface("
+        << iface->fullName()
+        << "::getInterfaceDescriptor())) {\n";
+
     out.indent();
     out << "_aidl_err = ::android::BAD_TYPE;\n";
     out << "break;\n";