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()); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits