diff options
Diffstat (limited to 'lib/AST/ODRHash.cpp')
-rw-r--r-- | lib/AST/ODRHash.cpp | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp index 121724a73152..17c95f2a0af7 100644 --- a/lib/AST/ODRHash.cpp +++ b/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,6 +450,20 @@ 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::AddDecl(const Decl *D) { @@ -420,6 +483,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 +672,7 @@ public: AddDecl(T->getDecl()); } }; +} // namespace void ODRHash::AddType(const Type *T) { assert(T && "Expecting non-null pointer."); |