diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/AST/ODRHash.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/AST/ODRHash.cpp | 103 |
1 files changed, 102 insertions, 1 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp b/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp index 121724a7315..38e8d34135f 100644 --- a/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp +++ b/gnu/llvm/tools/clang/lib/AST/ODRHash.cpp @@ -158,7 +158,14 @@ void ODRHash::AddTemplateArgument(TemplateArgument TA) { } } -void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {} +void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) { + assert(TPL && "Expecting non-null pointer."); + + ID.AddInteger(TPL->size()); + for (auto *ND : TPL->asArray()) { + AddSubDecl(ND); + } +} void ODRHash::clear() { DeclMap.clear(); @@ -199,6 +206,7 @@ unsigned ODRHash::CalculateHash() { return ID.ComputeHash(); } +namespace { // Process a Decl pointer. Add* methods call back into ODRHash while Visit* // methods process the relevant parts of the Decl. class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> { @@ -235,6 +243,10 @@ public: } } + void AddTemplateArgument(TemplateArgument TA) { + Hash.AddTemplateArgument(TA); + } + void Visit(const Decl *D) { ID.AddInteger(D->getKind()); Inherited::Visit(D); @@ -342,7 +354,44 @@ public: AddDecl(D->getFriendDecl()); } } + + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { + // Only care about default arguments as part of the definition. + const bool hasDefaultArgument = + D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); + Hash.AddBoolean(hasDefaultArgument); + if (hasDefaultArgument) { + AddTemplateArgument(D->getDefaultArgument()); + } + + Inherited::VisitTemplateTypeParmDecl(D); + } + + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { + // Only care about default arguments as part of the definition. + const bool hasDefaultArgument = + D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); + Hash.AddBoolean(hasDefaultArgument); + if (hasDefaultArgument) { + AddStmt(D->getDefaultArgument()); + } + + Inherited::VisitNonTypeTemplateParmDecl(D); + } + + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) { + // Only care about default arguments as part of the definition. + const bool hasDefaultArgument = + D->hasDefaultArgument() && !D->defaultArgumentWasInherited(); + Hash.AddBoolean(hasDefaultArgument); + if (hasDefaultArgument) { + AddTemplateArgument(D->getDefaultArgument().getArgument()); + } + + Inherited::VisitTemplateTemplateParmDecl(D); + } }; +} // namespace // Only allow a small portion of Decl's to be processed. Remove this once // all Decl's can be handled. @@ -401,10 +450,60 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) { for (auto SubDecl : Decls) { AddSubDecl(SubDecl); } + + const ClassTemplateDecl *TD = Record->getDescribedClassTemplate(); + AddBoolean(TD); + if (TD) { + AddTemplateParameterList(TD->getTemplateParameters()); + } + + ID.AddInteger(Record->getNumBases()); + auto Bases = Record->bases(); + for (auto Base : Bases) { + AddQualType(Base.getType()); + ID.AddInteger(Base.isVirtual()); + ID.AddInteger(Base.getAccessSpecifierAsWritten()); + } +} + +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; + + // TODO: Fix hashing for class methods. + if (isa<CXXMethodDecl>(Function)) return; + // And friend functions. + if (Function->getFriendObjectKind()) 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(); 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, @@ -420,6 +519,7 @@ void ODRHash::AddDecl(const Decl *D) { } } +namespace { // Process a Type pointer. Add* methods call back into ODRHash while Visit* // methods process the relevant parts of the Type. class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> { @@ -608,6 +708,7 @@ public: AddDecl(T->getDecl()); } }; +} // namespace void ODRHash::AddType(const Type *T) { assert(T && "Expecting non-null pointer."); |
