r325741 - [ODRHash] Handle some template weirdness.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 21 21:32:25 PST 2018


Author: rtrieu
Date: Wed Feb 21 21:32:25 2018
New Revision: 325741

URL: http://llvm.org/viewvc/llvm-project?rev=325741&view=rev
Log:
[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.

Modified:
    cfe/trunk/include/clang/AST/ODRHash.h
    cfe/trunk/lib/AST/ODRHash.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp

Modified: cfe/trunk/include/clang/AST/ODRHash.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ODRHash.h?rev=325741&r1=325740&r2=325741&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ODRHash.h (original)
+++ cfe/trunk/include/clang/AST/ODRHash.h Wed Feb 21 21:32:25 2018
@@ -37,8 +37,9 @@ class TemplateParameterList;
 // Typically, only one Add* call is needed.  clear can be called to reuse the
 // object.
 class ODRHash {
-  // Use DenseMaps to convert between Decl and Type pointers and an index value.
-  llvm::DenseMap<const Decl*, unsigned> DeclMap;
+  // Use DenseMaps to convert from DeclarationName and Type pointers
+  // to an index value.
+  llvm::DenseMap<DeclarationName, unsigned> DeclNameMap;
   llvm::DenseMap<const Type*, unsigned> TypeMap;
 
   // Save space by processing bools at the end.

Modified: cfe/trunk/lib/AST/ODRHash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=325741&r1=325740&r2=325741&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ODRHash.cpp (original)
+++ cfe/trunk/lib/AST/ODRHash.cpp Wed Feb 21 21:32:25 2018
@@ -33,6 +33,15 @@ void ODRHash::AddIdentifierInfo(const Id
 }
 
 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::AddTemplateParameterList(c
 }
 
 void ODRHash::clear() {
-  DeclMap.clear();
+  DeclNameMap.clear();
   TypeMap.clear();
   Bools.clear();
   ID.clear();
@@ -418,7 +427,6 @@ bool ODRHash::isWhitelistedDecl(const De
 
 void ODRHash::AddSubDecl(const Decl *D) {
   assert(D && "Expecting non-null pointer.");
-  AddDecl(D);
 
   ODRDeclVisitor(ID, *this).Visit(D);
 }
@@ -476,9 +484,7 @@ void ODRHash::AddFunctionDecl(const Func
   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::AddFunctionDecl(const Func
 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) {
-    return;
-  }
-
-  ID.AddInteger(D->getKind());
 
   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
     AddDeclarationName(ND->getDeclName());
+    return;
   }
+
+  ID.AddInteger(D->getKind());
+  // TODO: Handle non-NamedDecl here.
 }
 
 namespace {

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=325741&r1=325740&r2=325741&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Wed Feb 21 21:32:25 2018
@@ -38,6 +38,8 @@ namespace {
 
     void VisitStmt(const Stmt *S);
 
+    virtual void HandleStmtClass(Stmt::StmtClass SC) = 0;
+
 #define STMT(Node, Base) void Visit##Node(const Node *S);
 #include "clang/AST/StmtNodes.inc"
 
@@ -50,7 +52,7 @@ namespace {
     virtual void VisitType(QualType T) = 0;
 
     /// \brief Visit a name that occurs within an expression or statement.
-    virtual void VisitName(DeclarationName Name) = 0;
+    virtual void VisitName(DeclarationName Name, bool TreatAsDecl = false) = 0;
 
     /// \brief Visit identifiers that are not in Decl's or Type's.
     virtual void VisitIdentifierInfo(IdentifierInfo *II) = 0;
@@ -80,6 +82,10 @@ namespace {
                              const ASTContext &Context, bool Canonical)
         : StmtProfiler(ID, Canonical), Context(Context) {}
   private:
+    void HandleStmtClass(Stmt::StmtClass SC) override {
+      ID.AddInteger(SC);
+    }
+
     void VisitDecl(const Decl *D) override {
       ID.AddInteger(D ? D->getKind() : 0);
 
@@ -134,7 +140,7 @@ namespace {
       ID.AddPointer(T.getAsOpaquePtr());
     }
 
-    void VisitName(DeclarationName Name) override {
+    void VisitName(DeclarationName Name, bool /*TreatAsDecl*/) override {
       ID.AddPointer(Name.getAsOpaquePtr());
     }
 
@@ -163,11 +169,26 @@ namespace {
         : StmtProfiler(ID, false), Hash(Hash) {}
 
   private:
+    void HandleStmtClass(Stmt::StmtClass SC) override {
+      if (SC == Stmt::UnresolvedLookupExprClass) {
+        // Pretend that the name looked up is a Decl due to how templates
+        // handle some Decl lookups.
+        ID.AddInteger(Stmt::DeclRefExprClass);
+      } else {
+        ID.AddInteger(SC);
+      }
+    }
+
     void VisitType(QualType T) override {
       Hash.AddQualType(T);
     }
 
-    void VisitName(DeclarationName Name) override {
+    void VisitName(DeclarationName Name, bool TreatAsDecl) override {
+      if (TreatAsDecl) {
+        // A Decl can be null, so each Decl is preceded by a boolean to
+        // store its nullness.  Add a boolean here to match.
+        ID.AddBoolean(true);
+      }
       Hash.AddDeclarationName(Name);
     }
     void VisitIdentifierInfo(IdentifierInfo *II) override {
@@ -196,7 +217,9 @@ namespace {
 
 void StmtProfiler::VisitStmt(const Stmt *S) {
   assert(S && "Requires non-null Stmt pointer");
-  ID.AddInteger(S->getStmtClass());
+
+  HandleStmtClass(S->getStmtClass());
+
   for (const Stmt *SubStmt : S->children()) {
     if (SubStmt)
       Visit(SubStmt);
@@ -1662,7 +1685,7 @@ StmtProfiler::VisitCXXPseudoDestructorEx
 void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
   VisitExpr(S);
   VisitNestedNameSpecifier(S->getQualifier());
-  VisitName(S->getName());
+  VisitName(S->getName(), /*TreatAsDecl*/ true);
   ID.AddBoolean(S->hasExplicitTemplateArgs());
   if (S->hasExplicitTemplateArgs())
     VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());




More information about the cfe-commits mailing list