forked from OSchip/llvm-project
[modules] When loading in multiple canonical definitions of a template,
accumulate the set of specializations rather than overwriting one list with another. llvm-svn: 230712
This commit is contained in:
parent
f9da928993
commit
0b88437ebd
|
@ -66,7 +66,12 @@ namespace clang {
|
|||
serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
|
||||
return Reader.ReadDeclID(F, R, I);
|
||||
}
|
||||
|
||||
|
||||
void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) {
|
||||
for (unsigned I = 0, Size = Record[Idx++]; I != Size; ++I)
|
||||
IDs.push_back(ReadDeclID(Record, Idx));
|
||||
}
|
||||
|
||||
Decl *ReadDecl(const RecordData &R, unsigned &I) {
|
||||
return Reader.ReadDecl(F, R, I);
|
||||
}
|
||||
|
@ -398,7 +403,6 @@ void ASTDeclReader::Visit(Decl *D) {
|
|||
// FunctionDecl's body was written last after all other Stmts/Exprs.
|
||||
// We only read it if FD doesn't already have a body (e.g., from another
|
||||
// module).
|
||||
// FIXME: Also consider = default and = delete.
|
||||
// FIXME: Can we diagnose ODR violations somehow?
|
||||
if (Record[Idx++]) {
|
||||
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
|
||||
|
@ -1393,8 +1397,6 @@ void ASTDeclReader::MergeDefinitionData(
|
|||
}
|
||||
|
||||
// FIXME: Move this out into a .def file?
|
||||
// FIXME: Issue a diagnostic on a mismatched MATCH_FIELD, rather than
|
||||
// asserting; this can happen in the case of an ODR violation.
|
||||
bool DetectedOdrViolation = false;
|
||||
#define OR_FIELD(Field) DD.Field |= MergeDD.Field;
|
||||
#define MATCH_FIELD(Field) \
|
||||
|
@ -1723,36 +1725,37 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
|||
return Redecl;
|
||||
}
|
||||
|
||||
static DeclID *newDeclIDList(ASTContext &Context, DeclID *Old,
|
||||
SmallVectorImpl<DeclID> &IDs) {
|
||||
assert(!IDs.empty() && "no IDs to add to list");
|
||||
|
||||
size_t OldCount = Old ? *Old : 0;
|
||||
size_t NewCount = OldCount + IDs.size();
|
||||
auto *Result = new (Context) DeclID[1 + NewCount];
|
||||
auto *Pos = Result;
|
||||
*Pos++ = NewCount;
|
||||
if (OldCount)
|
||||
Pos = std::copy(Old + 1, Old + 1 + OldCount, Pos);
|
||||
std::copy(IDs.begin(), IDs.end(), Pos);
|
||||
return Result;
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
||||
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
||||
|
||||
if (ThisDeclID == Redecl.getFirstID()) {
|
||||
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
|
||||
// the specializations.
|
||||
SmallVector<serialization::DeclID, 2> SpecIDs;
|
||||
SpecIDs.push_back(0);
|
||||
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
// Specializations.
|
||||
unsigned Size = Record[Idx++];
|
||||
SpecIDs[0] += Size;
|
||||
for (unsigned I = 0; I != Size; ++I)
|
||||
SpecIDs.push_back(ReadDeclID(Record, Idx));
|
||||
|
||||
ReadDeclIDList(SpecIDs);
|
||||
// Partial specializations.
|
||||
Size = Record[Idx++];
|
||||
SpecIDs[0] += Size;
|
||||
for (unsigned I = 0; I != Size; ++I)
|
||||
SpecIDs.push_back(ReadDeclID(Record, Idx));
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
|
||||
if (SpecIDs[0]) {
|
||||
typedef serialization::DeclID DeclID;
|
||||
|
||||
// FIXME: Append specializations!
|
||||
CommonPtr->LazySpecializations
|
||||
= new (Reader.getContext()) DeclID [SpecIDs.size()];
|
||||
memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
|
||||
SpecIDs.size() * sizeof(DeclID));
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1774,30 +1777,16 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
|||
if (ThisDeclID == Redecl.getFirstID()) {
|
||||
// This VarTemplateDecl owns a CommonPtr; read it to keep track of all of
|
||||
// the specializations.
|
||||
SmallVector<serialization::DeclID, 2> SpecIDs;
|
||||
SpecIDs.push_back(0);
|
||||
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
// Specializations.
|
||||
unsigned Size = Record[Idx++];
|
||||
SpecIDs[0] += Size;
|
||||
for (unsigned I = 0; I != Size; ++I)
|
||||
SpecIDs.push_back(ReadDeclID(Record, Idx));
|
||||
|
||||
ReadDeclIDList(SpecIDs);
|
||||
// Partial specializations.
|
||||
Size = Record[Idx++];
|
||||
SpecIDs[0] += Size;
|
||||
for (unsigned I = 0; I != Size; ++I)
|
||||
SpecIDs.push_back(ReadDeclID(Record, Idx));
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
VarTemplateDecl::Common *CommonPtr = D->getCommonPtr();
|
||||
if (SpecIDs[0]) {
|
||||
typedef serialization::DeclID DeclID;
|
||||
|
||||
// FIXME: Append specializations!
|
||||
CommonPtr->LazySpecializations =
|
||||
new (Reader.getContext()) DeclID[SpecIDs.size()];
|
||||
memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
|
||||
SpecIDs.size() * sizeof(DeclID));
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1909,17 +1898,13 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|||
|
||||
if (ThisDeclID == Redecl.getFirstID()) {
|
||||
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
// Read the function specialization declaration IDs. The specializations
|
||||
// themselves will be loaded if they're needed.
|
||||
if (unsigned NumSpecs = Record[Idx++]) {
|
||||
// FIXME: Append specializations!
|
||||
FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = new (Reader.getContext())
|
||||
serialization::DeclID[NumSpecs + 1];
|
||||
CommonPtr->LazySpecializations[0] = NumSpecs;
|
||||
for (unsigned I = 0; I != NumSpecs; ++I)
|
||||
CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx);
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ struct A {
|
|||
}
|
||||
A(double) {}
|
||||
A(double, double) {}
|
||||
A(double, int) {}
|
||||
A(int, double) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef D_H
|
||||
#define D_H
|
||||
|
||||
#include "a.h"
|
||||
#include "b.h"
|
||||
|
||||
#endif
|
|
@ -11,3 +11,8 @@ module "c" {
|
|||
export *
|
||||
header "c.h"
|
||||
}
|
||||
|
||||
module "d" {
|
||||
export *
|
||||
header "d.h"
|
||||
}
|
||||
|
|
|
@ -4,21 +4,25 @@
|
|||
// RUN: -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
|
||||
// RUN: -I %S/Inputs/merge-decl-context
|
||||
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=c -o %t/c.pcm -fmodule-maps \
|
||||
// RUN: -fmodule-file=%t/b.pcm \
|
||||
// RUN: -fmodule-file=%t/b.pcm -fno-implicit-modules \
|
||||
// RUN: -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
|
||||
// RUN: -I %S/Inputs/merge-decl-context
|
||||
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=d -o %t/d.pcm -fmodule-maps \
|
||||
// RUN: -fmodule-file=%t/b.pcm -fno-implicit-modules \
|
||||
// RUN: -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
|
||||
// RUN: -I %S/Inputs/merge-decl-context
|
||||
|
||||
// Use the two modules in a single compile.
|
||||
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/c.pcm -fmodule-file=%t/b.pcm \
|
||||
// RUN: -fmodule-file=%t/d.pcm -fno-implicit-modules \
|
||||
// RUN: -fmodule-map-file=%S/Inputs/merge-decl-context/merge-decl-context.modulemap -I%S/Inputs \
|
||||
// RUN: -emit-llvm -o %t/test.o %s
|
||||
|
||||
#include "Inputs/merge-decl-context/a.h"
|
||||
#include "Inputs/merge-decl-context/b.h"
|
||||
#include "Inputs/merge-decl-context/c.h"
|
||||
#include "Inputs/merge-decl-context/d.h"
|
||||
|
||||
void t() {
|
||||
ff(42);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue