summaryrefslogtreecommitdiffstats
path: root/lib/Serialization
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
committerdim <dim@FreeBSD.org>2015-06-21 14:00:56 +0000
commit9dd834653b811ad20382e98a87dff824980c9916 (patch)
treea764184c2fc9486979b074250b013a0937ee64e5 /lib/Serialization
parentbb9760db9b86e93a638ed430d0a14785f7ff9064 (diff)
downloadFreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.zip
FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.tar.gz
Vendor import of clang trunk r240225:
https://llvm.org/svn/llvm-project/cfe/trunk@240225
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp55
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp277
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp31
-rw-r--r--lib/Serialization/ASTWriter.cpp5
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp29
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp21
-rw-r--r--lib/Serialization/GeneratePCH.cpp33
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp17
-rw-r--r--lib/Serialization/ModuleManager.cpp14
9 files changed, 284 insertions, 198 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 609c25d..d75b5eb 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
@@ -3590,6 +3591,7 @@ ASTReader::ReadASTCore(StringRef FileName,
ModuleFile &F = *M;
BitstreamCursor &Stream = F.Stream;
+ PCHContainerOps.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile);
Stream.init(&F.StreamFile);
F.SizeInBits = F.Buffer->getBufferSize() * 8;
@@ -3858,9 +3860,9 @@ static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){
/// \brief Retrieve the name of the original source file name
/// directly from the AST file, without actually loading the AST
/// file.
-std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
- FileManager &FileMgr,
- DiagnosticsEngine &Diags) {
+std::string ASTReader::getOriginalSourceFile(
+ const std::string &ASTFileName, FileManager &FileMgr,
+ const PCHContainerOperations &PCHContainerOps, DiagnosticsEngine &Diags) {
// Open the AST file.
auto Buffer = FileMgr.getBufferForFile(ASTFileName);
if (!Buffer) {
@@ -3871,8 +3873,7 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
// Initialize the stream
llvm::BitstreamReader StreamFile;
- StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
- (const unsigned char *)(*Buffer)->getBufferEnd());
+ PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
BitstreamCursor Stream(StreamFile);
// Sniff for the signature.
@@ -3954,9 +3955,10 @@ namespace {
};
}
-bool ASTReader::readASTFileControlBlock(StringRef Filename,
- FileManager &FileMgr,
- ASTReaderListener &Listener) {
+bool ASTReader::readASTFileControlBlock(
+ StringRef Filename, FileManager &FileMgr,
+ const PCHContainerOperations &PCHContainerOps,
+ ASTReaderListener &Listener) {
// Open the AST file.
// FIXME: This allows use of the VFS; we do not allow use of the
// VFS when actually loading a module.
@@ -4147,16 +4149,15 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,
}
}
-
-bool ASTReader::isAcceptableASTFile(StringRef Filename,
- FileManager &FileMgr,
- const LangOptions &LangOpts,
- const TargetOptions &TargetOpts,
- const PreprocessorOptions &PPOpts,
- std::string ExistingModuleCachePath) {
+bool ASTReader::isAcceptableASTFile(
+ StringRef Filename, FileManager &FileMgr,
+ const PCHContainerOperations &PCHContainerOps, const LangOptions &LangOpts,
+ const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts,
+ std::string ExistingModuleCachePath) {
SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
ExistingModuleCachePath, FileMgr);
- return !readASTFileControlBlock(Filename, FileMgr, validator);
+ return !readASTFileControlBlock(Filename, FileMgr, PCHContainerOps,
+ validator);
}
ASTReader::ASTReadResult
@@ -8407,24 +8408,26 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
}
}
-ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot,
- bool DisableValidation, bool AllowASTWithCompilerErrors,
+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
+ const PCHContainerOperations &PCHContainerOps,
+ StringRef isysroot, bool DisableValidation,
+ bool AllowASTWithCompilerErrors,
bool AllowConfigurationMismatch, bool ValidateSystemInputs,
bool UseGlobalIndex)
: Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr),
OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
- FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
- SemaObj(nullptr), PP(PP), Context(Context), Consumer(nullptr),
- ModuleMgr(PP.getFileManager()), isysroot(isysroot),
- DisableValidation(DisableValidation),
+ FileMgr(PP.getFileManager()), PCHContainerOps(PCHContainerOps),
+ Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context),
+ Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerOps),
+ isysroot(isysroot), DisableValidation(DisableValidation),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
AllowConfigurationMismatch(AllowConfigurationMismatch),
ValidateSystemInputs(ValidateSystemInputs),
UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
- CurrSwitchCaseStmts(&SwitchCaseStmts),
- NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0),
- TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0),
- NumIdentifierLookups(0), NumIdentifierLookupHits(0), NumSelectorsRead(0),
+ CurrSwitchCaseStmts(&SwitchCaseStmts), NumSLocEntriesRead(0),
+ TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
+ NumMacrosRead(0), TotalNumMacros(0), NumIdentifierLookups(0),
+ NumIdentifierLookupHits(0), NumSelectorsRead(0),
NumMethodPoolEntriesRead(0), NumMethodPoolLookups(0),
NumMethodPoolHits(0), NumMethodPoolTableLookups(0),
NumMethodPoolTableHits(0), TotalNumMethodPoolEntries(0),
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 02273ed..00ebd3e 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -365,9 +365,72 @@ namespace clang {
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+
+ /// We've merged the definition \p MergedDef into the existing definition
+ /// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made
+ /// visible.
+ void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef) {
+ if (Def->isHidden()) {
+ // If MergedDef is visible or becomes visible, make the definition visible.
+ if (!MergedDef->isHidden())
+ Def->Hidden = false;
+ else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
+ Reader.getContext().mergeDefinitionIntoModule(
+ Def, MergedDef->getImportedOwningModule(),
+ /*NotifyListeners*/ false);
+ Reader.PendingMergedDefinitionsToDeduplicate.insert(Def);
+ } else {
+ auto SubmoduleID = MergedDef->getOwningModuleID();
+ assert(SubmoduleID && "hidden definition in no module");
+ Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back(Def);
+ }
+ }
+ }
};
}
+namespace {
+/// Iterator over the redeclarations of a declaration that have already
+/// been merged into the same redeclaration chain.
+template<typename DeclT>
+class MergedRedeclIterator {
+ DeclT *Start, *Canonical, *Current;
+public:
+ MergedRedeclIterator() : Current(nullptr) {}
+ MergedRedeclIterator(DeclT *Start)
+ : Start(Start), Canonical(nullptr), Current(Start) {}
+
+ DeclT *operator*() { return Current; }
+
+ MergedRedeclIterator &operator++() {
+ if (Current->isFirstDecl()) {
+ Canonical = Current;
+ Current = Current->getMostRecentDecl();
+ } else
+ Current = Current->getPreviousDecl();
+
+ // If we started in the merged portion, we'll reach our start position
+ // eventually. Otherwise, we'll never reach it, but the second declaration
+ // we reached was the canonical declaration, so stop when we see that one
+ // again.
+ if (Current == Start || Current == Canonical)
+ Current = nullptr;
+ return *this;
+ }
+
+ friend bool operator!=(const MergedRedeclIterator &A,
+ const MergedRedeclIterator &B) {
+ return A.Current != B.Current;
+ }
+};
+}
+template<typename DeclT>
+llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) {
+ return llvm::iterator_range<MergedRedeclIterator<DeclT>>(
+ MergedRedeclIterator<DeclT>(D),
+ MergedRedeclIterator<DeclT>());
+}
+
uint64_t ASTDeclReader::GetCurrentCursorOffset() {
return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset;
}
@@ -585,9 +648,21 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
if (ED->IsCompleteDefinition &&
Reader.getContext().getLangOpts().Modules &&
Reader.getContext().getLangOpts().CPlusPlus) {
- if (EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]) {
+ EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
+ if (!OldDef) {
+ // This is the first time we've seen an imported definition. Look for a
+ // local definition before deciding that we are the first definition.
+ for (auto *D : merged_redecls(ED->getCanonicalDecl())) {
+ if (!D->isFromASTFile() && D->isCompleteDefinition()) {
+ OldDef = D;
+ break;
+ }
+ }
+ }
+ if (OldDef) {
Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
ED->IsCompleteDefinition = false;
+ mergeDefinitionVisibility(OldDef, ED);
} else {
OldDef = ED;
}
@@ -967,7 +1042,9 @@ void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
VisitNamedDecl(D);
D->setAtLoc(ReadSourceLocation(Record, Idx));
D->setLParenLoc(ReadSourceLocation(Record, Idx));
- D->setType(GetTypeSourceInfo(Record, Idx));
+ QualType T = Reader.readType(F, Record, Idx);
+ TypeSourceInfo *TSI = GetTypeSourceInfo(Record, Idx);
+ D->setType(T, TSI);
// FIXME: stable encoding
D->setPropertyAttributes(
(ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
@@ -1391,32 +1468,22 @@ void ASTDeclReader::MergeDefinitionData(
"merging class definition into non-definition");
auto &DD = *D->DefinitionData.getNotUpdated();
- // If the new definition has new special members, let the name lookup
- // code know that it needs to look in the new definition too.
- //
- // FIXME: We only need to do this if the merged definition declares members
- // that this definition did not declare, or if it defines members that this
- // definition did not define.
if (DD.Definition != MergeDD.Definition) {
+ // If the new definition has new special members, let the name lookup
+ // code know that it needs to look in the new definition too.
+ //
+ // FIXME: We only need to do this if the merged definition declares members
+ // that this definition did not declare, or if it defines members that this
+ // definition did not define.
Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition);
DD.Definition->setHasExternalVisibleStorage();
- if (DD.Definition->isHidden()) {
- // If MergeDD is visible or becomes visible, make the definition visible.
- if (!MergeDD.Definition->isHidden())
- DD.Definition->Hidden = false;
- else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
- Reader.getContext().mergeDefinitionIntoModule(
- DD.Definition, MergeDD.Definition->getImportedOwningModule(),
- /*NotifyListeners*/ false);
- Reader.PendingMergedDefinitionsToDeduplicate.insert(DD.Definition);
- } else {
- auto SubmoduleID = MergeDD.Definition->getOwningModuleID();
- assert(SubmoduleID && "hidden definition in no module");
- Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back(
- DD.Definition);
- }
- }
+ // Track that we merged the definitions.
+ Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
+ DD.Definition));
+ Reader.PendingDefinitions.erase(MergeDD.Definition);
+ MergeDD.Definition->IsCompleteDefinition = false;
+ mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
}
auto PFDI = Reader.PendingFakeDefinitionData.find(&DD);
@@ -1525,42 +1592,21 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) {
// because we're reading an update record, or because we've already done some
// merging. Either way, just merge into it.
CXXRecordDecl *Canon = D->getCanonicalDecl();
- if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
- if (CanonDD->Definition != DD->Definition)
- Reader.MergedDeclContexts.insert(
- std::make_pair(DD->Definition, CanonDD->Definition));
+ if (Canon->DefinitionData.getNotUpdated()) {
MergeDefinitionData(Canon, std::move(*DD));
D->DefinitionData = Canon->DefinitionData;
return;
}
- // Propagate the DefinitionData pointer to the canonical declaration, so
- // that all other deserialized declarations will see it.
- if (Canon == D) {
- D->DefinitionData = DD;
- D->IsCompleteDefinition = true;
-
- // If this is an update record, we can have redeclarations already. Make a
- // note that we need to propagate the DefinitionData pointer onto them.
- if (Update)
- Reader.PendingDefinitions.insert(D);
- } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
- // We have already deserialized a definition of this record. This
- // definition is no longer really a definition. Note that the pre-existing
- // definition is the *real* definition.
- Reader.MergedDeclContexts.insert(
- std::make_pair(D, CanonDD->Definition));
- D->DefinitionData = Canon->DefinitionData;
- D->IsCompleteDefinition = false;
- MergeDefinitionData(D, std::move(*DD));
- } else {
- Canon->DefinitionData = DD;
- D->DefinitionData = Canon->DefinitionData;
- D->IsCompleteDefinition = true;
+ // Mark this declaration as being a definition.
+ D->IsCompleteDefinition = true;
+ D->DefinitionData = DD;
- // Note that we have deserialized a definition. Any declarations
- // deserialized before this one will be be given the DefinitionData
- // pointer at the end.
+ // If this is not the first declaration or is an update record, we can have
+ // other redeclarations already. Make a note that we need to propagate the
+ // DefinitionData pointer onto them.
+ if (Update || Canon != D) {
+ Canon->DefinitionData = D->DefinitionData;
Reader.PendingDefinitions.insert(D);
}
}
@@ -1880,15 +1926,10 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
// This declaration might be a definition. Merge with any existing
// definition.
if (auto *DDD = D->DefinitionData.getNotUpdated()) {
- if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) {
+ if (CanonSpec->DefinitionData.getNotUpdated())
MergeDefinitionData(CanonSpec, std::move(*DDD));
- Reader.PendingDefinitions.erase(D);
- Reader.MergedDeclContexts.insert(
- std::make_pair(D, CanonDD->Definition));
- D->IsCompleteDefinition = false;
- } else {
+ else
CanonSpec->DefinitionData = D->DefinitionData;
- }
}
D->DefinitionData = CanonSpec->DefinitionData;
}
@@ -2033,9 +2074,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
D->setDeclaredWithTypename(Record[Idx++]);
- bool Inherited = Record[Idx++];
- TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx);
- D->setDefaultArgument(DefArg, Inherited);
+ if (Record[Idx++])
+ D->setDefaultArgument(GetTypeSourceInfo(Record, Idx));
}
void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
@@ -2052,11 +2092,8 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
} else {
// Rest of NonTypeTemplateParmDecl.
D->ParameterPack = Record[Idx++];
- if (Record[Idx++]) {
- Expr *DefArg = Reader.ReadExpr(F);
- bool Inherited = Record[Idx++];
- D->setDefaultArgument(DefArg, Inherited);
- }
+ if (Record[Idx++])
+ D->setDefaultArgument(Reader.ReadExpr(F));
}
}
@@ -2072,10 +2109,10 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx);
} else {
// Rest of TemplateTemplateParmDecl.
- TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx);
- bool IsInherited = Record[Idx++];
- D->setDefaultArgument(Arg, IsInherited);
D->ParameterPack = Record[Idx++];
+ if (Record[Idx++])
+ D->setDefaultArgument(Reader.getContext(),
+ Reader.ReadTemplateArgumentLoc(F, Record, Idx));
}
}
@@ -2189,14 +2226,12 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
auto *ExistingClass =
cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();
if (auto *DDD = DClass->DefinitionData.getNotUpdated()) {
- if (auto *ExistingDD = ExistingClass->DefinitionData.getNotUpdated()) {
+ if (ExistingClass->DefinitionData.getNotUpdated()) {
MergeDefinitionData(ExistingClass, std::move(*DDD));
- Reader.PendingDefinitions.erase(DClass);
- Reader.MergedDeclContexts.insert(
- std::make_pair(DClass, ExistingDD->Definition));
- DClass->IsCompleteDefinition = false;
} else {
ExistingClass->DefinitionData = DClass->DefinitionData;
+ // We may have skipped this before because we thought that DClass
+ // was the canonical declaration.
Reader.PendingDefinitions.insert(DClass);
}
}
@@ -2904,6 +2939,43 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {
llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
}
+/// Inherit the default template argument from \p From to \p To. Returns
+/// \c false if there is no default template for \p From.
+template <typename ParmDecl>
+static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
+ Decl *ToD) {
+ auto *To = cast<ParmDecl>(ToD);
+ if (!From->hasDefaultArgument())
+ return false;
+ To->setInheritedDefaultArgument(Context, From);
+ return true;
+}
+
+static void inheritDefaultTemplateArguments(ASTContext &Context,
+ TemplateDecl *From,
+ TemplateDecl *To) {
+ auto *FromTP = From->getTemplateParameters();
+ auto *ToTP = To->getTemplateParameters();
+ assert(FromTP->size() == ToTP->size() && "merged mismatched templates?");
+
+ for (unsigned I = 0, N = FromTP->size(); I != N; ++I) {
+ NamedDecl *FromParam = FromTP->getParam(N - I - 1);
+ NamedDecl *ToParam = ToTP->getParam(N - I - 1);
+
+ if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) {
+ if (!inheritDefaultTemplateArgument(Context, FTTP, ToParam))
+ break;
+ } else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam)) {
+ if (!inheritDefaultTemplateArgument(Context, FNTTP, ToParam))
+ break;
+ } else {
+ if (!inheritDefaultTemplateArgument(
+ Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam))
+ break;
+ }
+ }
+}
+
void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
Decl *Previous, Decl *Canon) {
assert(D && Previous);
@@ -2930,6 +3002,12 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
// be too.
if (Previous->Used)
D->Used = true;
+
+ // If the declaration declares a template, it may inherit default arguments
+ // from the previous declaration.
+ if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
+ inheritDefaultTemplateArguments(Reader.getContext(),
+ cast<TemplateDecl>(Previous), TD);
}
template<typename DeclT>
@@ -3579,48 +3657,6 @@ void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,
ModuleMgr.visit(ObjCCategoriesVisitor::visit, &Visitor);
}
-namespace {
-/// Iterator over the redeclarations of a declaration that have already
-/// been merged into the same redeclaration chain.
-template<typename DeclT>
-class MergedRedeclIterator {
- DeclT *Start, *Canonical, *Current;
-public:
- MergedRedeclIterator() : Current(nullptr) {}
- MergedRedeclIterator(DeclT *Start)
- : Start(Start), Canonical(nullptr), Current(Start) {}
-
- DeclT *operator*() { return Current; }
-
- MergedRedeclIterator &operator++() {
- if (Current->isFirstDecl()) {
- Canonical = Current;
- Current = Current->getMostRecentDecl();
- } else
- Current = Current->getPreviousDecl();
-
- // If we started in the merged portion, we'll reach our start position
- // eventually. Otherwise, we'll never reach it, but the second declaration
- // we reached was the canonical declaration, so stop when we see that one
- // again.
- if (Current == Start || Current == Canonical)
- Current = nullptr;
- return *this;
- }
-
- friend bool operator!=(const MergedRedeclIterator &A,
- const MergedRedeclIterator &B) {
- return A.Current != B.Current;
- }
-};
-}
-template<typename DeclT>
-llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) {
- return llvm::iterator_range<MergedRedeclIterator<DeclT>>(
- MergedRedeclIterator<DeclT>(D),
- MergedRedeclIterator<DeclT>());
-}
-
template<typename DeclT, typename Fn>
static void forAllLaterRedecls(DeclT *D, Fn F) {
F(D);
@@ -3854,6 +3890,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
case UPD_DECL_EXPORTED:
unsigned SubmoduleID = readSubmoduleID(Record, Idx);
+ auto *Exported = cast<NamedDecl>(D);
+ if (auto *TD = dyn_cast<TagDecl>(Exported))
+ Exported = TD->getDefinition();
Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr;
if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
// FIXME: This doesn't send the right notifications if there are
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index d1ecd46..c15f6b0 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -801,6 +801,16 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
Designators.data(), Designators.size());
}
+void ASTStmtReader::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
+ VisitExpr(E);
+ E->setBase(Reader.ReadSubExpr());
+ E->setUpdater(Reader.ReadSubExpr());
+}
+
+void ASTStmtReader::VisitNoInitExpr(NoInitExpr *E) {
+ VisitExpr(E);
+}
+
void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
VisitExpr(E);
}
@@ -2063,9 +2073,7 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) {
D->setLastIteration(Reader.ReadSubExpr());
D->setCalcLastIteration(Reader.ReadSubExpr());
D->setPreCond(Reader.ReadSubExpr());
- auto Fst = Reader.ReadSubExpr();
- auto Snd = Reader.ReadSubExpr();
- D->setCond(Fst, Snd);
+ D->setCond(Reader.ReadSubExpr());
D->setInit(Reader.ReadSubExpr());
D->setInc(Reader.ReadSubExpr());
if (isOpenMPWorksharingDirective(D->getDirectiveKind())) {
@@ -2181,6 +2189,11 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
+ VisitStmt(D);
+ VisitOMPExecutableDirective(D);
+}
+
void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
VisitStmt(D);
// The NumClauses field was read in ReadStmtFromStream.
@@ -2549,10 +2562,18 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
+ case EXPR_DESIGNATED_INIT_UPDATE:
+ S = new (Context) DesignatedInitUpdateExpr(Empty);
+ break;
+
case EXPR_IMPLICIT_VALUE_INIT:
S = new (Context) ImplicitValueInitExpr(Empty);
break;
+ case EXPR_NO_INIT:
+ S = new (Context) NoInitExpr(Empty);
+ break;
+
case EXPR_VA_ARG:
S = new (Context) VAArgExpr(Empty);
break;
@@ -2787,6 +2808,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = OMPTaskwaitDirective::CreateEmpty(Context, Empty);
break;
+ case STMT_OMP_TASKGROUP_DIRECTIVE:
+ S = OMPTaskgroupDirective::CreateEmpty(Context, Empty);
+ break;
+
case STMT_OMP_FLUSH_DIRECTIVE:
S = OMPFlushDirective::CreateEmpty(
Context, Record[ASTStmtReader::NumStmtFields], Empty);
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index e689234..5bb0bec 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -774,7 +774,9 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
RECORD(EXPR_EXT_VECTOR_ELEMENT);
RECORD(EXPR_INIT_LIST);
RECORD(EXPR_DESIGNATED_INIT);
+ RECORD(EXPR_DESIGNATED_INIT_UPDATE);
RECORD(EXPR_IMPLICIT_VALUE_INIT);
+ RECORD(EXPR_NO_INIT);
RECORD(EXPR_VA_ARG);
RECORD(EXPR_ADDR_LABEL);
RECORD(EXPR_STMT);
@@ -5762,8 +5764,5 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
assert(!WritingAST && "Already writing the AST!");
assert(D->isHidden() && "expected a hidden declaration");
- if (!D->isFromASTFile())
- return;
-
DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M));
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 0fa4f93..6c5bc5b 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -190,8 +190,7 @@ namespace clang {
assert(D->isCanonicalDecl() && "non-canonical decl in set");
Writer.AddDeclRef(D, Record);
}
- for (DeclID ID : LazySpecializations)
- Record.push_back(ID);
+ Record.append(LazySpecializations.begin(), LazySpecializations.end());
}
};
}
@@ -543,7 +542,7 @@ void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// FIXME: stable encoding for @required/@optional
Record.push_back(D->getImplementationControl());
- // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
+ // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
Record.push_back(D->getObjCDeclQualifier());
Record.push_back(D->hasRelatedResultType());
Writer.AddTypeRef(D->getReturnType(), Record);
@@ -679,6 +678,7 @@ void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
VisitNamedDecl(D);
Writer.AddSourceLocation(D->getAtLoc(), Record);
Writer.AddSourceLocation(D->getLParenLoc(), Record);
+ Writer.AddTypeRef(D->getType(), Record);
Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
// FIXME: stable encoding
Record.push_back((unsigned)D->getPropertyAttributes());
@@ -1380,8 +1380,12 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
VisitTypeDecl(D);
Record.push_back(D->wasDeclaredWithTypename());
- Record.push_back(D->defaultArgumentWasInherited());
- Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
+
+ bool OwnsDefaultArg = D->hasDefaultArgument() &&
+ !D->defaultArgumentWasInherited();
+ Record.push_back(OwnsDefaultArg);
+ if (OwnsDefaultArg)
+ Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
Code = serialization::DECL_TEMPLATE_TYPE_PARM;
}
@@ -1408,11 +1412,11 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
} else {
// Rest of NonTypeTemplateParmDecl.
Record.push_back(D->isParameterPack());
- Record.push_back(D->getDefaultArgument() != nullptr);
- if (D->getDefaultArgument()) {
+ bool OwnsDefaultArg = D->hasDefaultArgument() &&
+ !D->defaultArgumentWasInherited();
+ Record.push_back(OwnsDefaultArg);
+ if (OwnsDefaultArg)
Writer.AddStmt(D->getDefaultArgument());
- Record.push_back(D->defaultArgumentWasInherited());
- }
Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
}
}
@@ -1437,9 +1441,12 @@ void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
} else {
// Rest of TemplateTemplateParmDecl.
- Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
- Record.push_back(D->defaultArgumentWasInherited());
Record.push_back(D->isParameterPack());
+ bool OwnsDefaultArg = D->hasDefaultArgument() &&
+ !D->defaultArgumentWasInherited();
+ Record.push_back(OwnsDefaultArg);
+ if (OwnsDefaultArg)
+ Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
}
}
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index ec822f0..a461d3f 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -738,6 +738,18 @@ void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
Code = serialization::EXPR_DESIGNATED_INIT;
}
+void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
+ VisitExpr(E);
+ Writer.AddStmt(E->getBase());
+ Writer.AddStmt(E->getUpdater());
+ Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
+}
+
+void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
+ VisitExpr(E);
+ Code = serialization::EXPR_NO_INIT;
+}
+
void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
VisitExpr(E);
Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
@@ -1917,8 +1929,7 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
Writer.AddStmt(D->getLastIteration());
Writer.AddStmt(D->getCalcLastIteration());
Writer.AddStmt(D->getPreCond());
- Writer.AddStmt(D->getCond(/* SeparateIter */ false));
- Writer.AddStmt(D->getCond(/* SeparateIter */ true));
+ Writer.AddStmt(D->getCond());
Writer.AddStmt(D->getInit());
Writer.AddStmt(D->getInc());
if (isOpenMPWorksharingDirective(D->getDirectiveKind())) {
@@ -2060,6 +2071,12 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
+ VisitStmt(D);
+ VisitOMPExecutableDirective(D);
+ Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
+}
+
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
VisitStmt(D);
Record.push_back(D->getNumClauses());
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index b5031fd..c50b3f9 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -24,16 +24,14 @@
using namespace clang;
-PCHGenerator::PCHGenerator(const Preprocessor &PP,
- StringRef OutputFile,
- clang::Module *Module,
- StringRef isysroot,
- raw_ostream *OS, bool AllowASTWithErrors)
- : PP(PP), OutputFile(OutputFile), Module(Module),
- isysroot(isysroot.str()), Out(OS),
- SemaPtr(nullptr), Stream(Buffer), Writer(Stream),
- AllowASTWithErrors(AllowASTWithErrors),
- HasEmittedPCH(false) {
+PCHGenerator::PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
+ clang::Module *Module, StringRef isysroot,
+ std::shared_ptr<PCHBuffer> Buffer,
+ bool AllowASTWithErrors)
+ : PP(PP), OutputFile(OutputFile), Module(Module), isysroot(isysroot.str()),
+ SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data), Writer(Stream),
+ AllowASTWithErrors(AllowASTWithErrors) {
+ Buffer->IsComplete = false;
}
PCHGenerator::~PCHGenerator() {
@@ -47,21 +45,12 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
bool hasErrors = PP.getDiagnostics().hasErrorOccurred();
if (hasErrors && !AllowASTWithErrors)
return;
-
- // Emit the PCH file
+
+ // Emit the PCH file to the Buffer.
assert(SemaPtr && "No Sema?");
Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, hasErrors);
- // Write the generated bitstream to "Out".
- Out->write((char *)&Buffer.front(), Buffer.size());
-
- // Make sure it hits disk now.
- Out->flush();
-
- // Free up some memory, in case the process is kept alive.
- Buffer.clear();
-
- HasEmittedPCH = true;
+ Buffer->IsComplete = true;
}
ASTMutationListener *PCHGenerator::GetASTMutationListener() {
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index 1b52b44..2c7da3e 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ASTReaderInternals.h"
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Serialization/ASTBitCodes.h"
@@ -384,6 +385,7 @@ namespace {
/// \brief Builder that generates the global module index file.
class GlobalModuleIndexBuilder {
FileManager &FileMgr;
+ const PCHContainerOperations &PCHContainerOps;
/// \brief Mapping from files to module file information.
typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
@@ -416,7 +418,9 @@ namespace {
}
public:
- explicit GlobalModuleIndexBuilder(FileManager &FileMgr) : FileMgr(FileMgr){}
+ explicit GlobalModuleIndexBuilder(
+ FileManager &FileMgr, const PCHContainerOperations &PCHContainerOps)
+ : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps) {}
/// \brief Load the contents of the given module file into the builder.
///
@@ -501,8 +505,7 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
// Initialize the input stream
llvm::BitstreamReader InStreamFile;
- InStreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
- (const unsigned char *)(*Buffer)->getBufferEnd());
+ PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), InStreamFile);
llvm::BitstreamCursor InStream(InStreamFile);
// Sniff for the signature.
@@ -764,7 +767,9 @@ void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
}
GlobalModuleIndex::ErrorCode
-GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) {
+GlobalModuleIndex::writeIndex(FileManager &FileMgr,
+ const PCHContainerOperations &PCHContainerOps,
+ StringRef Path) {
llvm::SmallString<128> IndexPath;
IndexPath += Path;
llvm::sys::path::append(IndexPath, IndexFileName);
@@ -787,8 +792,8 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) {
}
// The module index builder.
- GlobalModuleIndexBuilder Builder(FileMgr);
-
+ GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerOps);
+
// Load each of the module files.
std::error_code EC;
for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 30d9c89..03d8ed0 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -11,6 +11,7 @@
// modules for the ASTReader.
//
//===----------------------------------------------------------------------===//
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
@@ -136,10 +137,9 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
New->Buffer = std::move(*Buf);
}
-
- // Initialize the stream
- New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
- (const unsigned char *)New->Buffer->getBufferEnd());
+
+ // Initialize the stream.
+ PCHContainerOps.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile);
}
if (ExpectedSignature) {
@@ -289,8 +289,10 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
ModulesInCommonWithGlobalIndex.push_back(MF);
}
-ModuleManager::ModuleManager(FileManager &FileMgr)
- : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(nullptr) {}
+ModuleManager::ModuleManager(FileManager &FileMgr,
+ const PCHContainerOperations &PCHContainerOps)
+ : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps), GlobalIndex(),
+ FirstVisitState(nullptr) {}
ModuleManager::~ModuleManager() {
for (unsigned i = 0, e = Chain.size(); i != e; ++i)
OpenPOWER on IntegriCloud