r212836 - [modules] When merging a class template, also merge the definition of its pattern.
Richard Smith
richard-llvm at metafoo.co.uk
Fri Jul 11 11:22:58 PDT 2014
Author: rsmith
Date: Fri Jul 11 13:22:58 2014
New Revision: 212836
URL: http://llvm.org/viewvc/llvm-project?rev=212836&view=rev
Log:
[modules] When merging a class template, also merge the definition of its pattern.
Modified:
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
cfe/trunk/test/Modules/Inputs/cxx-templates-c.h
cfe/trunk/test/Modules/cxx-templates.cpp
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=212836&r1=212835&r2=212836&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Jul 11 13:22:58 2014
@@ -1758,11 +1758,11 @@ ASTDeclReader::VisitClassTemplateSpecial
Reader.MergedDeclContexts.insert(
std::make_pair(D, CanonDD->Definition));
D->IsCompleteDefinition = false;
- D->DefinitionData = CanonSpec->DefinitionData;
} else {
CanonSpec->DefinitionData = D->DefinitionData;
}
}
+ D->DefinitionData = CanonSpec->DefinitionData;
}
}
}
@@ -2037,10 +2037,27 @@ void ASTDeclReader::mergeTemplatePattern
auto *DPattern = D->getTemplatedDecl();
auto *ExistingPattern = Existing->getTemplatedDecl();
RedeclarableResult Result(Reader, DsID, DPattern->getKind());
- if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern))
- // FIXME: Merge definitions here, if both declarations had definitions.
+ if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
+ // Merge with any existing definition.
+ // FIXME: This is duplicated in several places. Refactor.
+ auto *ExistingClass =
+ cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();
+ if (auto *DDD = DClass->DefinitionData.getNotUpdated()) {
+ if (auto *ExistingDD = ExistingClass->DefinitionData.getNotUpdated()) {
+ MergeDefinitionData(ExistingClass, *DDD);
+ Reader.PendingDefinitions.erase(DClass);
+ Reader.MergedDeclContexts.insert(
+ std::make_pair(DClass, ExistingDD->Definition));
+ DClass->IsCompleteDefinition = false;
+ } else {
+ ExistingClass->DefinitionData = DClass->DefinitionData;
+ }
+ }
+ DClass->DefinitionData = ExistingClass->DefinitionData;
+
return mergeRedeclarable(DClass, cast<TagDecl>(ExistingPattern),
Result);
+ }
if (auto *DFunction = dyn_cast<FunctionDecl>(DPattern))
return mergeRedeclarable(DFunction, cast<FunctionDecl>(ExistingPattern),
Result);
Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-a.h?rev=212836&r1=212835&r2=212836&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-a.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-a.h Fri Jul 11 13:22:58 2014
@@ -67,3 +67,9 @@ template<> struct WithExplicitSpecializa
template<typename T> template<typename U>
constexpr int Outer<T>::Inner<U>::f() { return 1; }
static_assert(Outer<int>::Inner<int>::f() == 1, "");
+
+template<typename T> struct MergeTemplateDefinitions {
+ static constexpr int f();
+ static constexpr int g();
+};
+template<typename T> constexpr int MergeTemplateDefinitions<T>::f() { return 1; }
Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-c.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-c.h?rev=212836&r1=212835&r2=212836&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-c.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-c.h Fri Jul 11 13:22:58 2014
@@ -5,3 +5,9 @@ template<typename T> struct MergeSpecial
template<> struct MergeSpecializations<bool> {
typedef int explicitly_specialized_in_c;
};
+
+template<typename T> struct MergeTemplateDefinitions {
+ static constexpr int f();
+ static constexpr int g();
+};
+template<typename T> constexpr int MergeTemplateDefinitions<T>::g() { return 2; }
Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=212836&r1=212835&r2=212836&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Fri Jul 11 13:22:58 2014
@@ -110,6 +110,9 @@ void g() {
static_assert(Outer<int>::Inner<int>::f() == 1, "");
static_assert(Outer<int>::Inner<int>::g() == 2, "");
+static_assert(MergeTemplateDefinitions<int>::f() == 1, "");
+static_assert(MergeTemplateDefinitions<int>::g() == 2, "");
+
RedeclaredAsFriend<int> raf1;
RedeclareTemplateAsFriend<double> rtaf;
RedeclaredAsFriend<double> raf2;
More information about the cfe-commits
mailing list