diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-27 00:25:58 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-27 00:25:58 +0000 |
| commit | 0b88437ebd4239386971cfac8bd1f020742305f4 (patch) | |
| tree | fa1bbcfbaade9771789dd4ee2689295d13e7a1b9 | |
| parent | f9da928993fd49fa6b59e964574a5aea5f2cbef8 (diff) | |
| download | bcm5719-llvm-0b88437ebd4239386971cfac8bd1f020742305f4.tar.gz bcm5719-llvm-0b88437ebd4239386971cfac8bd1f020742305f4.zip | |
[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
5 files changed, 64 insertions, 61 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 339d0b87c25..a10ae1edf94 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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)); - - 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)); + ReadDeclIDList(SpecIDs); + + 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)); - - 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)); + ReadDeclIDList(SpecIDs); + + 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); } } } diff --git a/clang/test/Modules/Inputs/merge-decl-context/a.h b/clang/test/Modules/Inputs/merge-decl-context/a.h index bd08ecaf417..89cc7120fd1 100644 --- a/clang/test/Modules/Inputs/merge-decl-context/a.h +++ b/clang/test/Modules/Inputs/merge-decl-context/a.h @@ -8,6 +8,8 @@ struct A { } A(double) {} A(double, double) {} + A(double, int) {} + A(int, double) {} }; template <typename T1, typename T2> diff --git a/clang/test/Modules/Inputs/merge-decl-context/d.h b/clang/test/Modules/Inputs/merge-decl-context/d.h new file mode 100644 index 00000000000..ccc7308b249 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-decl-context/d.h @@ -0,0 +1,7 @@ +#ifndef D_H +#define D_H + +#include "a.h" +#include "b.h" + +#endif diff --git a/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap b/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap index fedc5dfbbe4..46f69548bc6 100644 --- a/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap +++ b/clang/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap @@ -11,3 +11,8 @@ module "c" { export * header "c.h" } + +module "d" { + export * + header "d.h" +} diff --git a/clang/test/Modules/merge-decl-context.cpp b/clang/test/Modules/merge-decl-context.cpp index 90c234b66f5..208ba9212e8 100644 --- a/clang/test/Modules/merge-decl-context.cpp +++ b/clang/test/Modules/merge-decl-context.cpp @@ -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); } - - |

