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;
}
}
}
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);
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; }
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; }
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;