[ODRHash] Support TemplateSpecializationType

llvm-svn: 304261
This commit is contained in:
Richard Trieu 2017-05-31 00:31:58 +00:00
parent 180de970c8
commit 96b4962c8d
2 changed files with 61 additions and 1 deletions

View File

@ -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) {

View File

@ -866,6 +866,40 @@ S9 s9;
#endif
}
namespace TemplateSpecializationType {
#if defined(FIRST)
template <class T1> struct U1 {};
struct S1 {
U1<int> u;
};
#elif defined(SECOND)
template <class T1, class T2> struct U1 {};
struct S1 {
U1<int, int> 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 <class T1> struct U2 {};
struct S2 {
U2<int> u;
};
#elif defined(SECOND)
template <class T1> struct V1 {};
struct S2 {
V1<int> 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 {