[modules] Merging support for specializations of a function template. This very

rarely matters, but can affect whether two dependent types are canonically
equivalent.

llvm-svn: 241207
This commit is contained in:
Richard Smith 2015-07-01 23:19:58 +00:00
parent 9729fb3315
commit da6c234c39
3 changed files with 15 additions and 5 deletions

View File

@ -810,14 +810,14 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C);
void *InsertPos = nullptr;
FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
FunctionTemplateSpecializationInfo *ExistingInfo =
CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
if (InsertPos)
CommonPtr->Specializations.InsertNode(FTInfo, InsertPos);
else {
assert(Reader.getContext().getLangOpts().Modules &&
"already deserialized this template specialization");
// FIXME: This specialization is a redeclaration of one from another
// module. Merge it.
mergeRedeclarable(FD, ExistingInfo->Function, Redecl);
}
}
break;
@ -839,8 +839,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setDependentTemplateSpecialization(Reader.getContext(),
TemplDecls, TemplArgs);
// FIXME: Merging.
// These are not merged; we don't need to merge redeclarations of dependent
// template friends.
break;
}
}

View File

@ -86,3 +86,11 @@ namespace SeparateInline {
namespace TrailingAttributes {
template<typename T> struct X {} __attribute__((aligned(8)));
}
namespace MergeFunctionTemplateSpecializations {
template<typename T> T f();
template<typename T> struct X {
template<typename U> using Q = decltype(f<T>() + U());
};
using xiq = X<int>::Q<int>;
}

View File

@ -100,6 +100,8 @@ J<> post_j2;
FriendDefArg::Y<int> friend_def_arg;
FriendDefArg::D<> friend_def_arg_d;
MergeFunctionTemplateSpecializations::X<int>::Q<char> xiqc;
#ifdef TEXTUAL
#include "use-defs.h"
void use_static_inline() { StaticInline::g({}); }