Adding AidlCast to replace downcasting methods

This change only replaces ones in AidlMember for now but AidlCast can
replace downcasting methods in AidlDefinedType as well.

Bug: n/a
Test: aidl_unittests
Change-Id: Ib51f994622f87d6442cf1491b02c71c1a305d627
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 3b30ee6..a0cad71 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -978,14 +978,14 @@
   }
   if (members) {
     for (auto& m : *members) {
-      if (auto constant = m->AsConstantDeclaration(); constant) {
+      if (auto constant = AidlCast<AidlConstantDeclaration>(*m); constant) {
         constants_.emplace_back(constant);
-      } else if (auto variable = m->AsVariableDeclaration(); variable) {
+      } else if (auto variable = AidlCast<AidlVariableDeclaration>(*m); variable) {
         variables_.emplace_back(variable);
-      } else if (auto method = m->AsMethod(); method) {
+      } else if (auto method = AidlCast<AidlMethod>(*m); method) {
         methods_.emplace_back(method);
       } else {
-        AIDL_FATAL(*m);
+        AIDL_FATAL(*m) << "Unknown member type.";
       }
       members_.push_back(m.release());
     }
@@ -1086,14 +1086,18 @@
   return GetEnclosingScope()->ResolveName(name);
 }
 
-template <typename T>
-const T* AidlCast(const AidlNode& node) {
-  struct CastVisitor : AidlVisitor {
-    const T* cast = nullptr;
-    void Visit(const T& t) override { cast = &t; }
-  } visitor;
-  node.DispatchVisit(visitor);
-  return visitor.cast;
+template <>
+const AidlDefinedType* AidlCast<AidlDefinedType>(const AidlNode& node) {
+  struct Visitor : AidlVisitor {
+    const AidlDefinedType* defined_type = nullptr;
+    void Visit(const AidlInterface& t) override { defined_type = &t; }
+    void Visit(const AidlEnumDeclaration& t) override { defined_type = &t; }
+    void Visit(const AidlStructuredParcelable& t) override { defined_type = &t; }
+    void Visit(const AidlUnionDecl& t) override { defined_type = &t; }
+    void Visit(const AidlParcelable& t) override { defined_type = &t; }
+  } v;
+  node.DispatchVisit(v);
+  return v.defined_type;
 }
 
 const AidlDocument& AidlDefinedType::GetDocument() const {