r230712 - [modules] When loading in multiple canonical definitions of a template,
Richard Smith
richard-llvm at metafoo.co.uk
Thu Feb 26 16:25:59 PST 2015
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);
}
}
}
@@ -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);
}
-
-
More information about the cfe-commits
mailing list