From a7fae60ad9bddc322191668b3ddb0cb31e45b338 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Wed, 31 May 2017 00:31:58 +0000 Subject: [PATCH] [ODRHash] Support TemplateSpecializationType git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304261 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ODRHash.cpp | 28 +++++++++++++++++++++++++++- test/Modules/odr_hash.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp index 24371db64d..0e822ce35b 100644 --- a/lib/AST/ODRHash.cpp +++ b/lib/AST/ODRHash.cpp @@ -110,7 +110,24 @@ void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) { } } -void ODRHash::AddTemplateName(TemplateName Name) {} +void ODRHash::AddTemplateName(TemplateName Name) { + auto Kind = Name.getKind(); + ID.AddInteger(Kind); + + switch (Kind) { + case TemplateName::Template: + AddDecl(Name.getAsTemplateDecl()); + break; + // TODO: Support these cases. + case TemplateName::OverloadedTemplate: + case TemplateName::QualifiedTemplate: + case TemplateName::DependentTemplate: + case TemplateName::SubstTemplateTemplateParm: + case TemplateName::SubstTemplateTemplateParmPack: + break; + } +} + void ODRHash::AddTemplateArgument(TemplateArgument TA) {} void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {} @@ -492,6 +509,15 @@ public: AddQualType(T->getNamedType()); VisitTypeWithKeyword(T); } + + void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { + ID.AddInteger(T->getNumArgs()); + for (const auto &TA : T->template_arguments()) { + Hash.AddTemplateArgument(TA); + } + Hash.AddTemplateName(T->getTemplateName()); + VisitType(T); + } }; void ODRHash::AddType(const Type *T) { diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index 947583bcfd..a6a0b74743 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -866,6 +866,40 @@ S9 s9; #endif } +namespace TemplateSpecializationType { +#if defined(FIRST) +template struct U1 {}; +struct S1 { + U1 u; +}; +#elif defined(SECOND) +template struct U1 {}; +struct S1 { + U1 u; +}; +#else +S1 s1; +// expected-error@first.h:* {{'TemplateSpecializationType::S1::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'u' does not match}} +#endif + +#if defined(FIRST) +template struct U2 {}; +struct S2 { + U2 u; +}; +#elif defined(SECOND) +template struct V1 {}; +struct S2 { + V1 u; +}; +#else +S2 s2; +// expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'u' does not match}} +#endif +} + // Interesting cases that should not cause errors. struct S should not error // while struct T should error at the access specifier mismatch at the end. namespace AllDecls { -- 2.40.0