On Fri, Feb 27, 2015 at 1:30 AM Richard Smith <[email protected]> wrote:
> Author: rsmith > Date: Thu Feb 26 18:25:58 2015 > New Revision: 230712 > > URL: http://llvm.org/viewvc/llvm-project?rev=230712&view=rev > Log: > [modules] When loading in multiple canonical definitions of a template, > accumulate the set of specializations rather than overwriting one list > with another. > > Added: > cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h > Modified: > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h > cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl- > context.modulemap > cfe/trunk/test/Modules/merge-decl-context.cpp > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ > Serialization/ASTReaderDecl.cpp?rev=230712&r1=230711&r2=230712&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Feb 26 18:25:58 2015 > @@ -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::VisitRedeclarableTemplate > 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 > 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); > } > } > } > This seems 100% identical to VisitClassTemplateDecl now (unless I'm missing something). > @@ -1909,17 +1898,13 @@ void ASTDeclReader::VisitFunctionTemplat > > 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); > } > } > } > > Modified: cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/merge-decl-context/a.h?rev=230712&r1= > 230711&r2=230712&view=diff > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h (original) > +++ cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h Thu Feb 26 > 18:25:58 2015 > @@ -8,6 +8,8 @@ struct A { > } > A(double) {} > A(double, double) {} > + A(double, int) {} > + A(int, double) {} > }; > > template <typename T1, typename T2> > > Added: cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/merge-decl-context/d.h?rev=230712&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h (added) > +++ cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h Thu Feb 26 > 18:25:58 2015 > @@ -0,0 +1,7 @@ > +#ifndef D_H > +#define D_H > + > +#include "a.h" > +#include "b.h" > + > +#endif > > Modified: cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl- > context.modulemap > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/merge-decl-context/merge-decl-context. > modulemap?rev=230712&r1=230711&r2=230712&view=diff > ============================================================ > ================== > --- > cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap > (original) > +++ > cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap > Thu Feb 26 18:25:58 2015 > @@ -11,3 +11,8 @@ module "c" { > export * > header "c.h" > } > + > +module "d" { > + export * > + header "d.h" > +} > > Modified: cfe/trunk/test/Modules/merge-decl-context.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/merge-decl-context.cpp?rev=230712&r1=230711&r2=230712&view=diff > ============================================================ > ================== > --- cfe/trunk/test/Modules/merge-decl-context.cpp (original) > +++ cfe/trunk/test/Modules/merge-decl-context.cpp Thu Feb 26 18:25:58 2015 > @@ -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); > } > - > - > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
