[ODRHash] Handle some template weirdness.

Build the index off of DeclarationName instead of Decl pointers.  When finding
an UnresolvedLookupExprClass, hash it as if it were a DeclRefExpr.  This will
allow methods to be hashed.

llvm-svn: 325741
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 38e8d34..4104d34 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -33,6 +33,15 @@
 }
 
 void ODRHash::AddDeclarationName(DeclarationName Name) {
+  // Index all DeclarationName and use index numbers to refer to them.
+  auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));
+  ID.AddInteger(Result.first->second);
+  if (!Result.second) {
+    // If found in map, the the DeclarationName has previously been processed.
+    return;
+  }
+
+  // First time processing each DeclarationName, also process its details.
   AddBoolean(Name.isEmpty());
   if (Name.isEmpty())
     return;
@@ -168,7 +177,7 @@
 }
 
 void ODRHash::clear() {
-  DeclMap.clear();
+  DeclNameMap.clear();
   TypeMap.clear();
   Bools.clear();
   ID.clear();
@@ -418,7 +427,6 @@
 
 void ODRHash::AddSubDecl(const Decl *D) {
   assert(D && "Expecting non-null pointer.");
-  AddDecl(D);
 
   ODRDeclVisitor(ID, *this).Visit(D);
 }
@@ -476,9 +484,7 @@
   if (!Function->hasBody()) return;
   if (!Function->getBody()) return;
 
-  // TODO: Fix hashing for class methods.
-  if (isa<CXXMethodDecl>(Function)) return;
-  // And friend functions.
+  // TODO: Fix hashing friend functions.
   if (Function->getFriendObjectKind()) return;
 
   // Skip functions that are specializations or in specialization context.
@@ -504,19 +510,14 @@
 void ODRHash::AddDecl(const Decl *D) {
   assert(D && "Expecting non-null pointer.");
   D = D->getCanonicalDecl();
-  auto Result = DeclMap.insert(std::make_pair(D, DeclMap.size()));
-  ID.AddInteger(Result.first->second);
-  // On first encounter of a Decl pointer, process it.  Every time afterwards,
-  // only the index value is needed.
-  if (!Result.second) {
+
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    AddDeclarationName(ND->getDeclName());
     return;
   }
 
   ID.AddInteger(D->getKind());
-
-  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    AddDeclarationName(ND->getDeclName());
-  }
+  // TODO: Handle non-NamedDecl here.
 }
 
 namespace {