summaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-16 21:03:44 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-16 21:03:44 +0000
commit325377b57338e700317f5e423e5b0f1c08d99a39 (patch)
treeacd401a9713562cf3e93d13fa6a70ad67eb5cd99 /lib/Serialization
parent1b08b196ac845675036ac78f3ac927d0a37f707c (diff)
Notes
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp154
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp85
2 files changed, 192 insertions, 47 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 94a8f609f57c0..eeb0132c16900 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -9242,6 +9242,7 @@ void ASTReader::diagnoseOdrViolations() {
// Used with err_module_odr_violation_mismatch_decl and
// note_module_odr_violation_mismatch_decl
+ // This list should be the same Decl's as in ODRHash::isWhiteListedDecl
enum {
EndOfClass,
PublicSpecifer,
@@ -9250,6 +9251,9 @@ void ASTReader::diagnoseOdrViolations() {
StaticAssert,
Field,
CXXMethod,
+ TypeAlias,
+ TypeDef,
+ Var,
Other
} FirstDiffType = Other,
SecondDiffType = Other;
@@ -9277,6 +9281,12 @@ void ASTReader::diagnoseOdrViolations() {
return Field;
case Decl::CXXMethod:
return CXXMethod;
+ case Decl::TypeAlias:
+ return TypeAlias;
+ case Decl::Typedef:
+ return TypeDef;
+ case Decl::Var:
+ return Var;
}
};
@@ -9373,6 +9383,15 @@ void ASTReader::diagnoseOdrViolations() {
MethodNumberParameters,
MethodParameterType,
MethodParameterName,
+ MethodParameterSingleDefaultArgument,
+ MethodParameterDifferentDefaultArgument,
+ TypedefName,
+ TypedefType,
+ VarName,
+ VarType,
+ VarSingleInitializer,
+ VarDifferentInitializer,
+ VarConstexpr,
};
// These lambdas have the common portions of the ODR diagnostics. This
@@ -9739,6 +9758,38 @@ void ASTReader::diagnoseOdrViolations() {
ParameterMismatch = true;
break;
}
+
+ const Expr *FirstInit = FirstParam->getInit();
+ const Expr *SecondInit = SecondParam->getInit();
+ if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(),
+ MethodParameterSingleDefaultArgument)
+ << FirstName << (I + 1) << (FirstInit == nullptr)
+ << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(),
+ MethodParameterSingleDefaultArgument)
+ << SecondName << (I + 1) << (SecondInit == nullptr)
+ << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
+ ParameterMismatch = true;
+ break;
+ }
+
+ if (FirstInit && SecondInit &&
+ ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
+ ODRDiagError(FirstMethod->getLocation(),
+ FirstMethod->getSourceRange(),
+ MethodParameterDifferentDefaultArgument)
+ << FirstName << (I + 1) << FirstInit->getSourceRange();
+ ODRDiagNote(SecondMethod->getLocation(),
+ SecondMethod->getSourceRange(),
+ MethodParameterDifferentDefaultArgument)
+ << SecondName << (I + 1) << SecondInit->getSourceRange();
+ ParameterMismatch = true;
+ break;
+
+ }
}
if (ParameterMismatch) {
@@ -9748,6 +9799,109 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
+ case TypeAlias:
+ case TypeDef: {
+ TypedefNameDecl *FirstTD = cast<TypedefNameDecl>(FirstDecl);
+ TypedefNameDecl *SecondTD = cast<TypedefNameDecl>(SecondDecl);
+ auto FirstName = FirstTD->getDeclName();
+ auto SecondName = SecondTD->getDeclName();
+ if (FirstName != SecondName) {
+ ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
+ TypedefName)
+ << (FirstDiffType == TypeAlias) << FirstName;
+ ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
+ TypedefName)
+ << (FirstDiffType == TypeAlias) << SecondName;
+ Diagnosed = true;
+ break;
+ }
+
+ QualType FirstType = FirstTD->getUnderlyingType();
+ QualType SecondType = SecondTD->getUnderlyingType();
+ if (ComputeQualTypeODRHash(FirstType) !=
+ ComputeQualTypeODRHash(SecondType)) {
+ ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
+ TypedefType)
+ << (FirstDiffType == TypeAlias) << FirstName << FirstType;
+ ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
+ TypedefType)
+ << (FirstDiffType == TypeAlias) << SecondName << SecondType;
+ Diagnosed = true;
+ break;
+ }
+ break;
+ }
+ case Var: {
+ VarDecl *FirstVD = cast<VarDecl>(FirstDecl);
+ VarDecl *SecondVD = cast<VarDecl>(SecondDecl);
+ auto FirstName = FirstVD->getDeclName();
+ auto SecondName = SecondVD->getDeclName();
+ if (FirstName != SecondName) {
+ ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
+ VarName)
+ << FirstName;
+ ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
+ VarName)
+ << SecondName;
+ Diagnosed = true;
+ break;
+ }
+
+ QualType FirstType = FirstVD->getType();
+ QualType SecondType = SecondVD->getType();
+ if (ComputeQualTypeODRHash(FirstType) !=
+ ComputeQualTypeODRHash(SecondType)) {
+ ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
+ VarType)
+ << FirstName << FirstType;
+ ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
+ VarType)
+ << SecondName << SecondType;
+ Diagnosed = true;
+ break;
+ }
+
+ const Expr *FirstInit = FirstVD->getInit();
+ const Expr *SecondInit = SecondVD->getInit();
+ if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
+ ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
+ VarSingleInitializer)
+ << FirstName << (FirstInit == nullptr)
+ << (FirstInit ? FirstInit->getSourceRange(): SourceRange());
+ ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
+ VarSingleInitializer)
+ << SecondName << (SecondInit == nullptr)
+ << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
+ Diagnosed = true;
+ break;
+ }
+
+ if (FirstInit && SecondInit &&
+ ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
+ ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
+ VarDifferentInitializer)
+ << FirstName << FirstInit->getSourceRange();
+ ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
+ VarDifferentInitializer)
+ << SecondName << SecondInit->getSourceRange();
+ Diagnosed = true;
+ break;
+ }
+
+ const bool FirstIsConstexpr = FirstVD->isConstexpr();
+ const bool SecondIsConstexpr = SecondVD->isConstexpr();
+ if (FirstIsConstexpr != SecondIsConstexpr) {
+ ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
+ VarConstexpr)
+ << FirstName << FirstIsConstexpr;
+ ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
+ VarConstexpr)
+ << SecondName << SecondIsConstexpr;
+ Diagnosed = true;
+ break;
+ }
+ break;
+ }
}
if (Diagnosed == true)
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 9c467055fe551..ed103e629216c 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -216,30 +216,6 @@ namespace clang {
TypedefNameForLinkage(nullptr), HasPendingBody(false),
IsDeclMarkedUsed(false) {}
- template <typename T> static
- void AddLazySpecializations(T *D,
- SmallVectorImpl<serialization::DeclID>& IDs) {
- if (IDs.empty())
- return;
-
- // FIXME: We should avoid this pattern of getting the ASTContext.
- ASTContext &C = D->getASTContext();
-
- auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations;
-
- if (auto &Old = LazySpecializations) {
- IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
- std::sort(IDs.begin(), IDs.end());
- IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
- }
-
- auto *Result = new (C) serialization::DeclID[1 + IDs.size()];
- *Result = IDs.size();
- std::copy(IDs.begin(), IDs.end(), Result + 1);
-
- LazySpecializations = Result;
- }
-
template <typename DeclT>
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
static Decl *getMostRecentDeclImpl(...);
@@ -268,7 +244,7 @@ namespace clang {
void ReadFunctionDefinition(FunctionDecl *FD);
void Visit(Decl *D);
- void UpdateDecl(Decl *D, llvm::SmallVectorImpl<serialization::DeclID>&);
+ void UpdateDecl(Decl *D);
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
ObjCCategoryDecl *Next) {
@@ -1976,6 +1952,21 @@ 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");
+ if (Old) {
+ IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
+ std::sort(IDs.begin(), IDs.end());
+ IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
+ }
+
+ auto *Result = new (Context) DeclID[1 + IDs.size()];
+ *Result = IDs.size();
+ std::copy(IDs.begin(), IDs.end(), Result + 1);
+ return Result;
+}
+
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
@@ -1984,7 +1975,12 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// the specializations.
SmallVector<serialization::DeclID, 32> SpecIDs;
ReadDeclIDList(SpecIDs);
- ASTDeclReader::AddLazySpecializations(D, SpecIDs);
+
+ if (!SpecIDs.empty()) {
+ auto *CommonPtr = D->getCommonPtr();
+ CommonPtr->LazySpecializations = newDeclIDList(
+ Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
+ }
}
if (D->getTemplatedDecl()->TemplateOrInstantiation) {
@@ -2011,7 +2007,12 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
// the specializations.
SmallVector<serialization::DeclID, 32> SpecIDs;
ReadDeclIDList(SpecIDs);
- ASTDeclReader::AddLazySpecializations(D, SpecIDs);
+
+ if (!SpecIDs.empty()) {
+ auto *CommonPtr = D->getCommonPtr();
+ CommonPtr->LazySpecializations = newDeclIDList(
+ Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
+ }
}
}
@@ -2117,7 +2118,12 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// This FunctionTemplateDecl owns a CommonPtr; read it.
SmallVector<serialization::DeclID, 32> SpecIDs;
ReadDeclIDList(SpecIDs);
- ASTDeclReader::AddLazySpecializations(D, SpecIDs);
+
+ if (!SpecIDs.empty()) {
+ auto *CommonPtr = D->getCommonPtr();
+ CommonPtr->LazySpecializations = newDeclIDList(
+ Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
+ }
}
}
@@ -3661,9 +3667,6 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
Decl *D = Record.D;
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
-
- llvm::SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
-
if (UpdI != DeclUpdateOffsets.end()) {
auto UpdateOffsets = std::move(UpdI->second);
DeclUpdateOffsets.erase(UpdI);
@@ -3688,7 +3691,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
SourceLocation());
- Reader.UpdateDecl(D, PendingLazySpecializationIDs);
+ Reader.UpdateDecl(D);
// We might have made this declaration interesting. If so, remember that
// we need to hand it off to the consumer.
@@ -3700,17 +3703,6 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
}
}
}
- // Add the lazy specializations to the template.
- assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) ||
- isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) &&
- "Must not have pending specializations");
- if (auto *CTD = dyn_cast<ClassTemplateDecl>(D))
- ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs);
- else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
- ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs);
- else if (auto *VTD = dyn_cast<VarTemplateDecl>(D))
- ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs);
- PendingLazySpecializationIDs.clear();
// Load the pending visible updates for this decl context, if it has any.
auto I = PendingVisibleUpdates.find(ID);
@@ -3907,8 +3899,7 @@ static void forAllLaterRedecls(DeclT *D, Fn F) {
}
}
-void ASTDeclReader::UpdateDecl(Decl *D,
- llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) {
+void ASTDeclReader::UpdateDecl(Decl *D) {
while (Record.getIdx() < Record.size()) {
switch ((DeclUpdateKind)Record.readInt()) {
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
@@ -3924,8 +3915,8 @@ void ASTDeclReader::UpdateDecl(Decl *D,
}
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
- // It will be added to the template's lazy specialization set.
- PendingLazySpecializationIDs.push_back(ReadDeclID());
+ // It will be added to the template's specializations set when loaded.
+ (void)Record.readDecl();
break;
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {