Update Clang for 3.5 rebase (r209713).
Change-Id: I8c9133b0f8f776dc915f270b60f94962e771bc83
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index ff0b1dd..4ea95d0 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
@@ -29,6 +30,7 @@
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/Version.h"
#include "clang/Basic/VersionTuple.h"
+#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/MacroInfo.h"
@@ -70,6 +72,14 @@
return First->ReadFullVersionInformation(FullVersion) ||
Second->ReadFullVersionInformation(FullVersion);
}
+void ChainedASTReaderListener::ReadModuleName(StringRef ModuleName) {
+ First->ReadModuleName(ModuleName);
+ Second->ReadModuleName(ModuleName);
+}
+void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) {
+ First->ReadModuleMapFile(ModuleMapPath);
+ Second->ReadModuleMapFile(ModuleMapPath);
+}
bool ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
bool Complain) {
return First->ReadLanguageOptions(LangOpts, Complain) ||
@@ -82,7 +92,7 @@
Second->ReadTargetOptions(TargetOpts, Complain);
}
bool ChainedASTReaderListener::ReadDiagnosticOptions(
- const DiagnosticOptions &DiagOpts, bool Complain) {
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
Second->ReadDiagnosticOptions(DiagOpts, Complain);
}
@@ -125,8 +135,14 @@
bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
bool isSystem,
bool isOverridden) {
- return First->visitInputFile(Filename, isSystem, isOverridden) ||
- Second->visitInputFile(Filename, isSystem, isOverridden);
+ bool Continue = false;
+ if (First->needsInputFileVisitation() &&
+ (!isSystem || First->needsSystemInputFileVisitation()))
+ Continue |= First->visitInputFile(Filename, isSystem, isOverridden);
+ if (Second->needsInputFileVisitation() &&
+ (!isSystem || Second->needsSystemInputFileVisitation()))
+ Continue |= Second->visitInputFile(Filename, isSystem, isOverridden);
+ return Continue;
}
//===----------------------------------------------------------------------===//
@@ -210,7 +226,6 @@
CHECK_TARGET_OPT(Triple, "target");
CHECK_TARGET_OPT(CPU, "target CPU");
CHECK_TARGET_OPT(ABI, "target ABI");
- CHECK_TARGET_OPT(LinkerVersion, "target linker version");
#undef CHECK_TARGET_OPT
// Compare feature sets.
@@ -266,14 +281,14 @@
bool Complain) {
const LangOptions &ExistingLangOpts = PP.getLangOpts();
return checkLanguageOptions(LangOpts, ExistingLangOpts,
- Complain? &Reader.Diags : 0);
+ Complain? &Reader.Diags : nullptr);
}
bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
bool Complain) {
const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();
return checkTargetOptions(TargetOpts, ExistingTargetOpts,
- Complain? &Reader.Diags : 0);
+ Complain? &Reader.Diags : nullptr);
}
namespace {
@@ -283,11 +298,126 @@
DeclsMap;
}
+static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
+ DiagnosticsEngine &Diags,
+ bool Complain) {
+ typedef DiagnosticsEngine::Level Level;
+
+ // Check current mappings for new -Werror mappings, and the stored mappings
+ // for cases that were explicitly mapped to *not* be errors that are now
+ // errors because of options like -Werror.
+ DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags };
+
+ for (DiagnosticsEngine *MappingSource : MappingSources) {
+ for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) {
+ diag::kind DiagID = DiagIDMappingPair.first;
+ Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
+ if (CurLevel < DiagnosticsEngine::Error)
+ continue; // not significant
+ Level StoredLevel =
+ StoredDiags.getDiagnosticLevel(DiagID, SourceLocation());
+ if (StoredLevel < DiagnosticsEngine::Error) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" +
+ Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static DiagnosticsEngine::ExtensionHandling
+isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
+ DiagnosticsEngine::ExtensionHandling Ext =
+ Diags.getExtensionHandlingBehavior();
+ if (Ext == DiagnosticsEngine::Ext_Warn && Diags.getWarningsAsErrors())
+ Ext = DiagnosticsEngine::Ext_Error;
+ return Ext;
+}
+
+static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
+ DiagnosticsEngine &Diags,
+ bool IsSystem, bool Complain) {
+ // Top-level options
+ if (IsSystem) {
+ if (Diags.getSuppressSystemWarnings())
+ return false;
+ // If -Wsystem-headers was not enabled before, be conservative
+ if (StoredDiags.getSuppressSystemWarnings()) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers";
+ return true;
+ }
+ }
+
+ if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror";
+ return true;
+ }
+
+ if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings() &&
+ !StoredDiags.getEnableAllWarnings()) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror";
+ return true;
+ }
+
+ if (isExtHandlingFromDiagsError(Diags) &&
+ !isExtHandlingFromDiagsError(StoredDiags)) {
+ if (Complain)
+ Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors";
+ return true;
+ }
+
+ return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
+}
+
+bool PCHValidator::ReadDiagnosticOptions(
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
+ DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagIDs, DiagOpts.getPtr()));
+ // This should never fail, because we would have processed these options
+ // before writing them to an ASTFile.
+ ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
+
+ ModuleManager &ModuleMgr = Reader.getModuleManager();
+ assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
+
+ // If the original import came from a file explicitly generated by the user,
+ // don't check the diagnostic mappings.
+ // FIXME: currently this is approximated by checking whether this is not a
+ // module import.
+ // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
+ // the transitive closure of its imports, since unrelated modules cannot be
+ // imported until after this module finishes validation.
+ ModuleFile *TopImport = *ModuleMgr.rbegin();
+ while (!TopImport->ImportedBy.empty())
+ TopImport = TopImport->ImportedBy[0];
+ if (TopImport->Kind != MK_Module)
+ return false;
+
+ StringRef ModuleName = TopImport->ModuleName;
+ assert(!ModuleName.empty() && "diagnostic options read before module name");
+
+ Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
+ assert(M && "missing module");
+
+ // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
+ // contains the union of their flags.
+ return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
+}
+
/// \brief Collect the macro definitions provided by the given preprocessor
/// options.
-static void collectMacroDefinitions(const PreprocessorOptions &PPOpts,
- MacroDefinitionsMap &Macros,
- SmallVectorImpl<StringRef> *MacroNames = 0){
+static void
+collectMacroDefinitions(const PreprocessorOptions &PPOpts,
+ MacroDefinitionsMap &Macros,
+ SmallVectorImpl<StringRef> *MacroNames = nullptr) {
for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
StringRef Macro = PPOpts.Macros[I].first;
bool IsUndef = PPOpts.Macros[I].second;
@@ -442,7 +572,7 @@
const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts();
return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
- Complain? &Reader.Diags : 0,
+ Complain? &Reader.Diags : nullptr,
PP.getFileManager(),
SuggestedPredefines,
PP.getLangOpts());
@@ -456,9 +586,10 @@
// AST reader implementation
//===----------------------------------------------------------------------===//
-void
-ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
+void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener,
+ bool TakeOwnership) {
DeserializationListener = Listener;
+ OwnsDeserializationListener = TakeOwnership;
}
@@ -851,11 +982,11 @@
Error("Expected visible lookup table block");
return true;
}
- Info.NameLookupTableData
- = ASTDeclContextNameLookupTable::Create(
- (const unsigned char *)Blob.data() + Record[0],
- (const unsigned char *)Blob.data(),
- ASTDeclContextNameLookupTrait(*this, M));
+ Info.NameLookupTableData = ASTDeclContextNameLookupTable::Create(
+ (const unsigned char *)Blob.data() + Record[0],
+ (const unsigned char *)Blob.data() + sizeof(uint32_t),
+ (const unsigned char *)Blob.data(),
+ ASTDeclContextNameLookupTrait(*this, M));
}
return false;
@@ -1125,8 +1256,8 @@
llvm::MemoryBuffer *Buffer
= llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name);
- SourceMgr.createFileIDForMemBuffer(Buffer, FileCharacter, ID,
- BaseOffset + Offset, IncludeLoc);
+ SourceMgr.createFileID(Buffer, FileCharacter, ID, BaseOffset + Offset,
+ IncludeLoc);
break;
}
@@ -1161,7 +1292,7 @@
// FIXME: Can we map this down to a particular submodule? That would be
// ideal.
- return std::make_pair(M->ImportLoc, llvm::sys::path::stem(M->FileName));
+ return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));
}
/// \brief Find the location where the module F is imported.
@@ -1172,14 +1303,10 @@
// Otherwise we have a PCH. It's considered to be "imported" at the first
// location of its includer.
if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
- // Main file is the importer. We assume that it is the first entry in the
- // entry table. We can't ask the manager, because at the time of PCH loading
- // the main file entry doesn't exist yet.
- // The very first entry is the invalid instantiation loc, which takes up
- // offsets 0 and 1.
- return SourceLocation::getFromRawEncoding(2U);
+ // Main file is the importer.
+ assert(!SourceMgr.getMainFileID().isInvalid() && "missing main file");
+ return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
}
- //return F->Loaders[0]->FirstLoc;
return F->ImportedBy[0]->FirstLoc;
}
@@ -1228,7 +1355,7 @@
Stream.JumpToBit(Offset);
RecordData Record;
SmallVector<IdentifierInfo*, 16> MacroArgs;
- MacroInfo *Macro = 0;
+ MacroInfo *Macro = nullptr;
while (true) {
// Advance to the next record, but if we get to the end of the block, don't
@@ -1271,6 +1398,7 @@
MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, SubModID);
MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex));
MI->setIsUsed(Record[NextIndex++]);
+ MI->setUsedForHeaderGuard(Record[NextIndex++]);
if (RecType == PP_MACRO_FUNCTION_LIKE) {
// Decode function-like macro info.
@@ -1316,7 +1444,7 @@
case PP_TOKEN: {
// If we see a TOKEN before a PP_MACRO_*, then the file is
// erroneous, just pretend we didn't see this.
- if (Macro == 0) break;
+ if (!Macro) break;
unsigned Idx = 0;
Token Tok = ReadToken(F, Record, Idx);
@@ -1433,7 +1561,7 @@
GlobalMacroID GMacID,
llvm::ArrayRef<SubmoduleID> Overrides) {
assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
- SubmoduleID *OverrideData = 0;
+ SubmoduleID *OverrideData = nullptr;
if (!Overrides.empty()) {
OverrideData = new (Context) SubmoduleID[Overrides.size() + 1];
OverrideData[0] = Overrides.size();
@@ -1564,7 +1692,7 @@
// If there is a global index, look there first to determine which modules
// provably do not have any results for this identifier.
GlobalModuleIndex::HitSet Hits;
- GlobalModuleIndex::HitSet *HitsPtr = 0;
+ GlobalModuleIndex::HitSet *HitsPtr = nullptr;
if (!loadGlobalIndex()) {
if (GlobalIndex->lookupIdentifier(II.getName(), Hits)) {
HitsPtr = &Hits;
@@ -1586,7 +1714,7 @@
// Update the generation for this identifier.
if (getContext().getLangOpts().Modules)
- IdentifierGeneration[II] = CurrentGeneration;
+ IdentifierGeneration[II] = getGeneration();
}
struct ASTReader::ModuleMacroInfo {
@@ -1608,7 +1736,7 @@
DefMacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const {
if (!MI)
- return 0;
+ return nullptr;
return PP.AllocateDefMacroDirective(MI, ImportLoc, /*isImported=*/true);
}
};
@@ -1621,7 +1749,7 @@
if (ID & 1) {
// Macro undefinition.
Info.SubModID = getGlobalSubmoduleID(*PMInfo.M, ID >> 1);
- Info.MI = 0;
+ Info.MI = nullptr;
} else {
// Macro definition.
GlobalMacroID GMacID = getGlobalMacroID(*PMInfo.M, ID >> 1);
@@ -1631,7 +1759,7 @@
// FIXME: This is highly dubious. Multiple macro definitions can have the
// same MacroInfo (and hence the same GMacID) due to #pragma push_macro etc.
if (MacrosLoaded[GMacID - NUM_PREDEF_MACRO_IDS])
- return 0;
+ return nullptr;
Info.MI = getMacro(GMacID);
Info.SubModID = Info.MI->getOwningModuleID();
@@ -1692,10 +1820,10 @@
}
// Deserialize the macro directives history in reverse source-order.
- MacroDirective *Latest = 0, *Earliest = 0;
+ MacroDirective *Latest = nullptr, *Earliest = nullptr;
unsigned Idx = 0, N = Record.size();
while (Idx < N) {
- MacroDirective *MD = 0;
+ MacroDirective *MD = nullptr;
SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++];
switch (K) {
@@ -1735,7 +1863,7 @@
static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI,
Module *NewOwner, ASTReader &Reader) {
assert(PrevMI && NewMI);
- Module *PrevOwner = 0;
+ Module *PrevOwner = nullptr;
if (SubmoduleID PrevModID = PrevMI->getOwningModuleID())
PrevOwner = Reader.getSubmodule(PrevModID);
SourceManager &SrcMgr = Reader.getSourceManager();
@@ -1780,9 +1908,10 @@
llvm::ArrayRef<SubmoduleID> Overrides) {
MacroDirective *Prev = PP.getMacroDirective(II);
if (!Prev && Overrides.empty())
- return 0;
+ return nullptr;
- DefMacroDirective *PrevDef = Prev ? Prev->getDefinition().getDirective() : 0;
+ DefMacroDirective *PrevDef = Prev ? Prev->getDefinition().getDirective()
+ : nullptr;
if (PrevDef && PrevDef->isAmbiguous()) {
// We had a prior ambiguity. Check whether we resolve it (or make it worse).
AmbiguousMacros &Ambig = AmbiguousMacroDefs[II];
@@ -1796,7 +1925,7 @@
AmbiguousMacroDefs.erase(II);
} else {
// There's no ambiguity yet. Maybe we're introducing one.
- llvm::SmallVector<DefMacroDirective*, 1> Ambig;
+ AmbiguousMacros Ambig;
if (PrevDef)
Ambig.push_back(PrevDef);
@@ -1804,13 +1933,13 @@
if (!Ambig.empty()) {
AmbiguousMacros &Result = AmbiguousMacroDefs[II];
- Result.swap(Ambig);
+ std::swap(Result, Ambig);
return &Result;
}
}
// We ended up with no ambiguity.
- return 0;
+ return nullptr;
}
void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
@@ -1827,10 +1956,9 @@
assert(ImportLoc.isValid() && "no import location for a visible macro?");
}
- llvm::SmallVectorImpl<DefMacroDirective*> *Prev =
+ AmbiguousMacros *Prev =
removeOverriddenMacros(II, MMI->getOverriddenSubmodules());
-
// Create a synthetic macro definition corresponding to the import (or null
// if this was an undefinition of the macro).
DefMacroDirective *MD = MMI->import(PP, ImportLoc);
@@ -1954,7 +2082,7 @@
// If we didn't find the file, resolve it relative to the
// original directory from which this AST file was created.
- if (File == 0 && !F.OriginalDir.empty() && !CurrentDir.empty() &&
+ if (File == nullptr && !F.OriginalDir.empty() && !CurrentDir.empty() &&
F.OriginalDir != CurrentDir) {
std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
F.OriginalDir,
@@ -1965,11 +2093,11 @@
// For an overridden file, create a virtual file with the stored
// size/timestamp.
- if (Overridden && File == 0) {
+ if (Overridden && File == nullptr) {
File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
}
- if (File == 0) {
+ if (File == nullptr) {
if (Complain) {
std::string ErrorStr = "could not find file '";
ErrorStr += Filename;
@@ -2048,7 +2176,7 @@
std::string Filename = filenameStrRef;
MaybeAddSystemRootToFilename(M, Filename);
const FileEntry *File = FileMgr.getFile(Filename);
- if (File == 0 && !M.OriginalDir.empty() && !CurrentDir.empty() &&
+ if (File == nullptr && !M.OriginalDir.empty() && !CurrentDir.empty() &&
M.OriginalDir != CurrentDir) {
std::string resolved = resolveFileRelativeToOriginalDir(Filename,
M.OriginalDir,
@@ -2088,6 +2216,7 @@
ASTReader::ASTReadResult
ASTReader::ReadControlBlock(ModuleFile &F,
SmallVectorImpl<ImportedModule> &Loaded,
+ const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities) {
BitstreamCursor &Stream = F.Stream;
@@ -2117,7 +2246,7 @@
unsigned NumUserInputs = Record[1];
if (!DisableValidation &&
- (!HSOpts.ModulesValidateOncePerBuildSession ||
+ (ValidateSystemInputs || !HSOpts.ModulesValidateOncePerBuildSession ||
F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp)) {
bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
@@ -2262,11 +2391,11 @@
}
case DIAGNOSTIC_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
+ bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseDiagnosticOptions(Record, Complain, *Listener) &&
- !DisableValidation && !AllowConfigurationMismatch)
- return ConfigurationMismatch;
+ !DisableValidation)
+ return OutOfDate;
break;
}
@@ -2313,6 +2442,49 @@
F.OriginalDir = Blob;
break;
+ case MODULE_NAME:
+ F.ModuleName = Blob;
+ if (Listener)
+ Listener->ReadModuleName(F.ModuleName);
+ break;
+
+ case MODULE_MAP_FILE:
+ F.ModuleMapPath = Blob;
+
+ // Try to resolve ModuleName in the current header search context and
+ // verify that it is found in the same module map file as we saved. If the
+ // top-level AST file is a main file, skip this check because there is no
+ // usable header search context.
+ assert(!F.ModuleName.empty() &&
+ "MODULE_NAME should come before MOUDLE_MAP_FILE");
+ if (F.Kind == MK_Module &&
+ (*ModuleMgr.begin())->Kind != MK_MainFile) {
+ Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
+ if (!M) {
+ assert(ImportedBy && "top-level import should be verified");
+ if ((ClientLoadCapabilities & ARR_Missing) == 0)
+ Diag(diag::err_imported_module_not_found)
+ << F.ModuleName << ImportedBy->FileName;
+ return Missing;
+ }
+
+ const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
+ if (StoredModMap == nullptr || StoredModMap != M->ModuleMap) {
+ assert(M->ModuleMap && "found module is missing module map file");
+ assert(M->Name == F.ModuleName && "found module with different name");
+ assert(ImportedBy && "top-level import should be verified");
+ if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+ Diag(diag::err_imported_module_modmap_changed)
+ << F.ModuleName << ImportedBy->FileName
+ << M->ModuleMap->getName() << F.ModuleMapPath;
+ return OutOfDate;
+ }
+ }
+
+ if (Listener)
+ Listener->ReadModuleMapFile(F.ModuleMapPath);
+ break;
+
case INPUT_FILE_OFFSETS:
F.InputFileOffsets = (const uint32_t *)Blob.data();
F.InputFilesLoaded.resize(Record[0]);
@@ -2321,12 +2493,13 @@
}
}
-bool ASTReader::ReadASTBlock(ModuleFile &F) {
+ASTReader::ASTReadResult
+ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
BitstreamCursor &Stream = F.Stream;
if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
Error("malformed block record in AST file");
- return true;
+ return Failure;
}
// Read all of the records and blocks for the AST file.
@@ -2337,7 +2510,7 @@
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
Error("error at end of module block in AST file");
- return true;
+ return Failure;
case llvm::BitstreamEntry::EndBlock: {
// Outside of C++, we do not store a lookup map for the translation unit.
// Instead, mark it as needing a lookup map to be built if this module
@@ -2349,7 +2522,7 @@
!getContext().getLangOpts().CPlusPlus)
DC->setMustBuildLookupTable();
- return false;
+ return Success;
}
case llvm::BitstreamEntry::SubBlock:
switch (Entry.ID) {
@@ -2363,7 +2536,7 @@
// Read the abbrevs.
ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Error("malformed block record in AST file");
- return true;
+ return Failure;
}
break;
@@ -2375,7 +2548,7 @@
if (Stream.SkipBlock() ||
ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
Error("malformed block record in AST file");
- return true;
+ return Failure;
}
F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
break;
@@ -2386,7 +2559,7 @@
ReadBlockAbbrevs(F.PreprocessorDetailCursor,
PREPROCESSOR_DETAIL_BLOCK_ID)) {
Error("malformed preprocessor detail record in AST file");
- return true;
+ return Failure;
}
F.PreprocessorDetailStartOffset
= F.PreprocessorDetailCursor.GetCurrentBitNo();
@@ -2399,12 +2572,12 @@
case SOURCE_MANAGER_BLOCK_ID:
if (ReadSourceManagerBlock(F))
- return true;
+ return Failure;
break;
case SUBMODULE_BLOCK_ID:
- if (ReadSubmoduleBlock(F))
- return true;
+ if (ASTReadResult Result = ReadSubmoduleBlock(F, ClientLoadCapabilities))
+ return Result;
break;
case COMMENTS_BLOCK_ID: {
@@ -2412,7 +2585,7 @@
if (Stream.SkipBlock() ||
ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
Error("malformed comments block in AST file");
- return true;
+ return Failure;
}
CommentsCursors.push_back(std::make_pair(C, &F));
break;
@@ -2421,7 +2594,7 @@
default:
if (Stream.SkipBlock()) {
Error("malformed block record in AST file");
- return true;
+ return Failure;
}
break;
}
@@ -2442,7 +2615,7 @@
case TYPE_OFFSET: {
if (F.LocalNumTypes != 0) {
Error("duplicate TYPE_OFFSET record in AST file");
- return true;
+ return Failure;
}
F.TypeOffsets = (const uint32_t *)Blob.data();
F.LocalNumTypes = Record[0];
@@ -2466,7 +2639,7 @@
case DECL_OFFSET: {
if (F.LocalNumDecls != 0) {
Error("duplicate DECL_OFFSET record in AST file");
- return true;
+ return Failure;
}
F.DeclOffsets = (const DeclOffset *)Blob.data();
F.LocalNumDecls = Record[0];
@@ -2507,18 +2680,16 @@
unsigned Idx = 0;
serialization::DeclID ID = ReadDeclID(F, Record, Idx);
ASTDeclContextNameLookupTable *Table =
- ASTDeclContextNameLookupTable::Create(
- (const unsigned char *)Blob.data() + Record[Idx++],
- (const unsigned char *)Blob.data(),
- ASTDeclContextNameLookupTrait(*this, F));
- if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?
- DeclContext *TU = Context.getTranslationUnitDecl();
- F.DeclContextInfos[TU].NameLookupTableData = Table;
- TU->setHasExternalVisibleStorage(true);
- } else if (Decl *D = DeclsLoaded[ID - NUM_PREDEF_DECL_IDS]) {
+ ASTDeclContextNameLookupTable::Create(
+ (const unsigned char *)Blob.data() + Record[Idx++],
+ (const unsigned char *)Blob.data() + sizeof(uint32_t),
+ (const unsigned char *)Blob.data(),
+ ASTDeclContextNameLookupTrait(*this, F));
+ if (Decl *D = GetExistingDecl(ID)) {
auto *DC = cast<DeclContext>(D);
DC->getPrimaryContext()->setHasExternalVisibleStorage(true);
auto *&LookupTable = F.DeclContextInfos[DC].NameLookupTableData;
+ // FIXME: There should never be an existing lookup table.
delete LookupTable;
LookupTable = Table;
} else
@@ -2529,11 +2700,11 @@
case IDENTIFIER_TABLE:
F.IdentifierTableData = Blob.data();
if (Record[0]) {
- F.IdentifierLookupTable
- = ASTIdentifierLookupTable::Create(
- (const unsigned char *)F.IdentifierTableData + Record[0],
- (const unsigned char *)F.IdentifierTableData,
- ASTIdentifierLookupTrait(*this, F));
+ F.IdentifierLookupTable = ASTIdentifierLookupTable::Create(
+ (const unsigned char *)F.IdentifierTableData + Record[0],
+ (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t),
+ (const unsigned char *)F.IdentifierTableData,
+ ASTIdentifierLookupTrait(*this, F));
PP.getIdentifierTable().setExternalIdentifierLookup(this);
}
@@ -2542,7 +2713,7 @@
case IDENTIFIER_OFFSET: {
if (F.LocalNumIdentifiers != 0) {
Error("duplicate IDENTIFIER_OFFSET record in AST file");
- return true;
+ return Failure;
}
F.IdentifierOffsets = (const uint32_t *)Blob.data();
F.LocalNumIdentifiers = Record[0];
@@ -2581,7 +2752,7 @@
if (SpecialTypes.size() != Record.size()) {
Error("invalid special-types record");
- return true;
+ return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
@@ -2613,7 +2784,7 @@
case WEAK_UNDECLARED_IDENTIFIERS:
if (Record.size() % 4 != 0) {
Error("invalid weak identifiers record");
- return true;
+ return Failure;
}
// FIXME: Ignore weak undeclared identifiers from non-original PCH
@@ -2757,7 +2928,7 @@
ModuleFile *OM = ModuleMgr.lookup(Name);
if (!OM) {
Error("SourceLocation remap refers to unknown module");
- return true;
+ return Failure;
}
uint32_t SLocOffset =
@@ -2806,7 +2977,7 @@
case SOURCE_MANAGER_LINE_TABLE:
if (ParseLineTable(F, Record))
- return true;
+ return Failure;
break;
case SOURCE_LOCATION_PRELOADS: {
@@ -2814,7 +2985,7 @@
// which is based off F.SLocEntryBaseID.
if (!F.PreloadSLocEntries.empty()) {
Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
- return true;
+ return Failure;
}
F.PreloadSLocEntries.swap(Record);
@@ -2829,7 +3000,7 @@
case VTABLE_USES:
if (Record.size() % 3 != 0) {
Error("Invalid VTABLE_USES record");
- return true;
+ return Failure;
}
// Later tables overwrite earlier ones.
@@ -2853,12 +3024,12 @@
case PENDING_IMPLICIT_INSTANTIATIONS:
if (PendingInstantiations.size() % 2 != 0) {
Error("Invalid existing PendingInstantiations");
- return true;
+ return Failure;
}
if (Record.size() % 2 != 0) {
Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
- return true;
+ return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
@@ -2871,7 +3042,7 @@
case SEMA_DECL_REFS:
if (Record.size() != 2) {
Error("Invalid SEMA_DECL_REFS block");
- return true;
+ return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; ++I)
SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
@@ -2912,19 +3083,24 @@
case DECL_UPDATE_OFFSETS: {
if (Record.size() % 2 != 0) {
Error("invalid DECL_UPDATE_OFFSETS block in AST file");
- return true;
+ return Failure;
}
- // FIXME: If we've already loaded the decl, perform the updates now.
- for (unsigned I = 0, N = Record.size(); I != N; I += 2)
- DeclUpdateOffsets[getGlobalDeclID(F, Record[I])]
- .push_back(std::make_pair(&F, Record[I+1]));
+ for (unsigned I = 0, N = Record.size(); I != N; I += 2) {
+ GlobalDeclID ID = getGlobalDeclID(F, Record[I]);
+ DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1]));
+
+ // If we've already loaded the decl, perform the updates when we finish
+ // loading this block.
+ if (Decl *D = GetExistingDecl(ID))
+ PendingUpdateRecords.push_back(std::make_pair(ID, D));
+ }
break;
}
case DECL_REPLACEMENTS: {
if (Record.size() % 3 != 0) {
Error("invalid DECL_REPLACEMENTS block in AST file");
- return true;
+ return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; I += 3)
ReplacedDecls[getGlobalDeclID(F, Record[I])]
@@ -2935,7 +3111,7 @@
case OBJC_CATEGORIES_MAP: {
if (F.LocalNumObjCCategoriesInMap != 0) {
Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
- return true;
+ return Failure;
}
F.LocalNumObjCCategoriesInMap = Record[0];
@@ -2950,7 +3126,7 @@
case CXX_BASE_SPECIFIER_OFFSETS: {
if (F.LocalNumCXXBaseSpecifiers != 0) {
Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file");
- return true;
+ return Failure;
}
F.LocalNumCXXBaseSpecifiers = Record[0];
@@ -3017,12 +3193,12 @@
case UNDEFINED_BUT_USED:
if (UndefinedButUsed.size() % 2 != 0) {
Error("Invalid existing UndefinedButUsed");
- return true;
+ return Failure;
}
if (Record.size() % 2 != 0) {
Error("invalid undefined-but-used record");
- return true;
+ return Failure;
}
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++]));
@@ -3054,7 +3230,7 @@
case LOCAL_REDECLARATIONS_MAP: {
if (F.LocalNumRedeclarationsInMap != 0) {
Error("duplicate LOCAL_REDECLARATIONS_MAP record in AST file");
- return true;
+ return Failure;
}
F.LocalNumRedeclarationsInMap = Record[0];
@@ -3075,7 +3251,7 @@
case MACRO_OFFSET: {
if (F.LocalNumMacros != 0) {
Error("duplicate MACRO_OFFSET record in AST file");
- return true;
+ return Failure;
}
F.MacroOffsets = (const uint32_t *)Blob.data();
F.LocalNumMacros = Record[0];
@@ -3105,6 +3281,14 @@
LateParsedTemplates.append(Record.begin(), Record.end());
break;
}
+
+ case OPTIMIZE_PRAGMA_OPTIONS:
+ if (Record.size() != 1) {
+ Error("invalid pragma optimize record");
+ return Failure;
+ }
+ OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
+ break;
}
}
}
@@ -3263,13 +3447,16 @@
llvm::SaveAndRestore<SourceLocation>
SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
+ // Defer any pending actions until we get to the end of reading the AST file.
+ Deserializing AnASTFile(this);
+
// Bump the generation number.
- unsigned PreviousGeneration = CurrentGeneration++;
+ unsigned PreviousGeneration = incrementGeneration(Context);
unsigned NumModules = ModuleMgr.size();
SmallVector<ImportedModule, 4> Loaded;
switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
- /*ImportedBy=*/0, Loaded,
+ /*ImportedBy=*/nullptr, Loaded,
0, 0,
ClientLoadCapabilities)) {
case Failure:
@@ -3281,12 +3468,12 @@
ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
Context.getLangOpts().Modules
? &PP.getHeaderSearchInfo().getModuleMap()
- : 0);
+ : nullptr);
// If we find that any modules are unusable, the global index is going
// to be out-of-date. Just remove it.
GlobalIndex.reset();
- ModuleMgr.setGlobalIndex(0);
+ ModuleMgr.setGlobalIndex(nullptr);
return ReadResult;
case Success:
@@ -3302,8 +3489,8 @@
ModuleFile &F = *M->Mod;
// Read the AST block.
- if (ReadASTBlock(F))
- return Failure;
+ if (ASTReadResult Result = ReadASTBlock(F, ClientLoadCapabilities))
+ return Result;
// Once read, set the ModuleFile bit base offset and update the size in
// bits of all files we've seen.
@@ -3444,7 +3631,7 @@
std::string ErrorStr;
ModuleManager::AddModuleResult AddResult
= ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,
- CurrentGeneration, ExpectedSize, ExpectedModTime,
+ getGeneration(), ExpectedSize, ExpectedModTime,
M, ErrorStr);
switch (AddResult) {
@@ -3534,7 +3721,7 @@
break;
case CONTROL_BLOCK_ID:
HaveReadControlBlock = true;
- switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {
+ switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) {
case Success:
break;
@@ -3575,11 +3762,6 @@
DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID,
Context.getTranslationUnitDecl());
- // Make sure we load the declaration update records for the translation unit,
- // if there are any.
- loadDeclUpdateRecords(PREDEF_DECL_TRANSLATION_UNIT_ID,
- Context.getTranslationUnitDecl());
-
// FIXME: Find a better way to deal with collisions between these
// built-in types. Right now, we just ignore the problem.
@@ -3824,16 +4006,16 @@
bool ReadLanguageOptions(const LangOptions &LangOpts,
bool Complain) override {
- return checkLanguageOptions(ExistingLangOpts, LangOpts, 0);
+ return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr);
}
bool ReadTargetOptions(const TargetOptions &TargetOpts,
bool Complain) override {
- return checkTargetOptions(ExistingTargetOpts, TargetOpts, 0);
+ return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr);
}
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool Complain,
std::string &SuggestedPredefines) override {
- return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr,
+ return checkPreprocessorOptions(ExistingPPOpts, PPOpts, nullptr, FileMgr,
SuggestedPredefines, ExistingLangOpts);
}
};
@@ -3914,6 +4096,12 @@
break;
}
+ case MODULE_NAME:
+ Listener.ReadModuleName(Blob);
+ break;
+ case MODULE_MAP_FILE:
+ Listener.ReadModuleMapFile(Blob);
+ break;
case LANGUAGE_OPTIONS:
if (ParseLanguageOptions(Record, false, Listener))
return true;
@@ -3998,16 +4186,17 @@
return !readASTFileControlBlock(Filename, FileMgr, validator);
}
-bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
+ASTReader::ASTReadResult
+ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// Enter the submodule block.
if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
Error("malformed submodule block record in AST file");
- return true;
+ return Failure;
}
ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
bool First = true;
- Module *CurrentModule = 0;
+ Module *CurrentModule = nullptr;
RecordData Record;
while (true) {
llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
@@ -4016,9 +4205,9 @@
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
case llvm::BitstreamEntry::Error:
Error("malformed block record in AST file");
- return true;
+ return Failure;
case llvm::BitstreamEntry::EndBlock:
- return false;
+ return Success;
case llvm::BitstreamEntry::Record:
// The interesting case.
break;
@@ -4034,12 +4223,12 @@
case SUBMODULE_DEFINITION: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (Record.size() < 8) {
Error("malformed module definition");
- return true;
+ return Failure;
}
StringRef Name = Blob;
@@ -4055,20 +4244,26 @@
bool InferExportWildcard = Record[Idx++];
bool ConfigMacrosExhaustive = Record[Idx++];
- Module *ParentModule = 0;
- if (Parent)
+ Module *ParentModule = nullptr;
+ const FileEntry *ModuleMap = nullptr;
+ if (Parent) {
ParentModule = getSubmodule(Parent);
-
+ ModuleMap = ParentModule->ModuleMap;
+ }
+
+ if (!F.ModuleMapPath.empty())
+ ModuleMap = FileMgr.getFile(F.ModuleMapPath);
+
// Retrieve this (sub)module from the module map, creating it if
// necessary.
- CurrentModule = ModMap.findOrCreateModule(Name, ParentModule,
+ CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, ModuleMap,
IsFramework,
IsExplicit).first;
SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
if (GlobalIndex >= SubmodulesLoaded.size() ||
SubmodulesLoaded[GlobalIndex]) {
Error("too many submodules");
- return true;
+ return Failure;
}
if (!ParentModule) {
@@ -4080,13 +4275,13 @@
<< CurFile->getName()
<< F.File->getName();
}
- return true;
+ return Failure;
}
}
CurrentModule->setASTFile(F.File);
}
-
+
CurrentModule->IsFromModuleFile = true;
CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
CurrentModule->IsExternC = IsExternC;
@@ -4110,7 +4305,7 @@
case SUBMODULE_UMBRELLA_HEADER: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4120,8 +4315,9 @@
if (!CurrentModule->getUmbrellaHeader())
ModMap.setUmbrellaHeader(CurrentModule, Umbrella);
else if (CurrentModule->getUmbrellaHeader() != Umbrella) {
- Error("mismatched umbrella headers in submodule");
- return true;
+ if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+ Error("mismatched umbrella headers in submodule");
+ return OutOfDate;
}
}
break;
@@ -4130,7 +4326,7 @@
case SUBMODULE_HEADER: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4145,7 +4341,7 @@
case SUBMODULE_EXCLUDED_HEADER: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4160,7 +4356,7 @@
case SUBMODULE_PRIVATE_HEADER: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4175,7 +4371,7 @@
case SUBMODULE_TOPHEADER: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4188,7 +4384,7 @@
case SUBMODULE_UMBRELLA_DIR: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4199,8 +4395,9 @@
if (!CurrentModule->getUmbrellaDir())
ModMap.setUmbrellaDir(CurrentModule, Umbrella);
else if (CurrentModule->getUmbrellaDir() != Umbrella) {
- Error("mismatched umbrella directories in submodule");
- return true;
+ if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+ Error("mismatched umbrella directories in submodule");
+ return OutOfDate;
}
}
break;
@@ -4209,7 +4406,7 @@
case SUBMODULE_METADATA: {
if (!First) {
Error("submodule metadata record not at beginning of block");
- return true;
+ return Failure;
}
First = false;
@@ -4235,7 +4432,7 @@
case SUBMODULE_IMPORTS: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4256,7 +4453,7 @@
case SUBMODULE_EXPORTS: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4280,7 +4477,7 @@
case SUBMODULE_REQUIRES: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4294,7 +4491,7 @@
case SUBMODULE_LINK_LIBRARY:
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4307,7 +4504,7 @@
case SUBMODULE_CONFIG_MACRO:
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4319,7 +4516,7 @@
case SUBMODULE_CONFLICT: {
if (First) {
Error("missing submodule metadata record at beginning of block");
- return true;
+ return Failure;
}
if (!CurrentModule)
@@ -4387,7 +4584,6 @@
TargetOpts.Triple = ReadString(Record, Idx);
TargetOpts.CPU = ReadString(Record, Idx);
TargetOpts.ABI = ReadString(Record, Idx);
- TargetOpts.LinkerVersion = ReadString(Record, Idx);
for (unsigned N = Record[Idx++]; N; --N) {
TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
}
@@ -4400,15 +4596,15 @@
bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener) {
- DiagnosticOptions DiagOpts;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
+#define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
- DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
+ DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
#include "clang/Basic/DiagnosticOptions.def"
for (unsigned N = Record[Idx++]; N; --N) {
- DiagOpts.Warnings.push_back(ReadString(Record, Idx));
+ DiagOpts->Warnings.push_back(ReadString(Record, Idx));
}
return Listener.ReadDiagnosticOptions(DiagOpts, Complain);
@@ -4532,7 +4728,7 @@
if (!PP.getPreprocessingRecord()) {
Error("no preprocessing record");
- return 0;
+ return nullptr;
}
SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
@@ -4541,7 +4737,7 @@
llvm::BitstreamEntry Entry =
M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
if (Entry.Kind != llvm::BitstreamEntry::Record)
- return 0;
+ return nullptr;
// Read the record.
SourceRange Range(ReadSourceLocation(M, PPOffs.Begin),
@@ -4555,8 +4751,8 @@
switch (RecType) {
case PPD_MACRO_EXPANSION: {
bool isBuiltin = Record[0];
- IdentifierInfo *Name = 0;
- MacroDefinition *Def = 0;
+ IdentifierInfo *Name = nullptr;
+ MacroDefinition *Def = nullptr;
if (isBuiltin)
Name = getLocalIdentifier(M, Record[1]);
else {
@@ -4590,7 +4786,7 @@
case PPD_INCLUSION_DIRECTIVE: {
const char *FullFileNameStart = Blob.data() + Record[0];
StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
- const FileEntry *File = 0;
+ const FileEntry *File = nullptr;
if (!FullFileName.empty())
File = PP.getFileManager().getFile(FullFileName);
@@ -4659,15 +4855,13 @@
}
-/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.
-PreprocessedEntityID
-ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
- if (SourceMgr.isLocalSourceLocation(BLoc))
+PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
+ bool EndsAfter) const {
+ if (SourceMgr.isLocalSourceLocation(Loc))
return getTotalNumPreprocessedEntities();
- GlobalSLocOffsetMapType::const_iterator
- SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
- BLoc.getOffset() - 1);
+ GlobalSLocOffsetMapType::const_iterator SLocMapI = GlobalSLocOffsetMap.find(
+ SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
assert(SLocMapI != GlobalSLocOffsetMap.end() &&
"Corrupted global sloc offset map");
@@ -4684,21 +4878,26 @@
pp_iterator First = pp_begin;
pp_iterator PPI;
- // Do a binary search manually instead of using std::lower_bound because
- // The end locations of entities may be unordered (when a macro expansion
- // is inside another macro argument), but for this case it is not important
- // whether we get the first macro expansion or its containing macro.
- while (Count > 0) {
- Half = Count/2;
- PPI = First;
- std::advance(PPI, Half);
- if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
- BLoc)){
- First = PPI;
- ++First;
- Count = Count - Half - 1;
- } else
- Count = Half;
+ if (EndsAfter) {
+ PPI = std::upper_bound(pp_begin, pp_end, Loc,
+ PPEntityComp<&PPEntityOffset::Begin>(*this, M));
+ } else {
+ // Do a binary search manually instead of using std::lower_bound because
+ // The end locations of entities may be unordered (when a macro expansion
+ // is inside another macro argument), but for this case it is not important
+ // whether we get the first macro expansion or its containing macro.
+ while (Count > 0) {
+ Half = Count / 2;
+ PPI = First;
+ std::advance(PPI, Half);
+ if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
+ Loc)) {
+ First = PPI;
+ ++First;
+ Count = Count - Half - 1;
+ } else
+ Count = Half;
+ }
}
if (PPI == pp_end)
@@ -4707,35 +4906,6 @@
return M.BasePreprocessedEntityID + (PPI - pp_begin);
}
-/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.
-PreprocessedEntityID
-ASTReader::findEndPreprocessedEntity(SourceLocation ELoc) const {
- if (SourceMgr.isLocalSourceLocation(ELoc))
- return getTotalNumPreprocessedEntities();
-
- GlobalSLocOffsetMapType::const_iterator
- SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
- ELoc.getOffset() - 1);
- assert(SLocMapI != GlobalSLocOffsetMap.end() &&
- "Corrupted global sloc offset map");
-
- if (SLocMapI->second->NumPreprocessedEntities == 0)
- return findNextPreprocessedEntity(SLocMapI);
-
- ModuleFile &M = *SLocMapI->second;
- typedef const PPEntityOffset *pp_iterator;
- pp_iterator pp_begin = M.PreprocessedEntityOffsets;
- pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
- pp_iterator PPI =
- std::upper_bound(pp_begin, pp_end, ELoc,
- PPEntityComp<&PPEntityOffset::Begin>(*this, M));
-
- if (PPI == pp_end)
- return findNextPreprocessedEntity(SLocMapI);
-
- return M.BasePreprocessedEntityID + (PPI - pp_begin);
-}
-
/// \brief Returns a pair of [Begin, End) indices of preallocated
/// preprocessed entities that \arg Range encompasses.
std::pair<unsigned, unsigned>
@@ -4744,8 +4914,9 @@
return std::make_pair(0,0);
assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
- PreprocessedEntityID BeginID = findBeginPreprocessedEntity(Range.getBegin());
- PreprocessedEntityID EndID = findEndPreprocessedEntity(Range.getEnd());
+ PreprocessedEntityID BeginID =
+ findPreprocessedEntity(Range.getBegin(), false);
+ PreprocessedEntityID EndID = findPreprocessedEntity(Range.getEnd(), true);
return std::make_pair(BeginID, EndID);
}
@@ -5234,8 +5405,14 @@
QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
// FIXME: ASTContext::getInjectedClassNameType is not currently suitable
// for AST reading, too much interdependencies.
- return
- QualType(new (Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
+ const Type *T;
+ if (const Type *Existing = D->getTypeForDecl())
+ T = Existing;
+ else if (auto *Prev = D->getPreviousDecl())
+ T = Prev->getTypeForDecl();
+ else
+ T = new (Context, TypeAlignment) InjectedClassNameType(D, TST);
+ return QualType(T, 0);
}
case TYPE_TEMPLATE_TYPE_PARM: {
@@ -5420,7 +5597,7 @@
if (Record[Idx++])
TL.setSizeExpr(Reader.ReadExpr(F));
else
- TL.setSizeExpr(0);
+ TL.setSizeExpr(nullptr);
}
void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
VisitArrayTypeLoc(TL);
@@ -5507,7 +5684,7 @@
if (Record[Idx++])
TL.setAttrExprOperand(Reader.ReadExpr(F));
else
- TL.setAttrExprOperand(0);
+ TL.setAttrExprOperand(nullptr);
} else if (TL.hasAttrEnumOperand())
TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx));
}
@@ -5591,7 +5768,7 @@
unsigned &Idx) {
QualType InfoTy = readType(F, Record, Idx);
if (InfoTy.isNull())
- return 0;
+ return nullptr;
TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
TypeLocReader TLR(*this, F, Record, Idx);
@@ -5778,11 +5955,54 @@
return GetDecl(ID);
}
-uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
- unsigned &Idx){
- if (Idx >= Record.size())
+void ASTReader::CompleteRedeclChain(const Decl *D) {
+ if (NumCurrentElementsDeserializing) {
+ // We arrange to not care about the complete redeclaration chain while we're
+ // deserializing. Just remember that the AST has marked this one as complete
+ // but that it's not actually complete yet, so we know we still need to
+ // complete it later.
+ PendingIncompleteDeclChains.push_back(const_cast<Decl*>(D));
+ return;
+ }
+
+ const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+
+ // Recursively ensure that the decl context itself is complete
+ // (in particular, this matters if the decl context is a namespace).
+ //
+ // FIXME: This should be performed by lookup instead of here.
+ cast<Decl>(DC)->getMostRecentDecl();
+
+ // If this is a named declaration, complete it by looking it up
+ // within its context.
+ //
+ // FIXME: We don't currently handle the cases where we can't do this;
+ // merging a class definition that contains unnamed entities should merge
+ // those entities. Likewise, merging a function definition should merge
+ // all mergeable entities within it.
+ if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
+ isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
+ if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
+ auto *II = Name.getAsIdentifierInfo();
+ if (isa<TranslationUnitDecl>(DC) && II) {
+ // Outside of C++, we don't have a lookup table for the TU, so update
+ // the identifier instead. In C++, either way should work fine.
+ if (II->isOutOfDate())
+ updateOutOfDateIdentifier(*II);
+ } else
+ DC->lookup(Name);
+ }
+ }
+}
+
+uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M,
+ const RecordData &Record,
+ unsigned &Idx) {
+ if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXBaseSpecifiers) {
+ Error("malformed AST file: missing C++ base specifier");
return 0;
-
+ }
+
unsigned LocalID = Record[Idx++];
return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);
}
@@ -5797,8 +6017,8 @@
unsigned Code = Cursor.ReadCode();
unsigned RecCode = Cursor.readRecord(Code, Record);
if (RecCode != DECL_CXX_BASE_SPECIFIERS) {
- Error("Malformed AST file: missing C++ base specifiers");
- return 0;
+ Error("malformed AST file: missing C++ base specifiers");
+ return nullptr;
}
unsigned Idx = 0;
@@ -5831,7 +6051,7 @@
ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
if (!D->isFromASTFile())
- return 0;
+ return nullptr;
GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
return I->second;
@@ -5840,14 +6060,14 @@
SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
if (ID < NUM_PREDEF_DECL_IDS)
return SourceLocation();
-
+
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
if (Index > DeclsLoaded.size()) {
Error("declaration ID out-of-range for AST file");
return SourceLocation();
}
-
+
if (Decl *D = DeclsLoaded[Index])
return D->getLocation();
@@ -5856,15 +6076,15 @@
return ReadSourceLocation(*Rec.F, RawLocation);
}
-Decl *ASTReader::GetDecl(DeclID ID) {
- if (ID < NUM_PREDEF_DECL_IDS) {
+Decl *ASTReader::GetExistingDecl(DeclID ID) {
+ if (ID < NUM_PREDEF_DECL_IDS) {
switch ((PredefinedDeclIDs)ID) {
case PREDEF_DECL_NULL_ID:
- return 0;
-
+ return nullptr;
+
case PREDEF_DECL_TRANSLATION_UNIT_ID:
return Context.getTranslationUnitDecl();
-
+
case PREDEF_DECL_OBJC_ID_ID:
return Context.getObjCIdDecl();
@@ -5873,16 +6093,16 @@
case PREDEF_DECL_OBJC_CLASS_ID:
return Context.getObjCClassDecl();
-
+
case PREDEF_DECL_OBJC_PROTOCOL_ID:
return Context.getObjCProtocolDecl();
-
+
case PREDEF_DECL_INT_128_ID:
return Context.getInt128Decl();
case PREDEF_DECL_UNSIGNED_INT_128_ID:
return Context.getUInt128Decl();
-
+
case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
return Context.getObjCInstanceTypeDecl();
@@ -5890,15 +6110,30 @@
return Context.getBuiltinVaListDecl();
}
}
-
+
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
if (Index >= DeclsLoaded.size()) {
assert(0 && "declaration ID out-of-range for AST file");
Error("declaration ID out-of-range for AST file");
- return 0;
+ return nullptr;
}
-
+
+ return DeclsLoaded[Index];
+}
+
+Decl *ASTReader::GetDecl(DeclID ID) {
+ if (ID < NUM_PREDEF_DECL_IDS)
+ return GetExistingDecl(ID);
+
+ unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+
+ if (Index >= DeclsLoaded.size()) {
+ assert(0 && "declaration ID out-of-range for AST file");
+ Error("declaration ID out-of-range for AST file");
+ return nullptr;
+ }
+
if (!DeclsLoaded[Index]) {
ReadDeclRecord(ID);
if (DeserializationListener)
@@ -6183,7 +6418,7 @@
if (const DeclContext *DefDC = getDefinitiveDeclContext(DC))
return Reader.getOwningModuleFile(cast<Decl>(DefDC));
- return 0;
+ return nullptr;
}
bool
@@ -6204,14 +6439,19 @@
Contexts.push_back(DC);
if (DC->isNamespace()) {
- MergedDeclsMap::iterator Merged
- = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
+ auto Merged = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
if (Merged != MergedDecls.end()) {
for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
}
}
-
+ if (isa<CXXRecordDecl>(DC)) {
+ auto Merged = MergedLookups.find(DC);
+ if (Merged != MergedLookups.end())
+ Contexts.insert(Contexts.end(), Merged->second.begin(),
+ Merged->second.end());
+ }
+
DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls);
// If we can definitively determine which module file to look into,
@@ -6384,15 +6624,15 @@
QualType());
unsigned NumDeclsLoaded
= DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
- (Decl *)0);
+ (Decl *)nullptr);
unsigned NumIdentifiersLoaded
= IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
IdentifiersLoaded.end(),
- (IdentifierInfo *)0);
+ (IdentifierInfo *)nullptr);
unsigned NumMacrosLoaded
= MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
MacrosLoaded.end(),
- (MacroInfo *)0);
+ (MacroInfo *)nullptr);
unsigned NumSelectorsLoaded
= SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
SelectorsLoaded.end(),
@@ -6576,6 +6816,11 @@
}
SemaDeclRefs.clear();
}
+
+ // Update the state of 'pragma clang optimize'. Use the same API as if we had
+ // encountered the pragma in the source.
+ if(OptimizeOffPragmaLocation.isValid())
+ SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation);
}
IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
@@ -6586,7 +6831,7 @@
// If there is a global index, look there first to determine which modules
// provably do not have any results for this identifier.
GlobalModuleIndex::HitSet Hits;
- GlobalModuleIndex::HitSet *HitsPtr = 0;
+ GlobalModuleIndex::HitSet *HitsPtr = nullptr;
if (!loadGlobalIndex()) {
if (GlobalIndex->lookupIdentifier(Name, Hits)) {
HitsPtr = &Hits;
@@ -6742,7 +6987,7 @@
// Get the selector generation and update it to the current generation.
unsigned &Generation = SelectorGeneration[Sel];
unsigned PriorGeneration = Generation;
- Generation = CurrentGeneration;
+ Generation = getGeneration();
// Search for methods defined with this selector.
++NumMethodPoolLookups;
@@ -6999,11 +7244,11 @@
IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
if (ID == 0)
- return 0;
+ return nullptr;
if (IdentifiersLoaded.empty()) {
Error("no identifier table in AST file");
- return 0;
+ return nullptr;
}
ID -= 1;
@@ -7049,11 +7294,11 @@
MacroInfo *ASTReader::getMacro(MacroID ID) {
if (ID == 0)
- return 0;
+ return nullptr;
if (MacrosLoaded.empty()) {
Error("no macro table in AST file");
- return 0;
+ return nullptr;
}
ID -= NUM_PREDEF_MACRO_IDS;
@@ -7100,12 +7345,12 @@
Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {
if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {
assert(GlobalID == 0 && "Unhandled global submodule ID");
- return 0;
+ return nullptr;
}
if (GlobalID > SubmodulesLoaded.size()) {
Error("submodule ID out of range in AST file");
- return 0;
+ return nullptr;
}
return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
@@ -7128,7 +7373,7 @@
return Selector();
}
- if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
+ if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == nullptr) {
// Load this selector from the selector table.
GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);
assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");
@@ -7424,16 +7669,16 @@
std::pair<CXXCtorInitializer **, unsigned>
ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
unsigned &Idx) {
- CXXCtorInitializer **CtorInitializers = 0;
+ CXXCtorInitializer **CtorInitializers = nullptr;
unsigned NumInitializers = Record[Idx++];
if (NumInitializers) {
CtorInitializers
= new (Context) CXXCtorInitializer*[NumInitializers];
for (unsigned i=0; i != NumInitializers; ++i) {
- TypeSourceInfo *TInfo = 0;
+ TypeSourceInfo *TInfo = nullptr;
bool IsBaseVirtual = false;
- FieldDecl *Member = 0;
- IndirectFieldDecl *IndirectMember = 0;
+ FieldDecl *Member = nullptr;
+ IndirectFieldDecl *IndirectMember = nullptr;
CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
switch (Type) {
@@ -7513,7 +7758,7 @@
ASTReader::ReadNestedNameSpecifier(ModuleFile &F,
const RecordData &Record, unsigned &Idx) {
unsigned N = Record[Idx++];
- NestedNameSpecifier *NNS = 0, *Prev = 0;
+ NestedNameSpecifier *NNS = nullptr, *Prev = nullptr;
for (unsigned I = 0; I != N; ++I) {
NestedNameSpecifier::SpecifierKind Kind
= (NestedNameSpecifier::SpecifierKind)Record[Idx++];
@@ -7540,8 +7785,8 @@
case NestedNameSpecifier::TypeSpecWithTemplate: {
const Type *T = readType(F, Record, Idx).getTypePtrOrNull();
if (!T)
- return 0;
-
+ return nullptr;
+
bool Template = Record[Idx++];
NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);
break;
@@ -7688,14 +7933,14 @@
/// \brief Record that the given ID maps to the given switch-case
/// statement.
void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
- assert((*CurrSwitchCaseStmts)[ID] == 0 &&
+ assert((*CurrSwitchCaseStmts)[ID] == nullptr &&
"Already have a SwitchCase with this ID");
(*CurrSwitchCaseStmts)[ID] = SC;
}
/// \brief Retrieve the switch-case statement with the given ID.
SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
- assert((*CurrSwitchCaseStmts)[ID] != 0 && "No SwitchCase with this ID");
+ assert((*CurrSwitchCaseStmts)[ID] != nullptr && "No SwitchCase with this ID");
return (*CurrSwitchCaseStmts)[ID];
}
@@ -7754,10 +7999,24 @@
}
}
+std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
+ // If we know the owning module, use it.
+ if (Module *M = D->getOwningModule())
+ return M->getFullModuleName();
+
+ // Otherwise, use the name of the top-level module the decl is within.
+ if (ModuleFile *M = getOwningModuleFile(D))
+ return M->ModuleName;
+
+ // Not from a module.
+ return "";
+}
+
void ASTReader::finishPendingActions() {
- while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() ||
+ while (!PendingIdentifierInfos.empty() ||
+ !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
!PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
- !PendingOdrMergeChecks.empty()) {
+ !PendingUpdateRecords.empty() || !PendingOdrMergeChecks.empty()) {
// If any identifiers with corresponding top-level declarations have
// been loaded, load those declarations now.
typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> >
@@ -7773,6 +8032,13 @@
SetGloballyVisibleDecls(II, DeclIDs, &TopLevelDecls[II]);
}
+ // For each decl chain that we wanted to complete while deserializing, mark
+ // it as "still needs to be completed".
+ for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) {
+ markIncompleteDeclChain(PendingIncompleteDeclChains[I]);
+ }
+ PendingIncompleteDeclChains.clear();
+
// Load pending declaration chains.
for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
loadPendingDeclChain(PendingDeclChains[I]);
@@ -7821,6 +8087,27 @@
Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext());
}
+ // Perform any pending declaration updates.
+ while (!PendingUpdateRecords.empty()) {
+ auto Update = PendingUpdateRecords.pop_back_val();
+ ReadingKindTracker ReadingKind(Read_Decl, *this);
+ loadDeclUpdateRecords(Update.first, Update.second);
+ }
+
+ // Trigger the import of the full definition of each class that had any
+ // odr-merging problems, so we can produce better diagnostics for them.
+ for (auto &Merge : PendingOdrMergeFailures) {
+ Merge.first->buildLookup();
+ Merge.first->decls_begin();
+ Merge.first->bases_begin();
+ Merge.first->vbases_begin();
+ for (auto *RD : Merge.second) {
+ RD->decls_begin();
+ RD->bases_begin();
+ RD->vbases_begin();
+ }
+ }
+
// For each declaration from a merged context, check that the canonical
// definition of that context also contains a declaration of the same
// entity.
@@ -7859,11 +8146,11 @@
if (!Found) {
D->setInvalidDecl();
- Module *CanonDefModule = cast<Decl>(CanonDef)->getOwningModule();
+ std::string CanonDefModule =
+ getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef));
Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl)
- << D << D->getOwningModule()->getFullModuleName()
- << CanonDef << !CanonDefModule
- << (CanonDefModule ? CanonDefModule->getFullModuleName() : "");
+ << D << getOwningModuleNameForDiagnostic(D)
+ << CanonDef << CanonDefModule.empty() << CanonDefModule;
if (Candidates.empty())
Diag(cast<Decl>(CanonDef)->getLocation(),
@@ -7874,6 +8161,8 @@
diag::note_module_odr_violation_possible_decl)
<< Candidates[I];
}
+
+ DiagnosedOdrMergeFailures.insert(CanonDef);
}
}
}
@@ -7886,7 +8175,7 @@
DEnd = PendingDefinitions.end();
D != DEnd; ++D) {
if (TagDecl *TD = dyn_cast<TagDecl>(*D)) {
- if (const TagType *TagT = dyn_cast<TagType>(TD->TypeForDecl)) {
+ if (const TagType *TagT = dyn_cast<TagType>(TD->getTypeForDecl())) {
// Make sure that the TagType points at the definition.
const_cast<TagType*>(TagT)->decl = TD;
}
@@ -7894,7 +8183,6 @@
if (auto RD = dyn_cast<CXXRecordDecl>(*D)) {
for (auto R : RD->redecls())
cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData;
-
}
continue;
@@ -7943,6 +8231,46 @@
MD->setLazyBody(PB->second);
}
PendingBodies.clear();
+
+ // Issue any pending ODR-failure diagnostics.
+ for (auto &Merge : PendingOdrMergeFailures) {
+ if (!DiagnosedOdrMergeFailures.insert(Merge.first))
+ continue;
+
+ bool Diagnosed = false;
+ for (auto *RD : Merge.second) {
+ // Multiple different declarations got merged together; tell the user
+ // where they came from.
+ if (Merge.first != RD) {
+ // FIXME: Walk the definition, figure out what's different,
+ // and diagnose that.
+ if (!Diagnosed) {
+ std::string Module = getOwningModuleNameForDiagnostic(Merge.first);
+ Diag(Merge.first->getLocation(),
+ diag::err_module_odr_violation_different_definitions)
+ << Merge.first << Module.empty() << Module;
+ Diagnosed = true;
+ }
+
+ Diag(RD->getLocation(),
+ diag::note_module_odr_violation_different_definitions)
+ << getOwningModuleNameForDiagnostic(RD);
+ }
+ }
+
+ if (!Diagnosed) {
+ // All definitions are updates to the same declaration. This happens if a
+ // module instantiates the declaration of a class template specialization
+ // and two or more other modules instantiate its definition.
+ //
+ // FIXME: Indicate which modules had instantiations of this definition.
+ // FIXME: How can this even happen?
+ Diag(Merge.first->getLocation(),
+ diag::err_module_odr_violation_different_instantiations)
+ << Merge.first;
+ }
+ }
+ PendingOdrMergeFailures.clear();
}
void ASTReader::FinishedDeserializing() {
@@ -7977,39 +8305,39 @@
}
}
-ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
- StringRef isysroot, bool DisableValidation,
- bool AllowASTWithCompilerErrors,
- bool AllowConfigurationMismatch,
- bool ValidateSystemInputs,
+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot,
+ bool DisableValidation, bool AllowASTWithCompilerErrors,
+ bool AllowConfigurationMismatch, bool ValidateSystemInputs,
bool UseGlobalIndex)
- : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
- SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
- Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
- Consumer(0), ModuleMgr(PP.getFileManager()),
- isysroot(isysroot), DisableValidation(DisableValidation),
- AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
- AllowConfigurationMismatch(AllowConfigurationMismatch),
- ValidateSystemInputs(ValidateSystemInputs),
- UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
- CurrentGeneration(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),
- NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
- NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
- TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
- PassingDeclsToConsumer(false),
- NumCXXBaseSpecifiersLoaded(0), ReadingKind(Read_None)
-{
+ : 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),
+ 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),
+ NumMethodPoolEntriesRead(0), NumMethodPoolLookups(0),
+ NumMethodPoolHits(0), NumMethodPoolTableLookups(0),
+ NumMethodPoolTableHits(0), TotalNumMethodPoolEntries(0),
+ NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
+ NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
+ TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0),
+ PassingDeclsToConsumer(false), NumCXXBaseSpecifiersLoaded(0),
+ ReadingKind(Read_None) {
SourceMgr.setExternalSLocEntrySource(this);
}
ASTReader::~ASTReader() {
+ if (OwnsDeserializationListener)
+ delete DeserializationListener;
+
for (DeclContextVisibleUpdatesPending::iterator
I = PendingVisibleUpdates.begin(),
E = PendingVisibleUpdates.end();