diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 20 | ||||
-rw-r--r-- | clang/lib/AST/ODRHash.cpp | 30 |
2 files changed, 50 insertions, 0 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index ee15a4d2b4f..629037b1755 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -26,6 +26,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Stmt.h" @@ -3604,6 +3605,25 @@ unsigned FunctionDecl::getMemoryFunctionKind() const { return 0; } +unsigned FunctionDecl::getODRHash() { + if (HasODRHash) + return ODRHash; + + if (FunctionDecl *Definition = getDefinition()) { + if (Definition != this) { + HasODRHash = true; + ODRHash = Definition->getODRHash(); + return ODRHash; + } + } + + class ODRHash Hash; + Hash.AddFunctionDecl(this); + HasODRHash = true; + ODRHash = Hash.CalculateHash(); + return ODRHash; +} + //===----------------------------------------------------------------------===// // FieldDecl Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 0f07b6225d9..b6874e7ba42 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -466,6 +466,36 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) { } } +void ODRHash::AddFunctionDecl(const FunctionDecl *Function) { + assert(Function && "Expecting non-null pointer."); + + // Skip hashing these kinds of function. + if (Function->isImplicit()) return; + if (Function->isDefaulted()) return; + if (Function->isDeleted()) return; + if (!Function->hasBody()) return; + if (!Function->getBody()) return; + + // Skip functions that are specializations or in specialization context. + const DeclContext *DC = Function; + while (DC) { + if (isa<ClassTemplateSpecializationDecl>(DC)) return; + if (auto *F = dyn_cast<FunctionDecl>(DC)) + if (F->isFunctionTemplateSpecialization()) return; + DC = DC->getParent(); + } + + AddDecl(Function); + + AddQualType(Function->getReturnType()); + + ID.AddInteger(Function->param_size()); + for (auto Param : Function->parameters()) + AddSubDecl(Param); + + AddStmt(Function->getBody()); +} + void ODRHash::AddDecl(const Decl *D) { assert(D && "Expecting non-null pointer."); D = D->getCanonicalDecl(); |