aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Serialization
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-04-14 21:41:27 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-06-22 18:20:56 +0000
commitbdd1243df58e60e85101c09001d9812a789b6bc4 (patch)
treea1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/clang/lib/Serialization
parent781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff)
parente3b557809604d036af6e00c60f012c2025b59a5e (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Serialization')
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp2217
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp386
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp88
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp500
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp181
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp63
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp21
8 files changed, 1205 insertions, 2258 deletions
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
index 26b722b6b14a..96bc47dcdb4e 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
@@ -412,6 +412,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::PragmaComment:
case Decl::PragmaDetectMismatch:
case Decl::FileScopeAsm:
+ case Decl::TopLevelStmt:
case Decl::AccessSpec:
case Decl::Friend:
case Decl::FriendTemplate:
@@ -430,9 +431,11 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::Decomposition:
case Decl::Binding:
case Decl::Concept:
+ case Decl::ImplicitConceptSpecialization:
case Decl::LifetimeExtendedTemporary:
case Decl::RequiresExprBody:
case Decl::UnresolvedUsingIfExists:
+ case Decl::HLSLBuffer:
return false;
// These indirectly derive from Redeclarable<T> but are not actually
@@ -472,7 +475,7 @@ bool serialization::needsAnonymousDeclarationNumber(const NamedDecl *D) {
if (auto *VD = dyn_cast<VarDecl>(D))
return VD->isStaticLocal();
// FIXME: What about CapturedDecls (and declarations nested within them)?
- return isa<TagDecl>(D) || isa<BlockDecl>(D);
+ return isa<TagDecl, BlockDecl>(D);
}
// Otherwise, we only care about anonymous class members / block-scope decls.
@@ -482,5 +485,5 @@ bool serialization::needsAnonymousDeclarationNumber(const NamedDecl *D) {
return false;
if (!isa<RecordDecl, ObjCInterfaceDecl>(D->getLexicalDeclContext()))
return false;
- return isa<TagDecl>(D) || isa<FieldDecl>(D);
+ return isa<TagDecl, FieldDecl>(D);
}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
index d1e47c1045de..4d72596b7439 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
@@ -30,6 +30,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/ODRDiagsEmitter.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/RawCommentList.h"
@@ -96,8 +97,6 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -121,6 +120,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
@@ -134,6 +134,7 @@
#include <limits>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <system_error>
#include <tuple>
@@ -1223,7 +1224,7 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
auto &Lex = LexicalDecls[DC];
if (!Lex.first) {
Lex = std::make_pair(
- &M, llvm::makeArrayRef(
+ &M, llvm::ArrayRef(
reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
Blob.data()),
Blob.size() / 4));
@@ -1301,10 +1302,10 @@ void ASTReader::Error(llvm::Error &&Err) const {
switch (NumArgs) {
case 3:
Arg3 = Diag.getStringArg(2);
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case 2:
Arg2 = Diag.getStringArg(1);
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case 1:
Arg1 = Diag.getStringArg(0);
}
@@ -1336,10 +1337,7 @@ void ASTReader::ParseLineTable(ModuleFile &F, const RecordData &Record) {
// Parse the line entries
std::vector<LineEntry> Entries;
while (Idx < Record.size()) {
- int FID = Record[Idx++];
- assert(FID >= 0 && "Serialized line entries for non-local file.");
- // Remap FileID from 1-based old view.
- FID += F.SLocEntryBaseID - 1;
+ FileID FID = ReadFileID(F, Record, Idx);
// Extract the line entries
unsigned NumEntries = Record[Idx++];
@@ -1356,7 +1354,7 @@ void ASTReader::ParseLineTable(ModuleFile &F, const RecordData &Record) {
Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
FileKind, IncludeOffset));
}
- LineTable.AddEntry(FileID::get(FID), Entries);
+ LineTable.AddEntry(FID, Entries);
}
}
@@ -1421,41 +1419,6 @@ llvm::Error ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
}
}
-/// If a header file is not found at the path that we expect it to be
-/// and the PCH file was moved from its original location, try to resolve the
-/// file by assuming that header+PCH were moved together and the header is in
-/// the same place relative to the PCH.
-static std::string
-resolveFileRelativeToOriginalDir(const std::string &Filename,
- const std::string &OriginalDir,
- const std::string &CurrDir) {
- assert(OriginalDir != CurrDir &&
- "No point trying to resolve the file if the PCH dir didn't change");
-
- using namespace llvm::sys;
-
- SmallString<128> filePath(Filename);
- fs::make_absolute(filePath);
- assert(path::is_absolute(OriginalDir));
- SmallString<128> currPCHPath(CurrDir);
-
- path::const_iterator fileDirI = path::begin(path::parent_path(filePath)),
- fileDirE = path::end(path::parent_path(filePath));
- path::const_iterator origDirI = path::begin(OriginalDir),
- origDirE = path::end(OriginalDir);
- // Skip the common path components from filePath and OriginalDir.
- while (fileDirI != fileDirE && origDirI != origDirE &&
- *fileDirI == *origDirI) {
- ++fileDirI;
- ++origDirI;
- }
- for (; origDirI != origDirE; ++origDirI)
- path::append(currPCHPath, "..");
- path::append(currPCHPath, fileDirI, fileDirE);
- path::append(currPCHPath, path::filename(Filename));
- return std::string(currPCHPath.str());
-}
-
bool ASTReader::ReadSLocEntry(int ID) {
if (ID == 0)
return false;
@@ -1488,19 +1451,25 @@ bool ASTReader::ReadSLocEntry(int ID) {
unsigned RecCode = MaybeRecCode.get();
if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
- if (!llvm::compression::zlib::isAvailable()) {
- Error("zlib is not available");
+ // Inspect the first byte to differentiate zlib (\x78) and zstd
+ // (little-endian 0xFD2FB528).
+ const llvm::compression::Format F =
+ Blob.size() > 0 && Blob.data()[0] == 0x78
+ ? llvm::compression::Format::Zlib
+ : llvm::compression::Format::Zstd;
+ if (const char *Reason = llvm::compression::getReasonIfUnsupported(F)) {
+ Error(Reason);
return nullptr;
}
- SmallVector<uint8_t, 0> Uncompressed;
- if (llvm::Error E = llvm::compression::zlib::uncompress(
- llvm::arrayRefFromStringRef(Blob), Uncompressed, Record[0])) {
+ SmallVector<uint8_t, 0> Decompressed;
+ if (llvm::Error E = llvm::compression::decompress(
+ F, llvm::arrayRefFromStringRef(Blob), Decompressed, Record[0])) {
Error("could not decompress embedded file contents: " +
llvm::toString(std::move(E)));
return nullptr;
}
return llvm::MemoryBuffer::getMemBufferCopy(
- llvm::toStringRef(Uncompressed), Name);
+ llvm::toStringRef(Decompressed), Name);
} else if (RecCode == SM_SLOC_BUFFER_BLOB) {
return llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name, true);
} else {
@@ -1551,7 +1520,7 @@ bool ASTReader::ReadSLocEntry(int ID) {
// we will also try to fail gracefully by setting up the SLocEntry.
unsigned InputID = Record[4];
InputFile IF = getInputFile(*F, InputID);
- Optional<FileEntryRef> File = IF.getFile();
+ OptionalFileEntryRef File = IF.getFile();
bool OverriddenBuffer = IF.isOverridden();
// Note that we only check if a File was returned. If it was out-of-date
@@ -1579,8 +1548,8 @@ bool ASTReader::ReadSLocEntry(int ID) {
if (NumFileDecls && ContextObj) {
const DeclID *FirstDecl = F->FileSortedDecls + Record[6];
assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");
- FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl,
- NumFileDecls));
+ FileDeclIDs[FID] =
+ FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls));
}
const SrcMgr::ContentCache &ContentCache =
@@ -1699,11 +1668,38 @@ Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record,
Token Tok;
Tok.startToken();
Tok.setLocation(ReadSourceLocation(F, Record, Idx));
- Tok.setLength(Record[Idx++]);
- if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++]))
- Tok.setIdentifierInfo(II);
Tok.setKind((tok::TokenKind)Record[Idx++]);
Tok.setFlag((Token::TokenFlags)Record[Idx++]);
+
+ if (Tok.isAnnotation()) {
+ Tok.setAnnotationEndLoc(ReadSourceLocation(F, Record, Idx));
+ switch (Tok.getKind()) {
+ case tok::annot_pragma_loop_hint: {
+ auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
+ Info->PragmaName = ReadToken(F, Record, Idx);
+ Info->Option = ReadToken(F, Record, Idx);
+ unsigned NumTokens = Record[Idx++];
+ SmallVector<Token, 4> Toks;
+ Toks.reserve(NumTokens);
+ for (unsigned I = 0; I < NumTokens; ++I)
+ Toks.push_back(ReadToken(F, Record, Idx));
+ Info->Toks = llvm::ArrayRef(Toks).copy(PP.getPreprocessorAllocator());
+ Tok.setAnnotationValue(static_cast<void *>(Info));
+ break;
+ }
+ // Some annotation tokens do not use the PtrData field.
+ case tok::annot_pragma_openmp:
+ case tok::annot_pragma_openmp_end:
+ case tok::annot_pragma_unused:
+ break;
+ default:
+ llvm_unreachable("missing deserialization code for annotation token");
+ }
+ } else {
+ Tok.setLength(Record[Idx++]);
+ if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++]))
+ Tok.setIdentifierInfo(II);
+ }
return Tok;
}
@@ -1935,8 +1931,8 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
"Wrong data length in HeaderFileInfo deserialization");
while (d != End) {
uint32_t LocalSMID = endian::readNext<uint32_t, little, unaligned>(d);
- auto HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>(LocalSMID & 3);
- LocalSMID >>= 2;
+ auto HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>(LocalSMID & 7);
+ LocalSMID >>= 3;
// This header is part of a module. Associate it with the module to enable
// implicit module import.
@@ -1951,9 +1947,9 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
Reader.ResolveImportedPath(M, Filename);
// FIXME: NameAsWritten
Module::Header H = {std::string(key.Filename), "",
- *FileMgr.getFile(Filename)};
+ FileMgr.getOptionalFileRef(Filename)};
ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
- HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
+ HFI.isModuleHeader |= ModuleMap::isModular(HeaderRole);
}
// This HeaderFileInfo was externally loaded.
@@ -2269,8 +2265,15 @@ bool ASTReader::shouldDisableValidationForFile(
return false;
}
-ASTReader::InputFileInfo
-ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
+InputFileInfo ASTReader::getInputFileInfo(ModuleFile &F, unsigned ID) {
+ // If this ID is bogus, just return an empty input file.
+ if (ID == 0 || ID > F.InputFileInfosLoaded.size())
+ return InputFileInfo();
+
+ // If we've already loaded this input file, return it.
+ if (!F.InputFileInfosLoaded[ID - 1].Filename.empty())
+ return F.InputFileInfosLoaded[ID - 1];
+
// Go find this input file.
BitstreamCursor &Cursor = F.InputFilesCursor;
SavedStreamPosition SavedPosition(Cursor);
@@ -2323,6 +2326,9 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
}
R.ContentHash = (static_cast<uint64_t>(Record[1]) << 32) |
static_cast<uint64_t>(Record[0]);
+
+ // Note that we've loaded this input file info.
+ F.InputFileInfosLoaded[ID - 1] = R;
return R;
}
@@ -2347,7 +2353,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
consumeError(std::move(Err));
}
- InputFileInfo FI = readInputFileInfo(F, ID);
+ InputFileInfo FI = getInputFileInfo(F, ID);
off_t StoredSize = FI.StoredSize;
time_t StoredTime = FI.StoredTime;
bool Overridden = FI.Overridden;
@@ -2355,18 +2361,8 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
StringRef Filename = FI.Filename;
uint64_t StoredContentHash = FI.ContentHash;
- OptionalFileEntryRefDegradesToFileEntryPtr File =
- expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false));
-
- // If we didn't find the file, resolve it relative to the
- // original directory from which this AST file was created.
- if (!File && !F.OriginalDir.empty() && !F.BaseDirectory.empty() &&
- F.OriginalDir != F.BaseDirectory) {
- std::string Resolved = resolveFileRelativeToOriginalDir(
- std::string(Filename), F.OriginalDir, F.BaseDirectory);
- if (!Resolved.empty())
- File = expectedToOptional(FileMgr.getFileRef(Resolved));
- }
+ OptionalFileEntryRefDegradesToFileEntryPtr File = OptionalFileEntryRef(
+ expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false)));
// For an overridden file, create a virtual file with the stored
// size/timestamp.
@@ -2413,8 +2409,8 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
Content,
None,
} Kind;
- llvm::Optional<int64_t> Old = llvm::None;
- llvm::Optional<int64_t> New = llvm::None;
+ std::optional<int64_t> Old = std::nullopt;
+ std::optional<int64_t> New = std::nullopt;
};
auto HasInputFileChanged = [&]() {
if (StoredSize != File->getSize())
@@ -2683,12 +2679,11 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// so we verify all input files. Otherwise, verify only user input
// files.
- unsigned N = NumUserInputs;
- if (ValidateSystemInputs ||
- (HSOpts.ModulesValidateOncePerBuildSession &&
- F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp &&
- F.Kind == MK_ImplicitModule))
- N = NumInputs;
+ unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
+ if (HSOpts.ModulesValidateOncePerBuildSession &&
+ F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp &&
+ F.Kind == MK_ImplicitModule)
+ N = NumUserInputs;
for (unsigned I = 0; I < N; ++I) {
InputFile IF = getInputFile(F, I+1, Complain);
@@ -2705,7 +2700,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
: NumUserInputs;
for (unsigned I = 0; I < N; ++I) {
bool IsSystem = I >= NumUserInputs;
- InputFileInfo FI = readInputFileInfo(F, I+1);
+ InputFileInfo FI = getInputFileInfo(F, I + 1);
Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden,
F.Kind == MK_ExplicitModule ||
F.Kind == MK_PrebuiltModule);
@@ -2922,11 +2917,6 @@ ASTReader::ReadControlBlock(ModuleFile &F,
F.OriginalSourceFileID = FileID::get(Record[0]);
break;
- case ORIGINAL_PCH_DIR:
- F.OriginalDir = std::string(Blob);
- ResolveImportedPath(F, F.OriginalDir);
- break;
-
case MODULE_NAME:
F.ModuleName = std::string(Blob);
Diag(diag::remark_module_import)
@@ -2987,6 +2977,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
F.InputFileOffsets =
(const llvm::support::unaligned_uint64_t *)Blob.data();
F.InputFilesLoaded.resize(NumInputs);
+ F.InputFileInfosLoaded.resize(NumInputs);
F.NumUserInputFiles = NumUserInputs;
break;
}
@@ -3002,7 +2993,7 @@ void ASTReader::readIncludedFiles(ModuleFile &F, StringRef Blob,
for (unsigned I = 0; I < FileCount; ++I) {
size_t ID = endian::readNext<uint32_t, little, unaligned>(D);
- InputFileInfo IFI = readInputFileInfo(F, ID);
+ InputFileInfo IFI = getInputFileInfo(F, ID);
if (llvm::ErrorOr<const FileEntry *> File =
PP.getFileManager().getFile(IFI.Filename))
PP.getIncludedFiles().insert(*File);
@@ -3412,7 +3403,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
if (!Record.empty()) {
unsigned Idx = 0, End = Record.size() - 1;
bool ReachedEOFWhileSkipping = Record[Idx++];
- llvm::Optional<Preprocessor::PreambleSkipInfo> SkipInfo;
+ std::optional<Preprocessor::PreambleSkipInfo> SkipInfo;
if (ReachedEOFWhileSkipping) {
SourceLocation HashToken = ReadSourceLocation(F, Record, Idx);
SourceLocation IfTokenLoc = ReadSourceLocation(F, Record, Idx);
@@ -3453,9 +3444,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
SLocSpaceSize);
- if (!F.SLocEntryBaseID)
+ if (!F.SLocEntryBaseID) {
+ if (!Diags.isDiagnosticInFlight()) {
+ Diags.Report(SourceLocation(), diag::remark_sloc_usage);
+ SourceMgr.noteSLocAddressSpaceUsage(Diags);
+ }
return llvm::createStringError(std::errc::invalid_argument,
"ran out of source locations");
+ }
// Make our entry in the range map. BaseID is negative and growing, so
// we invert it. Because we invert it, though, we need the other end of
// the range.
@@ -3968,13 +3964,14 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
Module *M =
PP.getHeaderSearchInfo().lookupModule(F.ModuleName, F.ImportLoc);
auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
+ OptionalFileEntryRef ModMap =
+ M ? Map.getModuleMapFileForUniquing(M) : std::nullopt;
// Don't emit module relocation error if we have -fno-validate-pch
if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
DisableValidationForModuleKind::Module) &&
!ModMap) {
if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) {
- if (auto ASTFE = M ? M->getASTFile() : None) {
+ if (auto ASTFE = M ? M->getASTFile() : std::nullopt) {
// This module was defined by an imported (explicit) module.
Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName
<< ASTFE->getName();
@@ -4257,9 +4254,10 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
SourceLocation ImportLoc,
unsigned ClientLoadCapabilities,
SmallVectorImpl<ImportedSubmodule> *Imported) {
- llvm::SaveAndRestore<SourceLocation>
- SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
- llvm::SaveAndRestore<Optional<ModuleKind>> SetCurModuleKindRAII(
+ llvm::TimeTraceScope scope("ReadAST", FileName);
+
+ llvm::SaveAndRestore SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
+ llvm::SaveAndRestore<std::optional<ModuleKind>> SetCurModuleKindRAII(
CurrentDeserializingModuleKind, Type);
// Defer any pending actions until we get to the end of reading the AST file.
@@ -4276,10 +4274,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
ReadASTCore(FileName, Type, ImportLoc,
/*ImportedBy=*/nullptr, Loaded, 0, 0, ASTFileSignature(),
ClientLoadCapabilities)) {
- ModuleMgr.removeModules(ModuleMgr.begin() + NumModules,
- PP.getLangOpts().Modules
- ? &PP.getHeaderSearchInfo().getModuleMap()
- : nullptr);
+ ModuleMgr.removeModules(ModuleMgr.begin() + NumModules);
// If we find that any modules are unusable, the global index is going
// to be out-of-date. Just remove it.
@@ -4299,6 +4294,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
// hit errors parsing the ASTs at this point.
for (ImportedModule &M : Loaded) {
ModuleFile &F = *M.Mod;
+ llvm::TimeTraceScope Scope2("Read Loaded AST", F.ModuleName);
// Read the AST block.
if (llvm::Error Err = ReadASTBlock(F, ClientLoadCapabilities)) {
@@ -4343,10 +4339,8 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
// Map the original source file ID into the ID space of the current
// compilation.
- if (F.OriginalSourceFileID.isValid()) {
- F.OriginalSourceFileID = FileID::get(
- F.SLocEntryBaseID + F.OriginalSourceFileID.getOpaqueValue() - 1);
- }
+ if (F.OriginalSourceFileID.isValid())
+ F.OriginalSourceFileID = TranslateFileID(F, F.OriginalSourceFileID);
// Preload all the pending interesting identifiers by marking them out of
// date.
@@ -4426,6 +4420,11 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
Unresolved.Mod->Imports.insert(ResolvedMod);
continue;
+ case UnresolvedModuleRef::Affecting:
+ if (ResolvedMod)
+ Unresolved.Mod->AffectingClangModules.insert(ResolvedMod);
+ continue;
+
case UnresolvedModuleRef::Export:
if (ResolvedMod || Unresolved.IsWildcard)
Unresolved.Mod->Exports.push_back(
@@ -4806,6 +4805,13 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
Result = OutOfDate; // Don't return early. Read the signature.
break;
}
+ case HEADER_SEARCH_PATHS: {
+ bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
+ if (!AllowCompatibleConfigurationMismatch &&
+ ParseHeaderSearchPaths(Record, Complain, *Listener))
+ Result = ConfigurationMismatch;
+ break;
+ }
case DIAG_PRAGMA_MAPPINGS:
if (!F)
break;
@@ -5213,19 +5219,28 @@ namespace {
bool ASTReader::readASTFileControlBlock(
StringRef Filename, FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- bool FindModuleFileExtensions,
+ const InMemoryModuleCache &ModuleCache,
+ const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
ASTReaderListener &Listener, bool ValidateDiagnosticOptions) {
// Open the AST file.
- // FIXME: This allows use of the VFS; we do not allow use of the
- // VFS when actually loading a module.
- auto Buffer = FileMgr.getBufferForFile(Filename);
+ std::unique_ptr<llvm::MemoryBuffer> OwnedBuffer;
+ llvm::MemoryBuffer *Buffer = ModuleCache.lookupPCM(Filename);
if (!Buffer) {
- return true;
+ // FIXME: We should add the pcm to the InMemoryModuleCache if it could be
+ // read again later, but we do not have the context here to determine if it
+ // is safe to change the result of InMemoryModuleCache::getPCMState().
+
+ // FIXME: This allows use of the VFS; we do not allow use of the
+ // VFS when actually loading a module.
+ auto BufferOrErr = FileMgr.getBufferForFile(Filename);
+ if (!BufferOrErr)
+ return true;
+ OwnedBuffer = std::move(*BufferOrErr);
+ Buffer = OwnedBuffer.get();
}
// Initialize the stream
- StringRef Bytes = PCHContainerRdr.ExtractPCH(**Buffer);
+ StringRef Bytes = PCHContainerRdr.ExtractPCH(*Buffer);
BitstreamCursor Stream(Bytes);
// Sniff for the signature.
@@ -5478,6 +5493,7 @@ bool ASTReader::readASTFileControlBlock(
}
bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
+ const InMemoryModuleCache &ModuleCache,
const PCHContainerReader &PCHContainerRdr,
const LangOptions &LangOpts,
const TargetOptions &TargetOpts,
@@ -5487,9 +5503,9 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
ExistingModuleCachePath, FileMgr,
RequireStrictOptionMatches);
- return !readASTFileControlBlock(Filename, FileMgr, PCHContainerRdr,
- /*FindModuleFileExtensions=*/false,
- validator,
+ return !readASTFileControlBlock(Filename, FileMgr, ModuleCache,
+ PCHContainerRdr,
+ /*FindModuleFileExtensions=*/false, validator,
/*ValidateDiagnosticOptions=*/true);
}
@@ -5645,7 +5661,7 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
// `Headers/`, so this path will never exist.
std::string Filename = std::string(Blob);
ResolveImportedPath(F, Filename);
- if (auto Umbrella = PP.getFileManager().getFile(Filename)) {
+ if (auto Umbrella = PP.getFileManager().getOptionalFileRef(Filename)) {
if (!CurrentModule->getUmbrellaHeader()) {
// FIXME: NameAsWritten
ModMap.setUmbrellaHeader(CurrentModule, *Umbrella, Blob, "");
@@ -5724,6 +5740,18 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
}
break;
+ case SUBMODULE_AFFECTING_MODULES:
+ for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
+ UnresolvedModuleRef Unresolved;
+ Unresolved.File = &F;
+ Unresolved.Mod = CurrentModule;
+ Unresolved.ID = Record[Idx];
+ Unresolved.Kind = UnresolvedModuleRef::Affecting;
+ Unresolved.IsWildcard = false;
+ UnresolvedModuleRefs.push_back(Unresolved);
+ }
+ break;
+
case SUBMODULE_EXPORTS:
for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
UnresolvedModuleRef Unresolved;
@@ -5886,6 +5914,28 @@ bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
unsigned Idx = 0;
HSOpts.Sysroot = ReadString(Record, Idx);
+ HSOpts.ResourceDir = ReadString(Record, Idx);
+ HSOpts.ModuleCachePath = ReadString(Record, Idx);
+ HSOpts.ModuleUserBuildPath = ReadString(Record, Idx);
+ HSOpts.DisableModuleHash = Record[Idx++];
+ HSOpts.ImplicitModuleMaps = Record[Idx++];
+ HSOpts.ModuleMapFileHomeIsCwd = Record[Idx++];
+ HSOpts.EnablePrebuiltImplicitModules = Record[Idx++];
+ HSOpts.UseBuiltinIncludes = Record[Idx++];
+ HSOpts.UseStandardSystemIncludes = Record[Idx++];
+ HSOpts.UseStandardCXXIncludes = Record[Idx++];
+ HSOpts.UseLibcxx = Record[Idx++];
+ std::string SpecificModuleCachePath = ReadString(Record, Idx);
+
+ return Listener.ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
+ Complain);
+}
+
+bool ASTReader::ParseHeaderSearchPaths(const RecordData &Record, bool Complain,
+ ASTReaderListener &Listener) {
+ HeaderSearchOptions HSOpts;
+ unsigned Idx = 0;
+
// Include entries.
for (unsigned N = Record[Idx++]; N; --N) {
std::string Path = ReadString(Record, Idx);
@@ -5904,21 +5954,13 @@ bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
HSOpts.SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader);
}
- HSOpts.ResourceDir = ReadString(Record, Idx);
- HSOpts.ModuleCachePath = ReadString(Record, Idx);
- HSOpts.ModuleUserBuildPath = ReadString(Record, Idx);
- HSOpts.DisableModuleHash = Record[Idx++];
- HSOpts.ImplicitModuleMaps = Record[Idx++];
- HSOpts.ModuleMapFileHomeIsCwd = Record[Idx++];
- HSOpts.EnablePrebuiltImplicitModules = Record[Idx++];
- HSOpts.UseBuiltinIncludes = Record[Idx++];
- HSOpts.UseStandardSystemIncludes = Record[Idx++];
- HSOpts.UseStandardCXXIncludes = Record[Idx++];
- HSOpts.UseLibcxx = Record[Idx++];
- std::string SpecificModuleCachePath = ReadString(Record, Idx);
+ // VFS overlay files.
+ for (unsigned N = Record[Idx++]; N; --N) {
+ std::string VFSOverlayFile = ReadString(Record, Idx);
+ HSOpts.VFSOverlayFiles.emplace_back(std::move(VFSOverlayFile));
+ }
- return Listener.ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- Complain);
+ return Listener.ReadHeaderSearchPaths(HSOpts, Complain);
}
bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
@@ -6084,7 +6126,7 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
case PPD_INCLUSION_DIRECTIVE: {
const char *FullFileNameStart = Blob.data() + Record[0];
StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
- Optional<FileEntryRef> File;
+ OptionalFileEntryRef File;
if (!FullFileName.empty())
File = PP.getFileManager().getOptionalFileRef(FullFileName);
@@ -6223,8 +6265,8 @@ std::pair<unsigned, unsigned>
/// Optionally returns true or false if the preallocated preprocessed
/// entity with index \arg Index came from file \arg FID.
-Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) {
+std::optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) {
if (FID.isInvalid())
return false;
@@ -6248,7 +6290,7 @@ namespace {
/// Visitor used to search for information about a header file.
class HeaderFileInfoVisitor {
const FileEntry *FE;
- Optional<HeaderFileInfo> HFI;
+ std::optional<HeaderFileInfo> HFI;
public:
explicit HeaderFileInfoVisitor(const FileEntry *FE) : FE(FE) {}
@@ -6268,7 +6310,7 @@ namespace {
return true;
}
- Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
+ std::optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
};
} // namespace
@@ -6276,8 +6318,8 @@ namespace {
HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
HeaderFileInfoVisitor Visitor(FE);
ModuleMgr.visit(Visitor);
- if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo())
- return *HFI;
+ if (std::optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo())
+ return *HFI;
return HeaderFileInfo();
}
@@ -6294,9 +6336,8 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
DiagStates.clear();
- auto ReadDiagState =
- [&](const DiagState &BasedOn, SourceLocation Loc,
- bool IncludeNonPragmaStates) -> DiagnosticsEngine::DiagState * {
+ auto ReadDiagState = [&](const DiagState &BasedOn,
+ bool IncludeNonPragmaStates) {
unsigned BackrefID = Record[Idx++];
if (BackrefID != 0)
return DiagStates[BackrefID - 1];
@@ -6357,7 +6398,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
Initial.EnableAllWarnings = Flags & 1; Flags >>= 1;
Initial.IgnoreAllWarnings = Flags & 1; Flags >>= 1;
Initial.ExtBehavior = (diag::Severity)Flags;
- FirstState = ReadDiagState(Initial, SourceLocation(), true);
+ FirstState = ReadDiagState(Initial, true);
assert(F.OriginalSourceFileID.isValid());
@@ -6370,8 +6411,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
// For prefix ASTs, start with whatever the user configured on the
// command line.
Idx++; // Skip flags.
- FirstState = ReadDiagState(*Diag.DiagStatesByLoc.CurDiagState,
- SourceLocation(), false);
+ FirstState = ReadDiagState(*Diag.DiagStatesByLoc.CurDiagState, false);
}
// Read the state transitions.
@@ -6393,8 +6433,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
for (unsigned I = 0; I != Transitions; ++I) {
unsigned Offset = Record[Idx++];
- auto *State =
- ReadDiagState(*FirstState, Loc.getLocWithOffset(Offset), false);
+ auto *State = ReadDiagState(*FirstState, false);
F.StateTransitions.push_back({State, Offset});
}
}
@@ -6404,7 +6443,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
"Invalid data, missing final pragma diagnostic state");
SourceLocation CurStateLoc =
ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
- auto *CurState = ReadDiagState(*FirstState, CurStateLoc, false);
+ auto *CurState = ReadDiagState(*FirstState, false);
if (!F.isModule()) {
Diag.DiagStatesByLoc.CurDiagState = CurState;
@@ -6435,12 +6474,13 @@ ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
M->DeclsBlockStartOffset);
}
-static llvm::Optional<Type::TypeClass> getTypeClassForCode(TypeCode code) {
+static std::optional<Type::TypeClass> getTypeClassForCode(TypeCode code) {
switch (code) {
#define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \
case TYPE_##CODE_ID: return Type::CLASS_ID;
#include "clang/Serialization/TypeBitCodes.def"
- default: return llvm::None;
+ default:
+ return std::nullopt;
}
}
@@ -6697,7 +6737,7 @@ void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
TL.setTypeofLoc(readSourceLocation());
TL.setLParenLoc(readSourceLocation());
TL.setRParenLoc(readSourceLocation());
- TL.setUnderlyingTInfo(GetTypeSourceInfo());
+ TL.setUnmodifiedTInfo(GetTypeSourceInfo());
}
void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
@@ -6722,8 +6762,9 @@ void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
TL.setLAngleLoc(readSourceLocation());
TL.setRAngleLoc(readSourceLocation());
for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo(
- TL.getTypePtr()->getArg(i).getKind()));
+ TL.setArgLocInfo(
+ i, Reader.readTemplateArgumentLocInfo(
+ TL.getTypePtr()->getTypeConstraintArguments()[i].getKind()));
}
if (Reader.readBool())
TL.setRParenLoc(readSourceLocation());
@@ -6771,10 +6812,9 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc(
TL.setLAngleLoc(readSourceLocation());
TL.setRAngleLoc(readSourceLocation());
for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- TL.setArgLocInfo(
- i,
- Reader.readTemplateArgumentLocInfo(
- TL.getTypePtr()->getArg(i).getKind()));
+ TL.setArgLocInfo(i,
+ Reader.readTemplateArgumentLocInfo(
+ TL.getTypePtr()->template_arguments()[i].getKind()));
}
void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
@@ -6806,10 +6846,9 @@ void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
TL.setLAngleLoc(readSourceLocation());
TL.setRAngleLoc(readSourceLocation());
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- TL.setArgLocInfo(
- I,
- Reader.readTemplateArgumentLocInfo(
- TL.getTypePtr()->getArg(I).getKind()));
+ TL.setArgLocInfo(I,
+ Reader.readTemplateArgumentLocInfo(
+ TL.getTypePtr()->template_arguments()[I].getKind()));
}
void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
@@ -6818,6 +6857,7 @@ void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
TL.setNameLoc(readSourceLocation());
+ TL.setNameEndLoc(readSourceLocation());
}
void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
@@ -7262,8 +7302,7 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {
//
// FIXME: 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 (isa<TranslationUnitDecl, NamespaceDecl, RecordDecl, EnumDecl>(DC)) {
if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
if (!getContext().getLangOpts().CPlusPlus &&
isa<TranslationUnitDecl>(DC)) {
@@ -7997,8 +8036,8 @@ void ASTReader::UpdateSema() {
PragmaAlignPackStack.front().PushLocation);
DropFirst = true;
}
- for (const auto &Entry : llvm::makeArrayRef(PragmaAlignPackStack)
- .drop_front(DropFirst ? 1 : 0)) {
+ for (const auto &Entry :
+ llvm::ArrayRef(PragmaAlignPackStack).drop_front(DropFirst ? 1 : 0)) {
SemaObj->AlignPackStack.Stack.emplace_back(
Entry.SlotLabel, Entry.Value, Entry.Location, Entry.PushLocation);
}
@@ -8029,7 +8068,7 @@ void ASTReader::UpdateSema() {
DropFirst = true;
}
for (const auto &Entry :
- llvm::makeArrayRef(FpPragmaStack).drop_front(DropFirst ? 1 : 0))
+ llvm::ArrayRef(FpPragmaStack).drop_front(DropFirst ? 1 : 0))
SemaObj->FpPragmaStack.Stack.emplace_back(
Entry.SlotLabel, Entry.Value, Entry.Location, Entry.PushLocation);
if (FpPragmaCurrentLocation.isInvalid()) {
@@ -8065,7 +8104,7 @@ IdentifierInfo *ASTReader::get(StringRef Name) {
// lookups). Perform the lookup in PCH files, though, since we don't build
// a complete initial identifier table if we're carrying on from a PCH.
if (PP.getLangOpts().CPlusPlus) {
- for (auto F : ModuleMgr.pch_modules())
+ for (auto *F : ModuleMgr.pch_modules())
if (Visitor(*F))
break;
} else {
@@ -8272,8 +8311,8 @@ namespace serialization {
/// Add the given set of methods to the method list.
static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,
ObjCMethodList &List) {
- for (auto I = Methods.rbegin(), E = Methods.rend(); I != E; ++I)
- S.addMethodToGlobalList(&List, *I);
+ for (ObjCMethodDecl *M : llvm::reverse(Methods))
+ S.addMethodToGlobalList(&List, M);
}
void ASTReader::ReadMethodPool(Selector Sel) {
@@ -8725,8 +8764,7 @@ unsigned ASTReader::getModuleFileID(ModuleFile *F) {
return (I - PCHModules.end()) << 1;
}
-llvm::Optional<ASTSourceDescriptor>
-ASTReader::getSourceDescriptor(unsigned ID) {
+std::optional<ASTSourceDescriptor> ASTReader::getSourceDescriptor(unsigned ID) {
if (Module *M = getSubmodule(ID))
return ASTSourceDescriptor(*M);
@@ -8737,10 +8775,11 @@ ASTReader::getSourceDescriptor(unsigned ID) {
ModuleFile &MF = ModuleMgr.getPrimaryModule();
StringRef ModuleName = llvm::sys::path::filename(MF.OriginalSourceFileName);
StringRef FileName = llvm::sys::path::filename(MF.FileName);
- return ASTSourceDescriptor(ModuleName, MF.OriginalDir, FileName,
- MF.Signature);
+ return ASTSourceDescriptor(ModuleName,
+ llvm::sys::path::parent_path(MF.FileName),
+ FileName, MF.Signature);
}
- return None;
+ return std::nullopt;
}
ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(const Decl *FD) {
@@ -9207,30 +9246,16 @@ void ASTReader::visitInputFiles(serialization::ModuleFile &MF,
void ASTReader::visitTopLevelModuleMaps(
serialization::ModuleFile &MF,
- llvm::function_ref<void(const FileEntry *FE)> Visitor) {
+ llvm::function_ref<void(FileEntryRef FE)> Visitor) {
unsigned NumInputs = MF.InputFilesLoaded.size();
for (unsigned I = 0; I < NumInputs; ++I) {
- InputFileInfo IFI = readInputFileInfo(MF, I + 1);
+ InputFileInfo IFI = getInputFileInfo(MF, I + 1);
if (IFI.TopLevelModuleMap)
- // FIXME: This unnecessarily re-reads the InputFileInfo.
if (auto FE = getInputFile(MF, I + 1).getFile())
- Visitor(FE);
+ Visitor(*FE);
}
}
-std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
- // If we know the owning module, use it.
- if (Module *M = D->getImportedOwningModule())
- 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() || !PendingFunctionTypes.empty() ||
!PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
@@ -9478,35 +9503,13 @@ void ASTReader::finishPendingActions() {
PendingMergedDefinitionsToDeduplicate.clear();
}
-static unsigned computeODRHash(QualType Ty) {
- ODRHash Hasher;
- Hasher.AddQualType(Ty);
- return Hasher.CalculateHash();
-}
-
-static unsigned computeODRHash(const Stmt *S) {
- ODRHash Hasher;
- Hasher.AddStmt(S);
- return Hasher.CalculateHash();
-}
-
-static unsigned computeODRHash(const Decl *D) {
- assert(D);
- ODRHash Hasher;
- Hasher.AddSubDecl(D);
- return Hasher.CalculateHash();
-}
-
-static unsigned computeODRHash(const TemplateArgument &TA) {
- ODRHash Hasher;
- Hasher.AddTemplateArgument(TA);
- return Hasher.CalculateHash();
-}
-
void ASTReader::diagnoseOdrViolations() {
if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty() &&
+ PendingRecordOdrMergeFailures.empty() &&
PendingFunctionOdrMergeFailures.empty() &&
- PendingEnumOdrMergeFailures.empty())
+ PendingEnumOdrMergeFailures.empty() &&
+ PendingObjCInterfaceOdrMergeFailures.empty() &&
+ PendingObjCProtocolOdrMergeFailures.empty())
return;
// Trigger the import of the full definition of each class that had any
@@ -9528,6 +9531,25 @@ void ASTReader::diagnoseOdrViolations() {
}
}
+ // Trigger the import of the full definition of each record in C/ObjC.
+ auto RecordOdrMergeFailures = std::move(PendingRecordOdrMergeFailures);
+ PendingRecordOdrMergeFailures.clear();
+ for (auto &Merge : RecordOdrMergeFailures) {
+ Merge.first->decls_begin();
+ for (auto &D : Merge.second)
+ D->decls_begin();
+ }
+
+ // Trigger the import of the full interface definition.
+ auto ObjCInterfaceOdrMergeFailures =
+ std::move(PendingObjCInterfaceOdrMergeFailures);
+ PendingObjCInterfaceOdrMergeFailures.clear();
+ for (auto &Merge : ObjCInterfaceOdrMergeFailures) {
+ Merge.first->decls_begin();
+ for (auto &InterfacePair : Merge.second)
+ InterfacePair.first->decls_begin();
+ }
+
// Trigger the import of functions.
auto FunctionOdrMergeFailures = std::move(PendingFunctionOdrMergeFailures);
PendingFunctionOdrMergeFailures.clear();
@@ -9552,6 +9574,16 @@ void ASTReader::diagnoseOdrViolations() {
}
}
+ // Trigger the import of the full protocol definition.
+ auto ObjCProtocolOdrMergeFailures =
+ std::move(PendingObjCProtocolOdrMergeFailures);
+ PendingObjCProtocolOdrMergeFailures.clear();
+ for (auto &Merge : ObjCProtocolOdrMergeFailures) {
+ Merge.first->decls_begin();
+ for (auto &ProtocolPair : Merge.second)
+ ProtocolPair.first->decls_begin();
+ }
+
// For each declaration from a merged context, check that the canonical
// definition of that context also contains a declaration of the same
// entity.
@@ -9573,7 +9605,7 @@ void ASTReader::diagnoseOdrViolations() {
bool Found = false;
const Decl *DCanon = D->getCanonicalDecl();
- for (auto RI : D->redecls()) {
+ for (auto *RI : D->redecls()) {
if (RI->getLexicalDeclContext() == CanonDef) {
Found = true;
break;
@@ -9615,9 +9647,10 @@ void ASTReader::diagnoseOdrViolations() {
Deserializing RecursionGuard(this);
std::string CanonDefModule =
- getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef));
+ ODRDiagsEmitter::getOwningModuleNameForDiagnostic(
+ cast<Decl>(CanonDef));
Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl)
- << D << getOwningModuleNameForDiagnostic(D)
+ << D << ODRDiagsEmitter::getOwningModuleNameForDiagnostic(D)
<< CanonDef << CanonDefModule.empty() << CanonDefModule;
if (Candidates.empty())
@@ -9634,392 +9667,17 @@ void ASTReader::diagnoseOdrViolations() {
}
}
- if (OdrMergeFailures.empty() && FunctionOdrMergeFailures.empty() &&
- EnumOdrMergeFailures.empty())
+ if (OdrMergeFailures.empty() && RecordOdrMergeFailures.empty() &&
+ FunctionOdrMergeFailures.empty() && EnumOdrMergeFailures.empty() &&
+ ObjCInterfaceOdrMergeFailures.empty() &&
+ ObjCProtocolOdrMergeFailures.empty())
return;
// Ensure we don't accidentally recursively enter deserialization while
// we're producing our diagnostics.
Deserializing RecursionGuard(this);
-
- // Used with err_module_odr_violation_mismatch_decl and
- // note_module_odr_violation_mismatch_decl
- // This list should be the same Decl's as in ODRHash::isDeclToBeProcessed
- enum ODRMismatchDecl {
- EndOfClass,
- PublicSpecifer,
- PrivateSpecifer,
- ProtectedSpecifer,
- StaticAssert,
- Field,
- CXXMethod,
- TypeAlias,
- TypeDef,
- Var,
- Friend,
- FunctionTemplate,
- Other
- };
-
- // These lambdas have the common portions of the ODR diagnostics. This
- // has the same return as Diag(), so addition parameters can be passed
- // in with operator<<
- auto ODRDiagField = [this](NamedDecl *FirstRecord, StringRef FirstModule,
- StringRef SecondModule,
- const FieldDecl *FirstField,
- const FieldDecl *SecondField) {
- enum ODRFieldDifference {
- FieldName,
- FieldTypeName,
- FieldSingleBitField,
- FieldDifferentWidthBitField,
- FieldSingleMutable,
- FieldSingleInitializer,
- FieldDifferentInitializers,
- };
-
- auto DiagError = [FirstRecord, FirstField, FirstModule,
- this](ODRFieldDifference DiffType) {
- return Diag(FirstField->getLocation(),
- diag::err_module_odr_violation_field)
- << FirstRecord << FirstModule.empty() << FirstModule
- << FirstField->getSourceRange() << DiffType;
- };
- auto DiagNote = [SecondField, SecondModule,
- this](ODRFieldDifference DiffType) {
- return Diag(SecondField->getLocation(),
- diag::note_module_odr_violation_field)
- << SecondModule << SecondField->getSourceRange() << DiffType;
- };
-
- IdentifierInfo *FirstII = FirstField->getIdentifier();
- IdentifierInfo *SecondII = SecondField->getIdentifier();
- if (FirstII->getName() != SecondII->getName()) {
- DiagError(FieldName) << FirstII;
- DiagNote(FieldName) << SecondII;
- return true;
- }
-
- assert(getContext().hasSameType(FirstField->getType(),
- SecondField->getType()));
-
- QualType FirstType = FirstField->getType();
- QualType SecondType = SecondField->getType();
- if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
- DiagError(FieldTypeName) << FirstII << FirstType;
- DiagNote(FieldTypeName) << SecondII << SecondType;
- return true;
- }
-
- const bool IsFirstBitField = FirstField->isBitField();
- const bool IsSecondBitField = SecondField->isBitField();
- if (IsFirstBitField != IsSecondBitField) {
- DiagError(FieldSingleBitField) << FirstII << IsFirstBitField;
- DiagNote(FieldSingleBitField) << SecondII << IsSecondBitField;
- return true;
- }
-
- if (IsFirstBitField && IsSecondBitField) {
- unsigned FirstBitWidthHash = computeODRHash(FirstField->getBitWidth());
- unsigned SecondBitWidthHash = computeODRHash(SecondField->getBitWidth());
- if (FirstBitWidthHash != SecondBitWidthHash) {
- DiagError(FieldDifferentWidthBitField)
- << FirstII << FirstField->getBitWidth()->getSourceRange();
- DiagNote(FieldDifferentWidthBitField)
- << SecondII << SecondField->getBitWidth()->getSourceRange();
- return true;
- }
- }
-
- if (!PP.getLangOpts().CPlusPlus)
- return false;
-
- const bool IsFirstMutable = FirstField->isMutable();
- const bool IsSecondMutable = SecondField->isMutable();
- if (IsFirstMutable != IsSecondMutable) {
- DiagError(FieldSingleMutable) << FirstII << IsFirstMutable;
- DiagNote(FieldSingleMutable) << SecondII << IsSecondMutable;
- return true;
- }
-
- const Expr *FirstInitializer = FirstField->getInClassInitializer();
- const Expr *SecondInitializer = SecondField->getInClassInitializer();
- if ((!FirstInitializer && SecondInitializer) ||
- (FirstInitializer && !SecondInitializer)) {
- DiagError(FieldSingleInitializer)
- << FirstII << (FirstInitializer != nullptr);
- DiagNote(FieldSingleInitializer)
- << SecondII << (SecondInitializer != nullptr);
- return true;
- }
-
- if (FirstInitializer && SecondInitializer) {
- unsigned FirstInitHash = computeODRHash(FirstInitializer);
- unsigned SecondInitHash = computeODRHash(SecondInitializer);
- if (FirstInitHash != SecondInitHash) {
- DiagError(FieldDifferentInitializers)
- << FirstII << FirstInitializer->getSourceRange();
- DiagNote(FieldDifferentInitializers)
- << SecondII << SecondInitializer->getSourceRange();
- return true;
- }
- }
-
- return false;
- };
-
- auto ODRDiagTypeDefOrAlias =
- [this](NamedDecl *FirstRecord, StringRef FirstModule,
- StringRef SecondModule, const TypedefNameDecl *FirstTD,
- const TypedefNameDecl *SecondTD, bool IsTypeAlias) {
- enum ODRTypedefDifference {
- TypedefName,
- TypedefType,
- };
-
- auto DiagError = [FirstRecord, FirstTD, FirstModule,
- this](ODRTypedefDifference DiffType) {
- return Diag(FirstTD->getLocation(),
- diag::err_module_odr_violation_typedef)
- << FirstRecord << FirstModule.empty() << FirstModule
- << FirstTD->getSourceRange() << DiffType;
- };
- auto DiagNote = [SecondTD, SecondModule,
- this](ODRTypedefDifference DiffType) {
- return Diag(SecondTD->getLocation(),
- diag::note_module_odr_violation_typedef)
- << SecondModule << SecondTD->getSourceRange() << DiffType;
- };
-
- DeclarationName FirstName = FirstTD->getDeclName();
- DeclarationName SecondName = SecondTD->getDeclName();
- if (FirstName != SecondName) {
- DiagError(TypedefName) << IsTypeAlias << FirstName;
- DiagNote(TypedefName) << IsTypeAlias << SecondName;
- return true;
- }
-
- QualType FirstType = FirstTD->getUnderlyingType();
- QualType SecondType = SecondTD->getUnderlyingType();
- if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
- DiagError(TypedefType) << IsTypeAlias << FirstName << FirstType;
- DiagNote(TypedefType) << IsTypeAlias << SecondName << SecondType;
- return true;
- }
-
- return false;
- };
-
- auto ODRDiagVar = [this](NamedDecl *FirstRecord, StringRef FirstModule,
- StringRef SecondModule, const VarDecl *FirstVD,
- const VarDecl *SecondVD) {
- enum ODRVarDifference {
- VarName,
- VarType,
- VarSingleInitializer,
- VarDifferentInitializer,
- VarConstexpr,
- };
-
- auto DiagError = [FirstRecord, FirstVD, FirstModule,
- this](ODRVarDifference DiffType) {
- return Diag(FirstVD->getLocation(),
- diag::err_module_odr_violation_variable)
- << FirstRecord << FirstModule.empty() << FirstModule
- << FirstVD->getSourceRange() << DiffType;
- };
- auto DiagNote = [SecondVD, SecondModule, this](ODRVarDifference DiffType) {
- return Diag(SecondVD->getLocation(),
- diag::note_module_odr_violation_variable)
- << SecondModule << SecondVD->getSourceRange() << DiffType;
- };
-
- DeclarationName FirstName = FirstVD->getDeclName();
- DeclarationName SecondName = SecondVD->getDeclName();
- if (FirstName != SecondName) {
- DiagError(VarName) << FirstName;
- DiagNote(VarName) << SecondName;
- return true;
- }
-
- QualType FirstType = FirstVD->getType();
- QualType SecondType = SecondVD->getType();
- if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
- DiagError(VarType) << FirstName << FirstType;
- DiagNote(VarType) << SecondName << SecondType;
- return true;
- }
-
- if (!PP.getLangOpts().CPlusPlus)
- return false;
-
- const Expr *FirstInit = FirstVD->getInit();
- const Expr *SecondInit = SecondVD->getInit();
- if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
- DiagError(VarSingleInitializer)
- << FirstName << (FirstInit == nullptr)
- << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
- DiagNote(VarSingleInitializer)
- << SecondName << (SecondInit == nullptr)
- << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
- return true;
- }
-
- if (FirstInit && SecondInit &&
- computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
- DiagError(VarDifferentInitializer)
- << FirstName << FirstInit->getSourceRange();
- DiagNote(VarDifferentInitializer)
- << SecondName << SecondInit->getSourceRange();
- return true;
- }
-
- const bool FirstIsConstexpr = FirstVD->isConstexpr();
- const bool SecondIsConstexpr = SecondVD->isConstexpr();
- if (FirstIsConstexpr != SecondIsConstexpr) {
- DiagError(VarConstexpr) << FirstName << FirstIsConstexpr;
- DiagNote(VarConstexpr) << SecondName << SecondIsConstexpr;
- return true;
- }
- return false;
- };
-
- using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>;
- auto PopulateHashes = [](DeclHashes &Hashes, RecordDecl *Record,
- const DeclContext *DC) {
- for (auto *D : Record->decls()) {
- if (!ODRHash::isDeclToBeProcessed(D, DC))
- continue;
- Hashes.emplace_back(D, computeODRHash(D));
- }
- };
-
- struct DiffResult {
- Decl *FirstDecl = nullptr, *SecondDecl = nullptr;
- ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other;
- };
-
- // If there is a diagnoseable difference, FirstDiffType and
- // SecondDiffType will not be Other and FirstDecl and SecondDecl will be
- // filled in if not EndOfClass.
- auto FindTypeDiffs = [](DeclHashes &FirstHashes, DeclHashes &SecondHashes) {
- auto DifferenceSelector = [](Decl *D) {
- assert(D && "valid Decl required");
- switch (D->getKind()) {
- default:
- return Other;
- case Decl::AccessSpec:
- switch (D->getAccess()) {
- case AS_public:
- return PublicSpecifer;
- case AS_private:
- return PrivateSpecifer;
- case AS_protected:
- return ProtectedSpecifer;
- case AS_none:
- break;
- }
- llvm_unreachable("Invalid access specifier");
- case Decl::StaticAssert:
- return StaticAssert;
- case Decl::Field:
- return Field;
- case Decl::CXXMethod:
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- return CXXMethod;
- case Decl::TypeAlias:
- return TypeAlias;
- case Decl::Typedef:
- return TypeDef;
- case Decl::Var:
- return Var;
- case Decl::Friend:
- return Friend;
- case Decl::FunctionTemplate:
- return FunctionTemplate;
- }
- };
-
- DiffResult DR;
- auto FirstIt = FirstHashes.begin();
- auto SecondIt = SecondHashes.begin();
- while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
- if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
- FirstIt->second == SecondIt->second) {
- ++FirstIt;
- ++SecondIt;
- continue;
- }
-
- DR.FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
- DR.SecondDecl =
- SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
-
- DR.FirstDiffType =
- DR.FirstDecl ? DifferenceSelector(DR.FirstDecl) : EndOfClass;
- DR.SecondDiffType =
- DR.SecondDecl ? DifferenceSelector(DR.SecondDecl) : EndOfClass;
- return DR;
- }
- return DR;
- };
-
- // Use this to diagnose that an unexpected Decl was encountered
- // or no difference was detected. This causes a generic error
- // message to be emitted.
- auto DiagnoseODRUnexpected = [this](DiffResult &DR, NamedDecl *FirstRecord,
- StringRef FirstModule,
- NamedDecl *SecondRecord,
- StringRef SecondModule) {
- Diag(FirstRecord->getLocation(),
- diag::err_module_odr_violation_different_definitions)
- << FirstRecord << FirstModule.empty() << FirstModule;
-
- if (DR.FirstDecl) {
- Diag(DR.FirstDecl->getLocation(), diag::note_first_module_difference)
- << FirstRecord << DR.FirstDecl->getSourceRange();
- }
-
- Diag(SecondRecord->getLocation(),
- diag::note_module_odr_violation_different_definitions)
- << SecondModule;
-
- if (DR.SecondDecl) {
- Diag(DR.SecondDecl->getLocation(), diag::note_second_module_difference)
- << DR.SecondDecl->getSourceRange();
- }
- };
-
- auto DiagnoseODRMismatch = [this](DiffResult &DR, NamedDecl *FirstRecord,
- StringRef FirstModule,
- NamedDecl *SecondRecord,
- StringRef SecondModule) {
- auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
- ODRMismatchDecl DiffType, const Decl *D) {
- SourceLocation Loc;
- SourceRange Range;
- auto *Tag = dyn_cast<TagDecl>(Container);
- if (DiffType == EndOfClass && Tag) {
- Loc = Tag->getBraceRange().getEnd();
- } else {
- Loc = D->getLocation();
- Range = D->getSourceRange();
- }
- return std::make_pair(Loc, Range);
- };
-
- auto FirstDiagInfo =
- GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
- Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
- << FirstRecord << FirstModule.empty() << FirstModule
- << FirstDiagInfo.second << DR.FirstDiffType;
-
- auto SecondDiagInfo =
- GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
- Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
- << SecondModule << SecondDiagInfo.second << DR.SecondDiffType;
- };
+ ODRDiagsEmitter DiagsEmitter(Diags, getContext(),
+ getPreprocessor().getLangOpts());
// Issue any pending ODR-failure diagnostics.
for (auto &Merge : OdrMergeFailures) {
@@ -10030,986 +9688,12 @@ void ASTReader::diagnoseOdrViolations() {
bool Diagnosed = false;
CXXRecordDecl *FirstRecord = Merge.first;
- std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
for (auto &RecordPair : Merge.second) {
- CXXRecordDecl *SecondRecord = RecordPair.first;
- // Multiple different declarations got merged together; tell the user
- // where they came from.
- if (FirstRecord == SecondRecord)
- continue;
-
- std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
-
- auto *FirstDD = FirstRecord->DefinitionData;
- auto *SecondDD = RecordPair.second;
-
- assert(FirstDD && SecondDD && "Definitions without DefinitionData");
-
- // Diagnostics from DefinitionData are emitted here.
- if (FirstDD != SecondDD) {
- enum ODRDefinitionDataDifference {
- NumBases,
- NumVBases,
- BaseType,
- BaseVirtual,
- BaseAccess,
- };
- auto ODRDiagBaseError = [FirstRecord, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRDefinitionDataDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_definition_data)
- << FirstRecord << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagBaseNote = [&SecondModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRDefinitionDataDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_definition_data)
- << SecondModule << Range << DiffType;
- };
- auto GetSourceRange = [](struct CXXRecordDecl::DefinitionData *DD) {
- unsigned NumBases = DD->NumBases;
- if (NumBases == 0) return SourceRange();
- ArrayRef<CXXBaseSpecifier> bases = DD->bases();
- return SourceRange(bases[0].getBeginLoc(),
- bases[NumBases - 1].getEndLoc());
- };
-
- unsigned FirstNumBases = FirstDD->NumBases;
- unsigned FirstNumVBases = FirstDD->NumVBases;
- unsigned SecondNumBases = SecondDD->NumBases;
- unsigned SecondNumVBases = SecondDD->NumVBases;
- if (FirstNumBases != SecondNumBases) {
- ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
- NumBases)
- << FirstNumBases;
- ODRDiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
- NumBases)
- << SecondNumBases;
- Diagnosed = true;
- break;
- }
-
- if (FirstNumVBases != SecondNumVBases) {
- ODRDiagBaseError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
- NumVBases)
- << FirstNumVBases;
- ODRDiagBaseNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
- NumVBases)
- << SecondNumVBases;
- Diagnosed = true;
- break;
- }
-
- ArrayRef<CXXBaseSpecifier> FirstBases = FirstDD->bases();
- ArrayRef<CXXBaseSpecifier> SecondBases = SecondDD->bases();
- unsigned I = 0;
- for (I = 0; I < FirstNumBases; ++I) {
- const CXXBaseSpecifier FirstBase = FirstBases[I];
- const CXXBaseSpecifier SecondBase = SecondBases[I];
- if (computeODRHash(FirstBase.getType()) !=
- computeODRHash(SecondBase.getType())) {
- ODRDiagBaseError(FirstRecord->getLocation(),
- FirstBase.getSourceRange(), BaseType)
- << (I + 1) << FirstBase.getType();
- ODRDiagBaseNote(SecondRecord->getLocation(),
- SecondBase.getSourceRange(), BaseType)
- << (I + 1) << SecondBase.getType();
- break;
- }
-
- if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
- ODRDiagBaseError(FirstRecord->getLocation(),
- FirstBase.getSourceRange(), BaseVirtual)
- << (I + 1) << FirstBase.isVirtual() << FirstBase.getType();
- ODRDiagBaseNote(SecondRecord->getLocation(),
- SecondBase.getSourceRange(), BaseVirtual)
- << (I + 1) << SecondBase.isVirtual() << SecondBase.getType();
- break;
- }
-
- if (FirstBase.getAccessSpecifierAsWritten() !=
- SecondBase.getAccessSpecifierAsWritten()) {
- ODRDiagBaseError(FirstRecord->getLocation(),
- FirstBase.getSourceRange(), BaseAccess)
- << (I + 1) << FirstBase.getType()
- << (int)FirstBase.getAccessSpecifierAsWritten();
- ODRDiagBaseNote(SecondRecord->getLocation(),
- SecondBase.getSourceRange(), BaseAccess)
- << (I + 1) << SecondBase.getType()
- << (int)SecondBase.getAccessSpecifierAsWritten();
- break;
- }
- }
-
- if (I != FirstNumBases) {
- Diagnosed = true;
- break;
- }
- }
-
- const ClassTemplateDecl *FirstTemplate =
- FirstRecord->getDescribedClassTemplate();
- const ClassTemplateDecl *SecondTemplate =
- SecondRecord->getDescribedClassTemplate();
-
- assert(!FirstTemplate == !SecondTemplate &&
- "Both pointers should be null or non-null");
-
- if (FirstTemplate && SecondTemplate) {
- DeclHashes FirstTemplateHashes;
- DeclHashes SecondTemplateHashes;
-
- auto PopulateTemplateParameterHashs = [](DeclHashes &Hashes,
- const ClassTemplateDecl *TD) {
- for (auto *D : TD->getTemplateParameters()->asArray()) {
- Hashes.emplace_back(D, computeODRHash(D));
- }
- };
-
- PopulateTemplateParameterHashs(FirstTemplateHashes, FirstTemplate);
- PopulateTemplateParameterHashs(SecondTemplateHashes, SecondTemplate);
-
- assert(FirstTemplateHashes.size() == SecondTemplateHashes.size() &&
- "Number of template parameters should be equal.");
-
- auto FirstIt = FirstTemplateHashes.begin();
- auto FirstEnd = FirstTemplateHashes.end();
- auto SecondIt = SecondTemplateHashes.begin();
- for (; FirstIt != FirstEnd; ++FirstIt, ++SecondIt) {
- if (FirstIt->second == SecondIt->second)
- continue;
-
- const NamedDecl* FirstDecl = cast<NamedDecl>(FirstIt->first);
- const NamedDecl* SecondDecl = cast<NamedDecl>(SecondIt->first);
-
- assert(FirstDecl->getKind() == SecondDecl->getKind() &&
- "Parameter Decl's should be the same kind.");
-
- enum ODRTemplateDifference {
- ParamEmptyName,
- ParamName,
- ParamSingleDefaultArgument,
- ParamDifferentDefaultArgument,
- };
-
- auto hasDefaultArg = [](const NamedDecl *D) {
- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
- return TTP->hasDefaultArgument() &&
- !TTP->defaultArgumentWasInherited();
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D))
- return NTTP->hasDefaultArgument() &&
- !NTTP->defaultArgumentWasInherited();
- auto *TTP = cast<TemplateTemplateParmDecl>(D);
- return TTP->hasDefaultArgument() &&
- !TTP->defaultArgumentWasInherited();
- };
- bool hasFirstArg = hasDefaultArg(FirstDecl);
- bool hasSecondArg = hasDefaultArg(SecondDecl);
-
- ODRTemplateDifference ErrDiffType;
- ODRTemplateDifference NoteDiffType;
-
- DeclarationName FirstName = FirstDecl->getDeclName();
- DeclarationName SecondName = SecondDecl->getDeclName();
-
- if (FirstName != SecondName) {
- bool FirstNameEmpty =
- FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
- bool SecondNameEmpty = SecondName.isIdentifier() &&
- !SecondName.getAsIdentifierInfo();
- ErrDiffType = FirstNameEmpty ? ParamEmptyName : ParamName;
- NoteDiffType = SecondNameEmpty ? ParamEmptyName : ParamName;
- } else if (hasFirstArg == hasSecondArg)
- ErrDiffType = NoteDiffType = ParamDifferentDefaultArgument;
- else
- ErrDiffType = NoteDiffType = ParamSingleDefaultArgument;
-
- Diag(FirstDecl->getLocation(),
- diag::err_module_odr_violation_template_parameter)
- << FirstRecord << FirstModule.empty() << FirstModule
- << FirstDecl->getSourceRange() << ErrDiffType << hasFirstArg
- << FirstName;
- Diag(SecondDecl->getLocation(),
- diag::note_module_odr_violation_template_parameter)
- << SecondModule << SecondDecl->getSourceRange() << NoteDiffType
- << hasSecondArg << SecondName;
- break;
- }
-
- if (FirstIt != FirstEnd) {
- Diagnosed = true;
- break;
- }
- }
-
- DeclHashes FirstHashes;
- DeclHashes SecondHashes;
- const DeclContext *DC = FirstRecord;
- PopulateHashes(FirstHashes, FirstRecord, DC);
- PopulateHashes(SecondHashes, SecondRecord, DC);
-
- DiffResult DR = FindTypeDiffs(FirstHashes, SecondHashes);
- ODRMismatchDecl FirstDiffType = DR.FirstDiffType;
- ODRMismatchDecl SecondDiffType = DR.SecondDiffType;
- const Decl *FirstDecl = DR.FirstDecl;
- const Decl *SecondDecl = DR.SecondDecl;
-
- if (FirstDiffType == Other || SecondDiffType == Other) {
- DiagnoseODRUnexpected(DR, FirstRecord, FirstModule, SecondRecord,
- SecondModule);
+ if (DiagsEmitter.diagnoseMismatch(FirstRecord, RecordPair.first,
+ RecordPair.second)) {
Diagnosed = true;
break;
}
-
- if (FirstDiffType != SecondDiffType) {
- DiagnoseODRMismatch(DR, FirstRecord, FirstModule, SecondRecord,
- SecondModule);
- Diagnosed = true;
- break;
- }
-
- // Used with err_module_odr_violation_record and
- // note_module_odr_violation_record
- enum ODRCXXRecordDifference {
- StaticAssertCondition,
- StaticAssertMessage,
- StaticAssertOnlyMessage,
- MethodName,
- MethodDeleted,
- MethodDefaulted,
- MethodVirtual,
- MethodStatic,
- MethodVolatile,
- MethodConst,
- MethodInline,
- MethodNumberParameters,
- MethodParameterType,
- MethodParameterName,
- MethodParameterSingleDefaultArgument,
- MethodParameterDifferentDefaultArgument,
- MethodNoTemplateArguments,
- MethodDifferentNumberTemplateArguments,
- MethodDifferentTemplateArgument,
- MethodSingleBody,
- MethodDifferentBody,
- FriendTypeFunction,
- FriendType,
- FriendFunction,
- FunctionTemplateDifferentNumberParameters,
- FunctionTemplateParameterDifferentKind,
- FunctionTemplateParameterName,
- FunctionTemplateParameterSingleDefaultArgument,
- FunctionTemplateParameterDifferentDefaultArgument,
- FunctionTemplateParameterDifferentType,
- FunctionTemplatePackParameter,
- };
- auto ODRDiagDeclError = [FirstRecord, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRCXXRecordDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_record)
- << FirstRecord << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagDeclNote = [&SecondModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRCXXRecordDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_record)
- << SecondModule << Range << DiffType;
- };
-
- assert(FirstDiffType == SecondDiffType);
- switch (FirstDiffType) {
- case Other:
- case EndOfClass:
- case PublicSpecifer:
- case PrivateSpecifer:
- case ProtectedSpecifer:
- llvm_unreachable("Invalid diff type");
-
- case StaticAssert: {
- const StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
- const StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
-
- const Expr *FirstExpr = FirstSA->getAssertExpr();
- const Expr *SecondExpr = SecondSA->getAssertExpr();
- unsigned FirstODRHash = computeODRHash(FirstExpr);
- unsigned SecondODRHash = computeODRHash(SecondExpr);
- if (FirstODRHash != SecondODRHash) {
- ODRDiagDeclError(FirstExpr->getBeginLoc(),
- FirstExpr->getSourceRange(), StaticAssertCondition);
- ODRDiagDeclNote(SecondExpr->getBeginLoc(),
- SecondExpr->getSourceRange(), StaticAssertCondition);
- Diagnosed = true;
- break;
- }
-
- const StringLiteral *FirstStr = FirstSA->getMessage();
- const StringLiteral *SecondStr = SecondSA->getMessage();
- assert((FirstStr || SecondStr) && "Both messages cannot be empty");
- if ((FirstStr && !SecondStr) || (!FirstStr && SecondStr)) {
- SourceLocation FirstLoc, SecondLoc;
- SourceRange FirstRange, SecondRange;
- if (FirstStr) {
- FirstLoc = FirstStr->getBeginLoc();
- FirstRange = FirstStr->getSourceRange();
- } else {
- FirstLoc = FirstSA->getBeginLoc();
- FirstRange = FirstSA->getSourceRange();
- }
- if (SecondStr) {
- SecondLoc = SecondStr->getBeginLoc();
- SecondRange = SecondStr->getSourceRange();
- } else {
- SecondLoc = SecondSA->getBeginLoc();
- SecondRange = SecondSA->getSourceRange();
- }
- ODRDiagDeclError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
- << (FirstStr == nullptr);
- ODRDiagDeclNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
- << (SecondStr == nullptr);
- Diagnosed = true;
- break;
- }
-
- if (FirstStr && SecondStr &&
- FirstStr->getString() != SecondStr->getString()) {
- ODRDiagDeclError(FirstStr->getBeginLoc(), FirstStr->getSourceRange(),
- StaticAssertMessage);
- ODRDiagDeclNote(SecondStr->getBeginLoc(), SecondStr->getSourceRange(),
- StaticAssertMessage);
- Diagnosed = true;
- break;
- }
- break;
- }
- case Field: {
- Diagnosed = ODRDiagField(FirstRecord, FirstModule, SecondModule,
- cast<FieldDecl>(FirstDecl),
- cast<FieldDecl>(SecondDecl));
- break;
- }
- case CXXMethod: {
- enum {
- DiagMethod,
- DiagConstructor,
- DiagDestructor,
- } FirstMethodType,
- SecondMethodType;
- auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl* D) {
- if (isa<CXXConstructorDecl>(D)) return DiagConstructor;
- if (isa<CXXDestructorDecl>(D)) return DiagDestructor;
- return DiagMethod;
- };
- const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
- const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
- FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
- SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
- DeclarationName FirstName = FirstMethod->getDeclName();
- DeclarationName SecondName = SecondMethod->getDeclName();
- auto DiagMethodError = [&ODRDiagDeclError, FirstMethod, FirstMethodType,
- FirstName](ODRCXXRecordDifference DiffType) {
- return ODRDiagDeclError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), DiffType)
- << FirstMethodType << FirstName;
- };
- auto DiagMethodNote = [&ODRDiagDeclNote, SecondMethod, SecondMethodType,
- SecondName](ODRCXXRecordDifference DiffType) {
- return ODRDiagDeclNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), DiffType)
- << SecondMethodType << SecondName;
- };
-
- if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
- DiagMethodError(MethodName);
- DiagMethodNote(MethodName);
- Diagnosed = true;
- break;
- }
-
- const bool FirstDeleted = FirstMethod->isDeletedAsWritten();
- const bool SecondDeleted = SecondMethod->isDeletedAsWritten();
- if (FirstDeleted != SecondDeleted) {
- DiagMethodError(MethodDeleted) << FirstDeleted;
- DiagMethodNote(MethodDeleted) << SecondDeleted;
- Diagnosed = true;
- break;
- }
-
- const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted();
- const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted();
- if (FirstDefaulted != SecondDefaulted) {
- DiagMethodError(MethodDefaulted) << FirstDefaulted;
- DiagMethodNote(MethodDefaulted) << SecondDefaulted;
- Diagnosed = true;
- break;
- }
-
- const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
- const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
- const bool FirstPure = FirstMethod->isPure();
- const bool SecondPure = SecondMethod->isPure();
- if ((FirstVirtual || SecondVirtual) &&
- (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
- DiagMethodError(MethodVirtual) << FirstPure << FirstVirtual;
- DiagMethodNote(MethodVirtual) << SecondPure << SecondVirtual;
- Diagnosed = true;
- break;
- }
-
- // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging,
- // FirstDecl is the canonical Decl of SecondDecl, so the storage
- // class needs to be checked instead.
- StorageClass FirstStorage = FirstMethod->getStorageClass();
- StorageClass SecondStorage = SecondMethod->getStorageClass();
- const bool FirstStatic = FirstStorage == SC_Static;
- const bool SecondStatic = SecondStorage == SC_Static;
- if (FirstStatic != SecondStatic) {
- DiagMethodError(MethodStatic) << FirstStatic;
- DiagMethodNote(MethodStatic) << SecondStatic;
- Diagnosed = true;
- break;
- }
-
- const bool FirstVolatile = FirstMethod->isVolatile();
- const bool SecondVolatile = SecondMethod->isVolatile();
- if (FirstVolatile != SecondVolatile) {
- DiagMethodError(MethodVolatile) << FirstVolatile;
- DiagMethodNote(MethodVolatile) << SecondVolatile;
- Diagnosed = true;
- break;
- }
-
- const bool FirstConst = FirstMethod->isConst();
- const bool SecondConst = SecondMethod->isConst();
- if (FirstConst != SecondConst) {
- DiagMethodError(MethodConst) << FirstConst;
- DiagMethodNote(MethodConst) << SecondConst;
- Diagnosed = true;
- break;
- }
-
- const bool FirstInline = FirstMethod->isInlineSpecified();
- const bool SecondInline = SecondMethod->isInlineSpecified();
- if (FirstInline != SecondInline) {
- DiagMethodError(MethodInline) << FirstInline;
- DiagMethodNote(MethodInline) << SecondInline;
- Diagnosed = true;
- break;
- }
-
- const unsigned FirstNumParameters = FirstMethod->param_size();
- const unsigned SecondNumParameters = SecondMethod->param_size();
- if (FirstNumParameters != SecondNumParameters) {
- DiagMethodError(MethodNumberParameters) << FirstNumParameters;
- DiagMethodNote(MethodNumberParameters) << SecondNumParameters;
- Diagnosed = true;
- break;
- }
-
- // Need this status boolean to know when break out of the switch.
- bool ParameterMismatch = false;
- for (unsigned I = 0; I < FirstNumParameters; ++I) {
- const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
- const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
-
- QualType FirstParamType = FirstParam->getType();
- QualType SecondParamType = SecondParam->getType();
- if (FirstParamType != SecondParamType &&
- computeODRHash(FirstParamType) !=
- computeODRHash(SecondParamType)) {
- if (const DecayedType *ParamDecayedType =
- FirstParamType->getAs<DecayedType>()) {
- DiagMethodError(MethodParameterType)
- << (I + 1) << FirstParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- DiagMethodError(MethodParameterType)
- << (I + 1) << FirstParamType << false;
- }
-
- if (const DecayedType *ParamDecayedType =
- SecondParamType->getAs<DecayedType>()) {
- DiagMethodNote(MethodParameterType)
- << (I + 1) << SecondParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- DiagMethodNote(MethodParameterType)
- << (I + 1) << SecondParamType << false;
- }
- ParameterMismatch = true;
- break;
- }
-
- DeclarationName FirstParamName = FirstParam->getDeclName();
- DeclarationName SecondParamName = SecondParam->getDeclName();
- if (FirstParamName != SecondParamName) {
- DiagMethodError(MethodParameterName) << (I + 1) << FirstParamName;
- DiagMethodNote(MethodParameterName) << (I + 1) << SecondParamName;
- ParameterMismatch = true;
- break;
- }
-
- const Expr *FirstInit = FirstParam->getInit();
- const Expr *SecondInit = SecondParam->getInit();
- if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
- DiagMethodError(MethodParameterSingleDefaultArgument)
- << (I + 1) << (FirstInit == nullptr)
- << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
- DiagMethodNote(MethodParameterSingleDefaultArgument)
- << (I + 1) << (SecondInit == nullptr)
- << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
- ParameterMismatch = true;
- break;
- }
-
- if (FirstInit && SecondInit &&
- computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
- DiagMethodError(MethodParameterDifferentDefaultArgument)
- << (I + 1) << FirstInit->getSourceRange();
- DiagMethodNote(MethodParameterDifferentDefaultArgument)
- << (I + 1) << SecondInit->getSourceRange();
- ParameterMismatch = true;
- break;
- }
- }
-
- if (ParameterMismatch) {
- Diagnosed = true;
- break;
- }
-
- const TemplateArgumentList *FirstTemplateArgs =
- FirstMethod->getTemplateSpecializationArgs();
- const TemplateArgumentList *SecondTemplateArgs =
- SecondMethod->getTemplateSpecializationArgs();
-
- if ((FirstTemplateArgs && !SecondTemplateArgs) ||
- (!FirstTemplateArgs && SecondTemplateArgs)) {
- DiagMethodError(MethodNoTemplateArguments)
- << (FirstTemplateArgs != nullptr);
- DiagMethodNote(MethodNoTemplateArguments)
- << (SecondTemplateArgs != nullptr);
- Diagnosed = true;
- break;
- }
-
- if (FirstTemplateArgs && SecondTemplateArgs) {
- // Remove pack expansions from argument list.
- auto ExpandTemplateArgumentList =
- [](const TemplateArgumentList *TAL) {
- llvm::SmallVector<const TemplateArgument *, 8> ExpandedList;
- for (const TemplateArgument &TA : TAL->asArray()) {
- if (TA.getKind() != TemplateArgument::Pack) {
- ExpandedList.push_back(&TA);
- continue;
- }
- llvm::append_range(ExpandedList, llvm::make_pointer_range(
- TA.getPackAsArray()));
- }
- return ExpandedList;
- };
- llvm::SmallVector<const TemplateArgument *, 8> FirstExpandedList =
- ExpandTemplateArgumentList(FirstTemplateArgs);
- llvm::SmallVector<const TemplateArgument *, 8> SecondExpandedList =
- ExpandTemplateArgumentList(SecondTemplateArgs);
-
- if (FirstExpandedList.size() != SecondExpandedList.size()) {
- DiagMethodError(MethodDifferentNumberTemplateArguments)
- << (unsigned)FirstExpandedList.size();
- DiagMethodNote(MethodDifferentNumberTemplateArguments)
- << (unsigned)SecondExpandedList.size();
- Diagnosed = true;
- break;
- }
-
- bool TemplateArgumentMismatch = false;
- for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
- const TemplateArgument &FirstTA = *FirstExpandedList[i],
- &SecondTA = *SecondExpandedList[i];
- if (computeODRHash(FirstTA) == computeODRHash(SecondTA)) {
- continue;
- }
-
- DiagMethodError(MethodDifferentTemplateArgument)
- << FirstTA << i + 1;
- DiagMethodNote(MethodDifferentTemplateArgument)
- << SecondTA << i + 1;
- TemplateArgumentMismatch = true;
- break;
- }
-
- if (TemplateArgumentMismatch) {
- Diagnosed = true;
- break;
- }
- }
-
- // Compute the hash of the method as if it has no body.
- auto ComputeCXXMethodODRHash = [](const CXXMethodDecl *D) {
- ODRHash Hasher;
- Hasher.AddFunctionDecl(D, true /*SkipBody*/);
- return Hasher.CalculateHash();
- };
-
- // Compare the hash generated to the hash stored. A difference means
- // that a body was present in the original source. Due to merging,
- // the standard way of detecting a body will not work.
- const bool HasFirstBody =
- ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
- const bool HasSecondBody =
- ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
-
- if (HasFirstBody != HasSecondBody) {
- DiagMethodError(MethodSingleBody) << HasFirstBody;
- DiagMethodNote(MethodSingleBody) << HasSecondBody;
- Diagnosed = true;
- break;
- }
-
- if (HasFirstBody && HasSecondBody) {
- DiagMethodError(MethodDifferentBody);
- DiagMethodNote(MethodDifferentBody);
- Diagnosed = true;
- break;
- }
-
- break;
- }
- case TypeAlias:
- case TypeDef: {
- Diagnosed = ODRDiagTypeDefOrAlias(
- FirstRecord, FirstModule, SecondModule,
- cast<TypedefNameDecl>(FirstDecl), cast<TypedefNameDecl>(SecondDecl),
- FirstDiffType == TypeAlias);
- break;
- }
- case Var: {
- Diagnosed =
- ODRDiagVar(FirstRecord, FirstModule, SecondModule,
- cast<VarDecl>(FirstDecl), cast<VarDecl>(SecondDecl));
- break;
- }
- case Friend: {
- const FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
- const FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
-
- const NamedDecl *FirstND = FirstFriend->getFriendDecl();
- const NamedDecl *SecondND = SecondFriend->getFriendDecl();
-
- TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
- TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
-
- if (FirstND && SecondND) {
- ODRDiagDeclError(FirstFriend->getFriendLoc(),
- FirstFriend->getSourceRange(), FriendFunction)
- << FirstND;
- ODRDiagDeclNote(SecondFriend->getFriendLoc(),
- SecondFriend->getSourceRange(), FriendFunction)
- << SecondND;
- Diagnosed = true;
- break;
- }
-
- if (FirstTSI && SecondTSI) {
- QualType FirstFriendType = FirstTSI->getType();
- QualType SecondFriendType = SecondTSI->getType();
- assert(computeODRHash(FirstFriendType) !=
- computeODRHash(SecondFriendType));
- ODRDiagDeclError(FirstFriend->getFriendLoc(),
- FirstFriend->getSourceRange(), FriendType)
- << FirstFriendType;
- ODRDiagDeclNote(SecondFriend->getFriendLoc(),
- SecondFriend->getSourceRange(), FriendType)
- << SecondFriendType;
- Diagnosed = true;
- break;
- }
-
- ODRDiagDeclError(FirstFriend->getFriendLoc(),
- FirstFriend->getSourceRange(), FriendTypeFunction)
- << (FirstTSI == nullptr);
- ODRDiagDeclNote(SecondFriend->getFriendLoc(),
- SecondFriend->getSourceRange(), FriendTypeFunction)
- << (SecondTSI == nullptr);
- Diagnosed = true;
- break;
- }
- case FunctionTemplate: {
- const FunctionTemplateDecl *FirstTemplate =
- cast<FunctionTemplateDecl>(FirstDecl);
- const FunctionTemplateDecl *SecondTemplate =
- cast<FunctionTemplateDecl>(SecondDecl);
-
- TemplateParameterList *FirstTPL =
- FirstTemplate->getTemplateParameters();
- TemplateParameterList *SecondTPL =
- SecondTemplate->getTemplateParameters();
-
- auto DiagTemplateError = [&ODRDiagDeclError, FirstTemplate](
- ODRCXXRecordDifference DiffType) {
- return ODRDiagDeclError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(), DiffType)
- << FirstTemplate;
- };
- auto DiagTemplateNote = [&ODRDiagDeclNote, SecondTemplate](
- ODRCXXRecordDifference DiffType) {
- return ODRDiagDeclNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(), DiffType)
- << SecondTemplate;
- };
-
- if (FirstTPL->size() != SecondTPL->size()) {
- DiagTemplateError(FunctionTemplateDifferentNumberParameters)
- << FirstTPL->size();
- DiagTemplateNote(FunctionTemplateDifferentNumberParameters)
- << SecondTPL->size();
- Diagnosed = true;
- break;
- }
-
- bool ParameterMismatch = false;
- for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {
- NamedDecl *FirstParam = FirstTPL->getParam(i);
- NamedDecl *SecondParam = SecondTPL->getParam(i);
-
- if (FirstParam->getKind() != SecondParam->getKind()) {
- enum {
- TemplateTypeParameter,
- NonTypeTemplateParameter,
- TemplateTemplateParameter,
- };
- auto GetParamType = [](NamedDecl *D) {
- switch (D->getKind()) {
- default:
- llvm_unreachable("Unexpected template parameter type");
- case Decl::TemplateTypeParm:
- return TemplateTypeParameter;
- case Decl::NonTypeTemplateParm:
- return NonTypeTemplateParameter;
- case Decl::TemplateTemplateParm:
- return TemplateTemplateParameter;
- }
- };
-
- DiagTemplateError(FunctionTemplateParameterDifferentKind)
- << (i + 1) << GetParamType(FirstParam);
- DiagTemplateNote(FunctionTemplateParameterDifferentKind)
- << (i + 1) << GetParamType(SecondParam);
- ParameterMismatch = true;
- break;
- }
-
- if (FirstParam->getName() != SecondParam->getName()) {
- DiagTemplateError(FunctionTemplateParameterName)
- << (i + 1) << (bool)FirstParam->getIdentifier() << FirstParam;
- DiagTemplateNote(FunctionTemplateParameterName)
- << (i + 1) << (bool)SecondParam->getIdentifier() << SecondParam;
- ParameterMismatch = true;
- break;
- }
-
- if (isa<TemplateTypeParmDecl>(FirstParam) &&
- isa<TemplateTypeParmDecl>(SecondParam)) {
- TemplateTypeParmDecl *FirstTTPD =
- cast<TemplateTypeParmDecl>(FirstParam);
- TemplateTypeParmDecl *SecondTTPD =
- cast<TemplateTypeParmDecl>(SecondParam);
- bool HasFirstDefaultArgument =
- FirstTTPD->hasDefaultArgument() &&
- !FirstTTPD->defaultArgumentWasInherited();
- bool HasSecondDefaultArgument =
- SecondTTPD->hasDefaultArgument() &&
- !SecondTTPD->defaultArgumentWasInherited();
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
- << (i + 1) << HasFirstDefaultArgument;
- DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
- << (i + 1) << HasSecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
-
- if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
- QualType FirstType = FirstTTPD->getDefaultArgument();
- QualType SecondType = SecondTTPD->getDefaultArgument();
- if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
- DiagTemplateError(
- FunctionTemplateParameterDifferentDefaultArgument)
- << (i + 1) << FirstType;
- DiagTemplateNote(
- FunctionTemplateParameterDifferentDefaultArgument)
- << (i + 1) << SecondType;
- ParameterMismatch = true;
- break;
- }
- }
-
- if (FirstTTPD->isParameterPack() !=
- SecondTTPD->isParameterPack()) {
- DiagTemplateError(FunctionTemplatePackParameter)
- << (i + 1) << FirstTTPD->isParameterPack();
- DiagTemplateNote(FunctionTemplatePackParameter)
- << (i + 1) << SecondTTPD->isParameterPack();
- ParameterMismatch = true;
- break;
- }
- }
-
- if (isa<TemplateTemplateParmDecl>(FirstParam) &&
- isa<TemplateTemplateParmDecl>(SecondParam)) {
- TemplateTemplateParmDecl *FirstTTPD =
- cast<TemplateTemplateParmDecl>(FirstParam);
- TemplateTemplateParmDecl *SecondTTPD =
- cast<TemplateTemplateParmDecl>(SecondParam);
-
- TemplateParameterList *FirstTPL =
- FirstTTPD->getTemplateParameters();
- TemplateParameterList *SecondTPL =
- SecondTTPD->getTemplateParameters();
-
- auto ComputeTemplateParameterListODRHash =
- [](const TemplateParameterList *TPL) {
- assert(TPL);
- ODRHash Hasher;
- Hasher.AddTemplateParameterList(TPL);
- return Hasher.CalculateHash();
- };
-
- if (ComputeTemplateParameterListODRHash(FirstTPL) !=
- ComputeTemplateParameterListODRHash(SecondTPL)) {
- DiagTemplateError(FunctionTemplateParameterDifferentType)
- << (i + 1);
- DiagTemplateNote(FunctionTemplateParameterDifferentType)
- << (i + 1);
- ParameterMismatch = true;
- break;
- }
-
- bool HasFirstDefaultArgument =
- FirstTTPD->hasDefaultArgument() &&
- !FirstTTPD->defaultArgumentWasInherited();
- bool HasSecondDefaultArgument =
- SecondTTPD->hasDefaultArgument() &&
- !SecondTTPD->defaultArgumentWasInherited();
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
- << (i + 1) << HasFirstDefaultArgument;
- DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
- << (i + 1) << HasSecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
-
- if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
- TemplateArgument FirstTA =
- FirstTTPD->getDefaultArgument().getArgument();
- TemplateArgument SecondTA =
- SecondTTPD->getDefaultArgument().getArgument();
- if (computeODRHash(FirstTA) != computeODRHash(SecondTA)) {
- DiagTemplateError(
- FunctionTemplateParameterDifferentDefaultArgument)
- << (i + 1) << FirstTA;
- DiagTemplateNote(
- FunctionTemplateParameterDifferentDefaultArgument)
- << (i + 1) << SecondTA;
- ParameterMismatch = true;
- break;
- }
- }
-
- if (FirstTTPD->isParameterPack() !=
- SecondTTPD->isParameterPack()) {
- DiagTemplateError(FunctionTemplatePackParameter)
- << (i + 1) << FirstTTPD->isParameterPack();
- DiagTemplateNote(FunctionTemplatePackParameter)
- << (i + 1) << SecondTTPD->isParameterPack();
- ParameterMismatch = true;
- break;
- }
- }
-
- if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
- isa<NonTypeTemplateParmDecl>(SecondParam)) {
- NonTypeTemplateParmDecl *FirstNTTPD =
- cast<NonTypeTemplateParmDecl>(FirstParam);
- NonTypeTemplateParmDecl *SecondNTTPD =
- cast<NonTypeTemplateParmDecl>(SecondParam);
-
- QualType FirstType = FirstNTTPD->getType();
- QualType SecondType = SecondNTTPD->getType();
- if (computeODRHash(FirstType) != computeODRHash(SecondType)) {
- DiagTemplateError(FunctionTemplateParameterDifferentType)
- << (i + 1);
- DiagTemplateNote(FunctionTemplateParameterDifferentType)
- << (i + 1);
- ParameterMismatch = true;
- break;
- }
-
- bool HasFirstDefaultArgument =
- FirstNTTPD->hasDefaultArgument() &&
- !FirstNTTPD->defaultArgumentWasInherited();
- bool HasSecondDefaultArgument =
- SecondNTTPD->hasDefaultArgument() &&
- !SecondNTTPD->defaultArgumentWasInherited();
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- DiagTemplateError(FunctionTemplateParameterSingleDefaultArgument)
- << (i + 1) << HasFirstDefaultArgument;
- DiagTemplateNote(FunctionTemplateParameterSingleDefaultArgument)
- << (i + 1) << HasSecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
-
- if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
- Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument();
- Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument();
- if (computeODRHash(FirstDefaultArgument) !=
- computeODRHash(SecondDefaultArgument)) {
- DiagTemplateError(
- FunctionTemplateParameterDifferentDefaultArgument)
- << (i + 1) << FirstDefaultArgument;
- DiagTemplateNote(
- FunctionTemplateParameterDifferentDefaultArgument)
- << (i + 1) << SecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
- }
-
- if (FirstNTTPD->isParameterPack() !=
- SecondNTTPD->isParameterPack()) {
- DiagTemplateError(FunctionTemplatePackParameter)
- << (i + 1) << FirstNTTPD->isParameterPack();
- DiagTemplateNote(FunctionTemplatePackParameter)
- << (i + 1) << SecondNTTPD->isParameterPack();
- ParameterMismatch = true;
- break;
- }
- }
- }
-
- if (ParameterMismatch) {
- Diagnosed = true;
- break;
- }
-
- break;
- }
- }
-
- if (Diagnosed)
- continue;
-
- Diag(FirstDecl->getLocation(),
- diag::err_module_odr_violation_mismatch_decl_unknown)
- << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
- << FirstDecl->getSourceRange();
- Diag(SecondDecl->getLocation(),
- diag::note_module_odr_violation_mismatch_decl_unknown)
- << SecondModule << FirstDiffType << SecondDecl->getSourceRange();
- Diagnosed = true;
}
if (!Diagnosed) {
@@ -11021,158 +9705,39 @@ void ASTReader::diagnoseOdrViolations() {
// FIXME: How can this even happen?
Diag(Merge.first->getLocation(),
diag::err_module_odr_violation_different_instantiations)
- << Merge.first;
+ << Merge.first;
}
}
- // Issue ODR failures diagnostics for functions.
- for (auto &Merge : FunctionOdrMergeFailures) {
- enum ODRFunctionDifference {
- ReturnType,
- ParameterName,
- ParameterType,
- ParameterSingleDefaultArgument,
- ParameterDifferentDefaultArgument,
- FunctionBody,
- };
-
- FunctionDecl *FirstFunction = Merge.first;
- std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
+ // Issue any pending ODR-failure diagnostics for RecordDecl in C/ObjC. Note
+ // that in C++ this is done as a part of CXXRecordDecl ODR checking.
+ for (auto &Merge : RecordOdrMergeFailures) {
+ // If we've already pointed out a specific problem with this class, don't
+ // bother issuing a general "something's different" diagnostic.
+ if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
+ continue;
+ RecordDecl *FirstRecord = Merge.first;
bool Diagnosed = false;
- for (auto &SecondFunction : Merge.second) {
-
- if (FirstFunction == SecondFunction)
- continue;
-
- std::string SecondModule =
- getOwningModuleNameForDiagnostic(SecondFunction);
-
- auto ODRDiagError = [FirstFunction, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRFunctionDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_function)
- << FirstFunction << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagNote = [&SecondModule, this](SourceLocation Loc,
- SourceRange Range,
- ODRFunctionDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_function)
- << SecondModule << Range << DiffType;
- };
-
- if (computeODRHash(FirstFunction->getReturnType()) !=
- computeODRHash(SecondFunction->getReturnType())) {
- ODRDiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
- FirstFunction->getReturnTypeSourceRange(), ReturnType)
- << FirstFunction->getReturnType();
- ODRDiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
- SecondFunction->getReturnTypeSourceRange(), ReturnType)
- << SecondFunction->getReturnType();
+ for (auto *SecondRecord : Merge.second) {
+ if (DiagsEmitter.diagnoseMismatch(FirstRecord, SecondRecord)) {
Diagnosed = true;
break;
}
+ }
+ (void)Diagnosed;
+ assert(Diagnosed && "Unable to emit ODR diagnostic.");
+ }
- assert(FirstFunction->param_size() == SecondFunction->param_size() &&
- "Merged functions with different number of parameters");
-
- size_t ParamSize = FirstFunction->param_size();
- bool ParameterMismatch = false;
- for (unsigned I = 0; I < ParamSize; ++I) {
- const ParmVarDecl *FirstParam = FirstFunction->getParamDecl(I);
- const ParmVarDecl *SecondParam = SecondFunction->getParamDecl(I);
-
- assert(getContext().hasSameType(FirstParam->getType(),
- SecondParam->getType()) &&
- "Merged function has different parameter types.");
-
- if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
- ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
- ParameterName)
- << I + 1 << FirstParam->getDeclName();
- ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
- ParameterName)
- << I + 1 << SecondParam->getDeclName();
- ParameterMismatch = true;
- break;
- };
-
- QualType FirstParamType = FirstParam->getType();
- QualType SecondParamType = SecondParam->getType();
- if (FirstParamType != SecondParamType &&
- computeODRHash(FirstParamType) != computeODRHash(SecondParamType)) {
- if (const DecayedType *ParamDecayedType =
- FirstParamType->getAs<DecayedType>()) {
- ODRDiagError(FirstParam->getLocation(),
- FirstParam->getSourceRange(), ParameterType)
- << (I + 1) << FirstParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- ODRDiagError(FirstParam->getLocation(),
- FirstParam->getSourceRange(), ParameterType)
- << (I + 1) << FirstParamType << false;
- }
-
- if (const DecayedType *ParamDecayedType =
- SecondParamType->getAs<DecayedType>()) {
- ODRDiagNote(SecondParam->getLocation(),
- SecondParam->getSourceRange(), ParameterType)
- << (I + 1) << SecondParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- ODRDiagNote(SecondParam->getLocation(),
- SecondParam->getSourceRange(), ParameterType)
- << (I + 1) << SecondParamType << false;
- }
- ParameterMismatch = true;
- break;
- }
-
- const Expr *FirstInit = FirstParam->getInit();
- const Expr *SecondInit = SecondParam->getInit();
- if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
- ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
- ParameterSingleDefaultArgument)
- << (I + 1) << (FirstInit == nullptr)
- << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
- ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
- ParameterSingleDefaultArgument)
- << (I + 1) << (SecondInit == nullptr)
- << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
- ParameterMismatch = true;
- break;
- }
-
- if (FirstInit && SecondInit &&
- computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
- ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
- ParameterDifferentDefaultArgument)
- << (I + 1) << FirstInit->getSourceRange();
- ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
- ParameterDifferentDefaultArgument)
- << (I + 1) << SecondInit->getSourceRange();
- ParameterMismatch = true;
- break;
- }
-
- assert(computeODRHash(FirstParam) == computeODRHash(SecondParam) &&
- "Undiagnosed parameter difference.");
- }
-
- if (ParameterMismatch) {
+ // Issue ODR failures diagnostics for functions.
+ for (auto &Merge : FunctionOdrMergeFailures) {
+ FunctionDecl *FirstFunction = Merge.first;
+ bool Diagnosed = false;
+ for (auto &SecondFunction : Merge.second) {
+ if (DiagsEmitter.diagnoseMismatch(FirstFunction, SecondFunction)) {
Diagnosed = true;
break;
}
-
- // If no error has been generated before now, assume the problem is in
- // the body and generate a message.
- ODRDiagError(FirstFunction->getLocation(),
- FirstFunction->getSourceRange(), FunctionBody);
- ODRDiagNote(SecondFunction->getLocation(),
- SecondFunction->getSourceRange(), FunctionBody);
- Diagnosed = true;
- break;
}
(void)Diagnosed;
assert(Diagnosed && "Unable to emit ODR diagnostic.");
@@ -11180,164 +9745,57 @@ void ASTReader::diagnoseOdrViolations() {
// Issue ODR failures diagnostics for enums.
for (auto &Merge : EnumOdrMergeFailures) {
- enum ODREnumDifference {
- SingleScopedEnum,
- EnumTagKeywordMismatch,
- SingleSpecifiedType,
- DifferentSpecifiedTypes,
- DifferentNumberEnumConstants,
- EnumConstantName,
- EnumConstantSingleInitializer,
- EnumConstantDifferentInitializer,
- };
-
// If we've already pointed out a specific problem with this enum, don't
// bother issuing a general "something's different" diagnostic.
if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
continue;
EnumDecl *FirstEnum = Merge.first;
- std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
-
- using DeclHashes =
- llvm::SmallVector<std::pair<EnumConstantDecl *, unsigned>, 4>;
- auto PopulateHashes = [FirstEnum](DeclHashes &Hashes, EnumDecl *Enum) {
- for (auto *D : Enum->decls()) {
- // Due to decl merging, the first EnumDecl is the parent of
- // Decls in both records.
- if (!ODRHash::isDeclToBeProcessed(D, FirstEnum))
- continue;
- assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
- Hashes.emplace_back(cast<EnumConstantDecl>(D), computeODRHash(D));
- }
- };
- DeclHashes FirstHashes;
- PopulateHashes(FirstHashes, FirstEnum);
bool Diagnosed = false;
for (auto &SecondEnum : Merge.second) {
-
- if (FirstEnum == SecondEnum)
- continue;
-
- std::string SecondModule =
- getOwningModuleNameForDiagnostic(SecondEnum);
-
- auto ODRDiagError = [FirstEnum, &FirstModule,
- this](const auto *DiagAnchor,
- ODREnumDifference DiffType) {
- return Diag(DiagAnchor->getLocation(),
- diag::err_module_odr_violation_enum)
- << FirstEnum << FirstModule.empty() << FirstModule
- << DiagAnchor->getSourceRange() << DiffType;
- };
- auto ODRDiagNote = [&SecondModule, this](const auto *DiagAnchor,
- ODREnumDifference DiffType) {
- return Diag(DiagAnchor->getLocation(),
- diag::note_module_odr_violation_enum)
- << SecondModule << DiagAnchor->getSourceRange() << DiffType;
- };
-
- if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
- ODRDiagError(FirstEnum, SingleScopedEnum) << FirstEnum->isScoped();
- ODRDiagNote(SecondEnum, SingleScopedEnum) << SecondEnum->isScoped();
+ if (DiagsEmitter.diagnoseMismatch(FirstEnum, SecondEnum)) {
Diagnosed = true;
- continue;
+ break;
}
+ }
+ (void)Diagnosed;
+ assert(Diagnosed && "Unable to emit ODR diagnostic.");
+ }
- if (FirstEnum->isScoped() && SecondEnum->isScoped()) {
- if (FirstEnum->isScopedUsingClassTag() !=
- SecondEnum->isScopedUsingClassTag()) {
- ODRDiagError(FirstEnum, EnumTagKeywordMismatch)
- << FirstEnum->isScopedUsingClassTag();
- ODRDiagNote(SecondEnum, EnumTagKeywordMismatch)
- << SecondEnum->isScopedUsingClassTag();
- Diagnosed = true;
- continue;
- }
- }
+ for (auto &Merge : ObjCInterfaceOdrMergeFailures) {
+ // If we've already pointed out a specific problem with this interface,
+ // don't bother issuing a general "something's different" diagnostic.
+ if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
+ continue;
- QualType FirstUnderlyingType =
- FirstEnum->getIntegerTypeSourceInfo()
- ? FirstEnum->getIntegerTypeSourceInfo()->getType()
- : QualType();
- QualType SecondUnderlyingType =
- SecondEnum->getIntegerTypeSourceInfo()
- ? SecondEnum->getIntegerTypeSourceInfo()->getType()
- : QualType();
- if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
- ODRDiagError(FirstEnum, SingleSpecifiedType)
- << !FirstUnderlyingType.isNull();
- ODRDiagNote(SecondEnum, SingleSpecifiedType)
- << !SecondUnderlyingType.isNull();
+ bool Diagnosed = false;
+ ObjCInterfaceDecl *FirstID = Merge.first;
+ for (auto &InterfacePair : Merge.second) {
+ if (DiagsEmitter.diagnoseMismatch(FirstID, InterfacePair.first,
+ InterfacePair.second)) {
Diagnosed = true;
- continue;
- }
-
- if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
- if (computeODRHash(FirstUnderlyingType) !=
- computeODRHash(SecondUnderlyingType)) {
- ODRDiagError(FirstEnum, DifferentSpecifiedTypes)
- << FirstUnderlyingType;
- ODRDiagNote(SecondEnum, DifferentSpecifiedTypes)
- << SecondUnderlyingType;
- Diagnosed = true;
- continue;
- }
+ break;
}
+ }
+ (void)Diagnosed;
+ assert(Diagnosed && "Unable to emit ODR diagnostic.");
+ }
- DeclHashes SecondHashes;
- PopulateHashes(SecondHashes, SecondEnum);
+ for (auto &Merge : ObjCProtocolOdrMergeFailures) {
+ // If we've already pointed out a specific problem with this protocol,
+ // don't bother issuing a general "something's different" diagnostic.
+ if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
+ continue;
- if (FirstHashes.size() != SecondHashes.size()) {
- ODRDiagError(FirstEnum, DifferentNumberEnumConstants)
- << (int)FirstHashes.size();
- ODRDiagNote(SecondEnum, DifferentNumberEnumConstants)
- << (int)SecondHashes.size();
+ ObjCProtocolDecl *FirstProtocol = Merge.first;
+ bool Diagnosed = false;
+ for (auto &ProtocolPair : Merge.second) {
+ if (DiagsEmitter.diagnoseMismatch(FirstProtocol, ProtocolPair.first,
+ ProtocolPair.second)) {
Diagnosed = true;
- continue;
- }
-
- for (unsigned I = 0; I < FirstHashes.size(); ++I) {
- if (FirstHashes[I].second == SecondHashes[I].second)
- continue;
- const EnumConstantDecl *FirstConstant = FirstHashes[I].first;
- const EnumConstantDecl *SecondConstant = SecondHashes[I].first;
-
- if (FirstConstant->getDeclName() != SecondConstant->getDeclName()) {
-
- ODRDiagError(FirstConstant, EnumConstantName)
- << I + 1 << FirstConstant;
- ODRDiagNote(SecondConstant, EnumConstantName)
- << I + 1 << SecondConstant;
- Diagnosed = true;
- break;
- }
-
- const Expr *FirstInit = FirstConstant->getInitExpr();
- const Expr *SecondInit = SecondConstant->getInitExpr();
- if (!FirstInit && !SecondInit)
- continue;
-
- if (!FirstInit || !SecondInit) {
- ODRDiagError(FirstConstant, EnumConstantSingleInitializer)
- << I + 1 << FirstConstant << (FirstInit != nullptr);
- ODRDiagNote(SecondConstant, EnumConstantSingleInitializer)
- << I + 1 << SecondConstant << (SecondInit != nullptr);
- Diagnosed = true;
- break;
- }
-
- if (computeODRHash(FirstInit) != computeODRHash(SecondInit)) {
- ODRDiagError(FirstConstant, EnumConstantDifferentInitializer)
- << I + 1 << FirstConstant;
- ODRDiagNote(SecondConstant, EnumConstantDifferentInitializer)
- << I + 1 << SecondConstant;
- Diagnosed = true;
- break;
- }
+ break;
}
}
-
(void)Diagnosed;
assert(Diagnosed && "Unable to emit ODR diagnostic.");
}
@@ -11619,7 +10077,16 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_atomic_default_mem_order:
C = new (Context) OMPAtomicDefaultMemOrderClause();
break;
- case llvm::omp::OMPC_private:
+ case llvm::omp::OMPC_at:
+ C = new (Context) OMPAtClause();
+ break;
+ case llvm::omp::OMPC_severity:
+ C = new (Context) OMPSeverityClause();
+ break;
+ case llvm::omp::OMPC_message:
+ C = new (Context) OMPMessageClause();
+ break;
+ case llvm::omp::OMPC_private:
C = OMPPrivateClause::CreateEmpty(Context, Record.readInt());
break;
case llvm::omp::OMPC_firstprivate:
@@ -11805,6 +10272,9 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_align:
C = new (Context) OMPAlignClause();
break;
+ case llvm::omp::OMPC_ompx_dyn_cgroup_mem:
+ C = new (Context) OMPXDynCGroupMemClause();
+ break;
#define OMP_CLAUSE_NO_CLASS(Enum, Str) \
case llvm::omp::Enum: \
break;
@@ -12021,6 +10491,23 @@ void OMPClauseReader::VisitOMPAtomicDefaultMemOrderClause(
C->setAtomicDefaultMemOrderKindKwLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPAtClause(OMPAtClause *C) {
+ C->setAtKind(static_cast<OpenMPAtClauseKind>(Record.readInt()));
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setAtKindKwLoc(Record.readSourceLocation());
+}
+
+void OMPClauseReader::VisitOMPSeverityClause(OMPSeverityClause *C) {
+ C->setSeverityKind(static_cast<OpenMPSeverityClauseKind>(Record.readInt()));
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setSeverityKindKwLoc(Record.readSourceLocation());
+}
+
+void OMPClauseReader::VisitOMPMessageClause(OMPMessageClause *C) {
+ C->setMessageString(Record.readSubExpr());
+ C->setLParenLoc(Record.readSourceLocation());
+}
+
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
C->setLParenLoc(Record.readSourceLocation());
unsigned NumVars = C->varlist_size();
@@ -12347,10 +10834,13 @@ void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) {
void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
C->setLParenLoc(Record.readSourceLocation());
+ bool HasIteratorModifier = false;
for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
C->setMapTypeModifier(
I, static_cast<OpenMPMapModifierKind>(Record.readInt()));
C->setMapTypeModifierLoc(I, Record.readSourceLocation());
+ if (C->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator)
+ HasIteratorModifier = true;
}
C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc());
C->setMapperIdInfo(Record.readDeclarationNameInfo());
@@ -12375,6 +10865,9 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
UDMappers.push_back(Record.readExpr());
C->setUDMapperRefs(UDMappers);
+ if (HasIteratorModifier)
+ C->setIteratorModifier(Record.readExpr());
+
SmallVector<ValueDecl *, 16> Decls;
Decls.reserve(UniqueDecls);
for (unsigned i = 0; i < UniqueDecls; ++i)
@@ -12436,13 +10929,17 @@ void OMPClauseReader::VisitOMPPriorityClause(OMPPriorityClause *C) {
void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
VisitOMPClauseWithPreInit(C);
+ C->setModifier(Record.readEnum<OpenMPGrainsizeClauseModifier>());
C->setGrainsize(Record.readSubExpr());
+ C->setModifierLoc(Record.readSourceLocation());
C->setLParenLoc(Record.readSourceLocation());
}
void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
VisitOMPClauseWithPreInit(C);
+ C->setModifier(Record.readEnum<OpenMPNumTasksClauseModifier>());
C->setNumTasks(Record.readSubExpr());
+ C->setModifierLoc(Record.readSourceLocation());
C->setLParenLoc(Record.readSourceLocation());
}
@@ -12825,8 +11322,10 @@ void OMPClauseReader::VisitOMPAffinityClause(OMPAffinityClause *C) {
void OMPClauseReader::VisitOMPOrderClause(OMPOrderClause *C) {
C->setKind(Record.readEnum<OpenMPOrderClauseKind>());
+ C->setModifier(Record.readEnum<OpenMPOrderClauseModifier>());
C->setLParenLoc(Record.readSourceLocation());
C->setKindKwLoc(Record.readSourceLocation());
+ C->setModifierKwLoc(Record.readSourceLocation());
}
void OMPClauseReader::VisitOMPFilterClause(OMPFilterClause *C) {
@@ -12846,6 +11345,12 @@ void OMPClauseReader::VisitOMPAlignClause(OMPAlignClause *C) {
C->setLParenLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) {
+ VisitOMPClauseWithPreInit(C);
+ C->setSize(Record.readSubExpr());
+ C->setLParenLoc(Record.readSourceLocation());
+}
+
OMPTraitInfo *ASTRecordReader::readOMPTraitInfo() {
OMPTraitInfo &TI = getContext().getNewOMPTraitInfo();
TI.Sets.resize(readUInt32());
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
index 73800191dfc1..8cb513eff13e 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -322,6 +322,7 @@ namespace clang {
void VisitNamedDecl(NamedDecl *ND);
void VisitLabelDecl(LabelDecl *LD);
void VisitNamespaceDecl(NamespaceDecl *D);
+ void VisitHLSLBufferDecl(HLSLBufferDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
void VisitTypeDecl(TypeDecl *TD);
@@ -381,8 +382,10 @@ namespace clang {
void VisitDecompositionDecl(DecompositionDecl *DD);
void VisitBindingDecl(BindingDecl *BD);
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- DeclID VisitTemplateDecl(TemplateDecl *D);
+ void VisitTemplateDecl(TemplateDecl *D);
void VisitConceptDecl(ConceptDecl *D);
+ void VisitImplicitConceptSpecializationDecl(
+ ImplicitConceptSpecializationDecl *D);
void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
@@ -399,6 +402,7 @@ namespace clang {
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
void VisitExportDecl(ExportDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
+ void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
void VisitImportDecl(ImportDecl *D);
void VisitAccessSpecDecl(AccessSpecDecl *D);
void VisitFriendDecl(FriendDecl *D);
@@ -414,14 +418,15 @@ namespace clang {
template<typename T>
RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
- template<typename T>
- void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl,
- DeclID TemplatePatternID = 0);
+ template <typename T>
+ void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl);
- template<typename T>
+ void mergeRedeclarableTemplate(RedeclarableTemplateDecl *D,
+ RedeclarableResult &Redecl);
+
+ template <typename T>
void mergeRedeclarable(Redeclarable<T> *D, T *Existing,
- RedeclarableResult &Redecl,
- DeclID TemplatePatternID = 0);
+ RedeclarableResult &Redecl);
template<typename T>
void mergeMergeable(Mergeable<T> *D);
@@ -430,7 +435,7 @@ namespace clang {
void mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
- DeclID DsID, bool IsKeyDecl);
+ bool IsKeyDecl);
ObjCTypeParamList *ReadObjCTypeParamList();
@@ -563,7 +568,7 @@ void ASTDeclReader::Visit(Decl *D) {
void ASTDeclReader::VisitDecl(Decl *D) {
if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
- isa<ParmVarDecl>(D) || isa<ObjCTypeParamDecl>(D)) {
+ isa<ParmVarDecl, ObjCTypeParamDecl>(D)) {
// We don't want to deserialize the DeclContext of a template
// parameter or of a parameter of a function template immediately. These
// entities might be used in the formulation of its DeclContext (for
@@ -824,6 +829,7 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
VisitRecordDeclImpl(RD);
+ RD->setODRHash(Record.readInt());
// Maintain the invariant of a redeclaration chain containing only
// a single definition.
@@ -844,6 +850,8 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
Reader.MergedDeclContexts.insert(std::make_pair(RD, OldDef));
RD->demoteThisDefinitionToDeclaration();
Reader.mergeDefinitionVisibility(OldDef, RD);
+ if (OldDef->getODRHash() != RD->getODRHash())
+ Reader.PendingRecordOdrMergeFailures[OldDef].push_back(RD);
} else {
OldDef = RD;
}
@@ -886,88 +894,27 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
RedeclarableResult Redecl = VisitRedeclarable(FD);
- VisitDeclaratorDecl(FD);
-
- // Attach a type to this function. Use the real type if possible, but fall
- // back to the type as written if it involves a deduced return type.
- if (FD->getTypeSourceInfo() &&
- FD->getTypeSourceInfo()->getType()->castAs<FunctionType>()
- ->getReturnType()->getContainedAutoType()) {
- // We'll set up the real type in Visit, once we've finished loading the
- // function.
- FD->setType(FD->getTypeSourceInfo()->getType());
- Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID});
- } else {
- FD->setType(Reader.GetType(DeferredTypeID));
- }
- DeferredTypeID = 0;
-
- FD->DNLoc = Record.readDeclarationNameLoc(FD->getDeclName());
- FD->IdentifierNamespace = Record.readInt();
-
- // FunctionDecl's body is handled last at ASTDeclReader::Visit,
- // after everything else is read.
-
- FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
- FD->setInlineSpecified(Record.readInt());
- FD->setImplicitlyInline(Record.readInt());
- FD->setVirtualAsWritten(Record.readInt());
- // We defer calling `FunctionDecl::setPure()` here as for methods of
- // `CXXTemplateSpecializationDecl`s, we may not have connected up the
- // definition (which is required for `setPure`).
- const bool Pure = Record.readInt();
- FD->setHasInheritedPrototype(Record.readInt());
- FD->setHasWrittenPrototype(Record.readInt());
- FD->setDeletedAsWritten(Record.readInt());
- FD->setTrivial(Record.readInt());
- FD->setTrivialForCall(Record.readInt());
- FD->setDefaulted(Record.readInt());
- FD->setExplicitlyDefaulted(Record.readInt());
- FD->setHasImplicitReturnZero(Record.readInt());
- FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt()));
- FD->setUsesSEHTry(Record.readInt());
- FD->setHasSkippedBody(Record.readInt());
- FD->setIsMultiVersion(Record.readInt());
- FD->setLateTemplateParsed(Record.readInt());
-
- FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
- FD->EndRangeLoc = readSourceLocation();
- FD->ODRHash = Record.readInt();
- FD->setHasODRHash(true);
-
- if (FD->isDefaulted()) {
- if (unsigned NumLookups = Record.readInt()) {
- SmallVector<DeclAccessPair, 8> Lookups;
- for (unsigned I = 0; I != NumLookups; ++I) {
- NamedDecl *ND = Record.readDeclAs<NamedDecl>();
- AccessSpecifier AS = (AccessSpecifier)Record.readInt();
- Lookups.push_back(DeclAccessPair::make(ND, AS));
- }
- FD->setDefaultedFunctionInfo(FunctionDecl::DefaultedFunctionInfo::Create(
- Reader.getContext(), Lookups));
- }
- }
+ FunctionDecl *Existing = nullptr;
switch ((FunctionDecl::TemplatedKind)Record.readInt()) {
case FunctionDecl::TK_NonTemplate:
- mergeRedeclarable(FD, Redecl);
break;
case FunctionDecl::TK_DependentNonTemplate:
- mergeRedeclarable(FD, Redecl);
FD->setInstantiatedFromDecl(readDeclAs<FunctionDecl>());
break;
- case FunctionDecl::TK_FunctionTemplate:
- // Merged when we merge the template.
- FD->setDescribedFunctionTemplate(readDeclAs<FunctionTemplateDecl>());
+ case FunctionDecl::TK_FunctionTemplate: {
+ auto *Template = readDeclAs<FunctionTemplateDecl>();
+ Template->init(FD);
+ FD->setDescribedFunctionTemplate(Template);
break;
+ }
case FunctionDecl::TK_MemberSpecialization: {
auto *InstFD = readDeclAs<FunctionDecl>();
auto TSK = (TemplateSpecializationKind)Record.readInt();
SourceLocation POI = readSourceLocation();
FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
- mergeRedeclarable(FD, Redecl);
break;
}
case FunctionDecl::TK_FunctionTemplateSpecialization: {
@@ -1038,7 +985,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
else {
assert(Reader.getContext().getLangOpts().Modules &&
"already deserialized this template specialization");
- mergeRedeclarable(FD, ExistingInfo->getFunction(), Redecl);
+ Existing = ExistingInfo->getFunction();
}
}
break;
@@ -1066,6 +1013,97 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
}
}
+ VisitDeclaratorDecl(FD);
+
+ // Attach a type to this function. Use the real type if possible, but fall
+ // back to the type as written if it involves a deduced return type.
+ if (FD->getTypeSourceInfo() && FD->getTypeSourceInfo()
+ ->getType()
+ ->castAs<FunctionType>()
+ ->getReturnType()
+ ->getContainedAutoType()) {
+ // We'll set up the real type in Visit, once we've finished loading the
+ // function.
+ FD->setType(FD->getTypeSourceInfo()->getType());
+ Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID});
+ } else {
+ FD->setType(Reader.GetType(DeferredTypeID));
+ }
+ DeferredTypeID = 0;
+
+ FD->DNLoc = Record.readDeclarationNameLoc(FD->getDeclName());
+ FD->IdentifierNamespace = Record.readInt();
+
+ // FunctionDecl's body is handled last at ASTDeclReader::Visit,
+ // after everything else is read.
+
+ FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
+ FD->setInlineSpecified(Record.readInt());
+ FD->setImplicitlyInline(Record.readInt());
+ FD->setVirtualAsWritten(Record.readInt());
+ // We defer calling `FunctionDecl::setPure()` here as for methods of
+ // `CXXTemplateSpecializationDecl`s, we may not have connected up the
+ // definition (which is required for `setPure`).
+ const bool Pure = Record.readInt();
+ FD->setHasInheritedPrototype(Record.readInt());
+ FD->setHasWrittenPrototype(Record.readInt());
+ FD->setDeletedAsWritten(Record.readInt());
+ FD->setTrivial(Record.readInt());
+ FD->setTrivialForCall(Record.readInt());
+ FD->setDefaulted(Record.readInt());
+ FD->setExplicitlyDefaulted(Record.readInt());
+ FD->setIneligibleOrNotSelected(Record.readInt());
+ FD->setHasImplicitReturnZero(Record.readInt());
+ FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt()));
+ FD->setUsesSEHTry(Record.readInt());
+ FD->setHasSkippedBody(Record.readInt());
+ FD->setIsMultiVersion(Record.readInt());
+ FD->setLateTemplateParsed(Record.readInt());
+ FD->setFriendConstraintRefersToEnclosingTemplate(Record.readInt());
+
+ FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
+ FD->EndRangeLoc = readSourceLocation();
+ FD->setDefaultLoc(readSourceLocation());
+
+ FD->ODRHash = Record.readInt();
+ FD->setHasODRHash(true);
+
+ if (FD->isDefaulted()) {
+ if (unsigned NumLookups = Record.readInt()) {
+ SmallVector<DeclAccessPair, 8> Lookups;
+ for (unsigned I = 0; I != NumLookups; ++I) {
+ NamedDecl *ND = Record.readDeclAs<NamedDecl>();
+ AccessSpecifier AS = (AccessSpecifier)Record.readInt();
+ Lookups.push_back(DeclAccessPair::make(ND, AS));
+ }
+ FD->setDefaultedFunctionInfo(FunctionDecl::DefaultedFunctionInfo::Create(
+ Reader.getContext(), Lookups));
+ }
+ }
+
+ if (Existing)
+ mergeRedeclarable(FD, Existing, Redecl);
+ else if (auto Kind = FD->getTemplatedKind();
+ Kind == FunctionDecl::TK_FunctionTemplate ||
+ Kind == FunctionDecl::TK_FunctionTemplateSpecialization) {
+ // Function Templates have their FunctionTemplateDecls merged instead of
+ // their FunctionDecls.
+ auto merge = [this, &Redecl, FD](auto &&F) {
+ auto *Existing = cast_or_null<FunctionDecl>(Redecl.getKnownMergeTarget());
+ RedeclarableResult NewRedecl(Existing ? F(Existing) : nullptr,
+ Redecl.getFirstID(), Redecl.isKeyDecl());
+ mergeRedeclarableTemplate(F(FD), NewRedecl);
+ };
+ if (Kind == FunctionDecl::TK_FunctionTemplate)
+ merge(
+ [](FunctionDecl *FD) { return FD->getDescribedFunctionTemplate(); });
+ else
+ merge([](FunctionDecl *FD) {
+ return FD->getTemplateSpecializationInfo()->getTemplate();
+ });
+ } else
+ mergeRedeclarable(FD, Redecl);
+
// Defer calling `setPure` until merging above has guaranteed we've set
// `DefinitionData` (as this will need to access it).
FD->setPure(Pure);
@@ -1169,6 +1207,8 @@ void ASTDeclReader::ReadObjCDefinitionData(
Data.EndLoc = readSourceLocation();
Data.HasDesignatedInitializers = Record.readInt();
+ Data.ODRHash = Record.readInt();
+ Data.HasODRHash = true;
// Read the directly referenced protocols and their SourceLocations.
unsigned NumProtocols = Record.readInt();
@@ -1196,13 +1236,16 @@ void ASTDeclReader::ReadObjCDefinitionData(
void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D,
struct ObjCInterfaceDecl::DefinitionData &&NewDD) {
struct ObjCInterfaceDecl::DefinitionData &DD = D->data();
- if (DD.Definition != NewDD.Definition) {
- Reader.MergedDeclContexts.insert(
- std::make_pair(NewDD.Definition, DD.Definition));
- Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition);
- }
+ if (DD.Definition == NewDD.Definition)
+ return;
+
+ Reader.MergedDeclContexts.insert(
+ std::make_pair(NewDD.Definition, DD.Definition));
+ Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition);
- // FIXME: odr checking?
+ if (D->getODRHash() != NewDD.ODRHash)
+ Reader.PendingObjCInterfaceOdrMergeFailures[DD.Definition].push_back(
+ {NewDD.Definition, &NewDD});
}
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
@@ -1297,18 +1340,23 @@ void ASTDeclReader::ReadObjCDefinitionData(
ProtoLocs.push_back(readSourceLocation());
Data.ReferencedProtocols.set(ProtoRefs.data(), NumProtoRefs,
ProtoLocs.data(), Reader.getContext());
+ Data.ODRHash = Record.readInt();
+ Data.HasODRHash = true;
}
-void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D,
- struct ObjCProtocolDecl::DefinitionData &&NewDD) {
+void ASTDeclReader::MergeDefinitionData(
+ ObjCProtocolDecl *D, struct ObjCProtocolDecl::DefinitionData &&NewDD) {
struct ObjCProtocolDecl::DefinitionData &DD = D->data();
- if (DD.Definition != NewDD.Definition) {
- Reader.MergedDeclContexts.insert(
- std::make_pair(NewDD.Definition, DD.Definition));
- Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition);
- }
+ if (DD.Definition == NewDD.Definition)
+ return;
+
+ Reader.MergedDeclContexts.insert(
+ std::make_pair(NewDD.Definition, DD.Definition));
+ Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition);
- // FIXME: odr checking?
+ if (D->getODRHash() != NewDD.ODRHash)
+ Reader.PendingObjCProtocolOdrMergeFailures[DD.Definition].push_back(
+ {NewDD.Definition, &NewDD});
}
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
@@ -1640,6 +1688,11 @@ void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
AD->setRParenLoc(readSourceLocation());
}
+void ASTDeclReader::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
+ VisitDecl(D);
+ D->Statement = Record.readStmt();
+}
+
void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
VisitDecl(BD);
BD->setBody(cast_or_null<CompoundStmt>(Record.readStmt()));
@@ -1707,6 +1760,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
RedeclarableResult Redecl = VisitRedeclarable(D);
VisitNamedDecl(D);
D->setInline(Record.readInt());
+ D->setNested(Record.readInt());
D->LocStart = readSourceLocation();
D->RBraceLoc = readSourceLocation();
@@ -1720,7 +1774,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
} else {
// Link this namespace back to the first declaration, which has already
// been deserialized.
- D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl());
+ D->AnonOrFirstNamespaceAndFlags.setPointer(D->getFirstDecl());
}
mergeRedeclarable(D, Redecl);
@@ -1735,6 +1789,15 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
}
}
+void ASTDeclReader::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
+ VisitNamedDecl(D);
+ VisitDeclContext(D);
+ D->IsCBuffer = Record.readBool();
+ D->KwLoc = readSourceLocation();
+ D->LBraceLoc = readSourceLocation();
+ D->RBraceLoc = readSourceLocation();
+}
+
void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
RedeclarableResult Redecl = VisitRedeclarable(D);
VisitNamedDecl(D);
@@ -1761,7 +1824,7 @@ void ASTDeclReader::VisitUsingEnumDecl(UsingEnumDecl *D) {
VisitNamedDecl(D);
D->setUsingLoc(readSourceLocation());
D->setEnumLoc(readSourceLocation());
- D->Enum = readDeclAs<EnumDecl>();
+ D->setEnumType(Record.readTypeSourceInfo());
D->FirstUsingShadow.setPointer(readDeclAs<UsingShadowDecl>());
if (auto *Pattern = readDeclAs<UsingEnumDecl>())
Reader.getContext().setInstantiatedFromUsingEnumDecl(D, Pattern);
@@ -1872,9 +1935,12 @@ void ASTDeclReader::ReadCXXDefinitionData(
Lambda.ManglingNumber = Record.readInt();
D->setDeviceLambdaManglingNumber(Record.readInt());
Lambda.ContextDecl = readDeclID();
- Lambda.Captures = (Capture *)Reader.getContext().Allocate(
- sizeof(Capture) * Lambda.NumCaptures);
- Capture *ToCapture = Lambda.Captures;
+ Capture *ToCapture = nullptr;
+ if (Lambda.NumCaptures) {
+ ToCapture = (Capture *)Reader.getContext().Allocate(sizeof(Capture) *
+ Lambda.NumCaptures);
+ Lambda.AddCaptureList(Reader.getContext(), ToCapture);
+ }
Lambda.MethodTyInfo = readTypeSourceInfo();
for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
SourceLocation Loc = readSourceLocation();
@@ -1958,8 +2024,26 @@ void ASTDeclReader::MergeDefinitionData(
// lazily load it.
if (DD.IsLambda) {
- // FIXME: ODR-checking for merging lambdas (this happens, for instance,
- // when they occur within the body of a function template specialization).
+ auto &Lambda1 = static_cast<CXXRecordDecl::LambdaDefinitionData &>(DD);
+ auto &Lambda2 = static_cast<CXXRecordDecl::LambdaDefinitionData &>(MergeDD);
+ DetectedOdrViolation |= Lambda1.DependencyKind != Lambda2.DependencyKind;
+ DetectedOdrViolation |= Lambda1.IsGenericLambda != Lambda2.IsGenericLambda;
+ DetectedOdrViolation |= Lambda1.CaptureDefault != Lambda2.CaptureDefault;
+ DetectedOdrViolation |= Lambda1.NumCaptures != Lambda2.NumCaptures;
+ DetectedOdrViolation |=
+ Lambda1.NumExplicitCaptures != Lambda2.NumExplicitCaptures;
+ DetectedOdrViolation |=
+ Lambda1.HasKnownInternalLinkage != Lambda2.HasKnownInternalLinkage;
+ DetectedOdrViolation |= Lambda1.ManglingNumber != Lambda2.ManglingNumber;
+
+ if (Lambda1.NumCaptures && Lambda1.NumCaptures == Lambda2.NumCaptures) {
+ for (unsigned I = 0, N = Lambda1.NumCaptures; I != N; ++I) {
+ LambdaCapture &Cap1 = Lambda1.Captures.front()[I];
+ LambdaCapture &Cap2 = Lambda2.Captures.front()[I];
+ DetectedOdrViolation |= Cap1.getCaptureKind() != Cap2.getCaptureKind();
+ }
+ Lambda1.AddCaptureList(Reader.getContext(), Lambda2.Captures.front());
+ }
}
if (D->getODRHash() != MergeDD.ODRHash) {
@@ -2175,15 +2259,12 @@ void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
D->FriendLoc = readSourceLocation();
}
-DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
+void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
VisitNamedDecl(D);
- DeclID PatternID = readDeclID();
- auto *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
- TemplateParameterList *TemplateParams = Record.readTemplateParameterList();
- D->init(TemplatedDecl, TemplateParams);
-
- return PatternID;
+ assert(!D->TemplateParams && "TemplateParams already set!");
+ D->TemplateParams = Record.readTemplateParameterList();
+ D->init(readDeclAs<NamedDecl>());
}
void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) {
@@ -2192,6 +2273,17 @@ void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) {
mergeMergeable(D);
}
+void ASTDeclReader::VisitImplicitConceptSpecializationDecl(
+ ImplicitConceptSpecializationDecl *D) {
+ // The size of the template list was read during creation of the Decl, so we
+ // don't have to re-read it here.
+ VisitDecl(D);
+ llvm::SmallVector<TemplateArgument, 4> Args;
+ for (unsigned I = 0; I < D->NumTemplateArgs; ++I)
+ Args.push_back(Record.readTemplateArgument(/*Canonicalize=*/true));
+ D->setTemplateArguments(Args);
+}
+
void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
}
@@ -2220,21 +2312,15 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
}
}
- DeclID PatternID = VisitTemplateDecl(D);
+ VisitTemplateDecl(D);
D->IdentifierNamespace = Record.readInt();
- mergeRedeclarable(D, Redecl, PatternID);
-
- // If we merged the template with a prior declaration chain, merge the common
- // pointer.
- // FIXME: Actually merge here, don't just overwrite.
- D->Common = D->getCanonicalDecl()->Common;
-
return Redecl;
}
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
+ mergeRedeclarableTemplate(D, Redecl);
if (ThisDeclID == Redecl.getFirstID()) {
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
@@ -2262,6 +2348,7 @@ void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
/// VarTemplateDecl beyond TemplateDecl...
void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
+ mergeRedeclarableTemplate(D, Redecl);
if (ThisDeclID == Redecl.getFirstID()) {
// This VarTemplateDecl owns a CommonPtr; read it to keep track of all of
@@ -2390,8 +2477,6 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
VarTemplateSpecializationDecl *D) {
- RedeclarableResult Redecl = VisitVarDeclImpl(D);
-
ASTContext &C = Reader.getContext();
if (Decl *InstD = readDecl()) {
if (auto *VTD = dyn_cast<VarTemplateDecl>(InstD)) {
@@ -2428,6 +2513,8 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
D->IsCompleteDefinition = Record.readInt();
+ RedeclarableResult Redecl = VisitVarDeclImpl(D);
+
bool writtenAsCanonicalDecl = Record.readInt();
if (writtenAsCanonicalDecl) {
auto *CanonPattern = readDeclAs<VarTemplateDecl>();
@@ -2535,7 +2622,8 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
}
void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
+ RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
+ mergeRedeclarableTemplate(D, Redecl);
}
void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
@@ -2632,10 +2720,9 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
/// Attempts to merge the given declaration (D) with another declaration
/// of the same entity.
-template<typename T>
+template <typename T>
void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
- RedeclarableResult &Redecl,
- DeclID TemplatePatternID) {
+ RedeclarableResult &Redecl) {
// If modules are not available, there is no reason to perform this merge.
if (!Reader.getContext().getLangOpts().Modules)
return;
@@ -2648,10 +2735,19 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
if (auto *Existing = Redecl.getKnownMergeTarget())
// We already know of an existing declaration we should merge with.
- mergeRedeclarable(D, cast<T>(Existing), Redecl, TemplatePatternID);
+ mergeRedeclarable(D, cast<T>(Existing), Redecl);
else if (FindExistingResult ExistingRes = findExisting(D))
if (T *Existing = ExistingRes)
- mergeRedeclarable(D, Existing, Redecl, TemplatePatternID);
+ mergeRedeclarable(D, Existing, Redecl);
+}
+
+void ASTDeclReader::mergeRedeclarableTemplate(RedeclarableTemplateDecl *D,
+ RedeclarableResult &Redecl) {
+ mergeRedeclarable(D, Redecl);
+ // If we merged the template with a prior declaration chain, merge the
+ // common pointer.
+ // FIXME: Actually merge here, don't just overwrite.
+ D->Common = D->getCanonicalDecl()->Common;
}
/// "Cast" to type T, asserting if we don't have an implicit conversion.
@@ -2666,7 +2762,7 @@ template<typename T> static T assert_cast(...) {
/// declarations.
void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
RedeclarableTemplateDecl *Existing,
- DeclID DsID, bool IsKeyDecl) {
+ bool IsKeyDecl) {
auto *DPattern = D->getTemplatedDecl();
auto *ExistingPattern = Existing->getTemplatedDecl();
RedeclarableResult Result(/*MergeWith*/ ExistingPattern,
@@ -2706,17 +2802,13 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
/// Attempts to merge the given declaration (D) with another declaration
/// of the same entity.
-template<typename T>
+template <typename T>
void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
- RedeclarableResult &Redecl,
- DeclID TemplatePatternID) {
+ RedeclarableResult &Redecl) {
auto *D = static_cast<T *>(DBase);
T *ExistingCanon = Existing->getCanonicalDecl();
T *DCanon = D->getCanonicalDecl();
if (ExistingCanon != DCanon) {
- assert(DCanon->getGlobalID() == Redecl.getFirstID() &&
- "already merged this declaration");
-
// Have our redeclaration link point back at the canonical declaration
// of the existing declaration, so that this declaration has the
// appropriate canonical declaration.
@@ -2729,14 +2821,14 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
// We cannot have loaded any redeclarations of this declaration yet, so
// there's nothing else that needs to be updated.
if (auto *Namespace = dyn_cast<NamespaceDecl>(D))
- Namespace->AnonOrFirstNamespaceAndInline.setPointer(
- assert_cast<NamespaceDecl*>(ExistingCanon));
+ Namespace->AnonOrFirstNamespaceAndFlags.setPointer(
+ assert_cast<NamespaceDecl *>(ExistingCanon));
// When we merge a template, merge its pattern.
if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
mergeTemplatePattern(
- DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
- TemplatePatternID, Redecl.isKeyDecl());
+ DTemplate, assert_cast<RedeclarableTemplateDecl *>(ExistingCanon),
+ Redecl.isKeyDecl());
// If this declaration is a key declaration, make a note of that.
if (Redecl.isKeyDecl())
@@ -2859,6 +2951,8 @@ public:
return Reader.readInt();
}
+ bool readBool() { return Reader.readBool(); }
+
SourceRange readSourceRange() {
return Reader.readSourceRange();
}
@@ -2964,16 +3058,11 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
return false;
}
- if (isa<FileScopeAsmDecl>(D) ||
- isa<ObjCProtocolDecl>(D) ||
- isa<ObjCImplDecl>(D) ||
- isa<ImportDecl>(D) ||
- isa<PragmaCommentDecl>(D) ||
- isa<PragmaDetectMismatchDecl>(D))
+ if (isa<FileScopeAsmDecl, TopLevelStmtDecl, ObjCProtocolDecl, ObjCImplDecl,
+ ImportDecl, PragmaCommentDecl, PragmaDetectMismatchDecl>(D))
return true;
- if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) ||
- isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D) ||
- isa<OMPRequiresDecl>(D))
+ if (isa<OMPThreadPrivateDecl, OMPDeclareReductionDecl, OMPDeclareMapperDecl,
+ OMPAllocateDecl, OMPRequiresDecl>(D))
return !D->getDeclContext()->isFunctionOrMethod();
if (const auto *Var = dyn_cast<VarDecl>(D))
return Var->isFileVarDecl() &&
@@ -3776,6 +3865,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
case DECL_FILE_SCOPE_ASM:
D = FileScopeAsmDecl::CreateDeserialized(Context, ID);
break;
+ case DECL_TOP_LEVEL_STMT_DECL:
+ D = TopLevelStmtDecl::CreateDeserialized(Context, ID);
+ break;
case DECL_BLOCK:
D = BlockDecl::CreateDeserialized(Context, ID);
break;
@@ -3853,6 +3945,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
case DECL_OBJC_TYPE_PARAM:
D = ObjCTypeParamDecl::CreateDeserialized(Context, ID);
break;
+ case DECL_HLSL_BUFFER:
+ D = HLSLBufferDecl::CreateDeserialized(Context, ID);
+ break;
+ case DECL_IMPLICIT_CONCEPT_SPECIALIZATION:
+ D = ImplicitConceptSpecializationDecl::CreateDeserialized(Context, ID,
+ Record.readInt());
+ break;
}
assert(D && "Unknown declaration reading AST file");
@@ -3906,8 +4005,7 @@ void ASTReader::PassInterestingDeclsToConsumer() {
// Guard variable to avoid recursively redoing the process of passing
// decls to consumer.
- SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
- true);
+ SaveAndRestore GuardPassingDeclsToConsumer(PassingDeclsToConsumer, true);
// Ensure that we've loaded all potentially-interesting declarations
// that need to be eagerly loaded.
@@ -3985,7 +4083,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
}
// Add the lazy specializations to the template.
assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) ||
- isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) &&
+ isa<FunctionTemplateDecl, VarTemplateDecl>(D)) &&
"Must not have pending specializations");
if (auto *CTD = dyn_cast<ClassTemplateDecl>(D))
ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs);
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
index e0ae019bf803..46d653c7f940 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -61,6 +61,7 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
+#include <optional>
#include <string>
using namespace clang;
@@ -772,6 +773,7 @@ static ConstraintSatisfaction
readConstraintSatisfaction(ASTRecordReader &Record) {
ConstraintSatisfaction Satisfaction;
Satisfaction.IsSatisfied = Record.readInt();
+ Satisfaction.ContainsErrors = Record.readInt();
if (!Satisfaction.IsSatisfied) {
unsigned NumDetailRecords = Record.readInt();
for (unsigned i = 0; i != NumDetailRecords; ++i) {
@@ -793,17 +795,13 @@ readConstraintSatisfaction(ASTRecordReader &Record) {
void ASTStmtReader::VisitConceptSpecializationExpr(
ConceptSpecializationExpr *E) {
VisitExpr(E);
- unsigned NumTemplateArgs = Record.readInt();
E->NestedNameSpec = Record.readNestedNameSpecifierLoc();
E->TemplateKWLoc = Record.readSourceLocation();
E->ConceptName = Record.readDeclarationNameInfo();
E->NamedConcept = readDeclAs<ConceptDecl>();
E->FoundDecl = Record.readDeclAs<NamedDecl>();
+ E->SpecDecl = Record.readDeclAs<ImplicitConceptSpecializationDecl>();
E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
- llvm::SmallVector<TemplateArgument, 4> Args;
- for (unsigned I = 0; I < NumTemplateArgs; ++I)
- Args.push_back(Record.readTemplateArgument());
- E->setTemplateArguments(Args);
E->Satisfaction = E->isValueDependent() ? nullptr :
ASTConstraintSatisfaction::Create(Record.getContext(),
readConstraintSatisfaction(Record));
@@ -860,7 +858,7 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
} else
E = Record.readExpr();
- llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> Req;
+ std::optional<concepts::ExprRequirement::ReturnTypeRequirement> Req;
ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
SourceLocation NoexceptLoc;
if (RK == concepts::Requirement::RK_Simple) {
@@ -898,9 +896,17 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
std::move(*Req));
} break;
case concepts::Requirement::RK_Nested: {
- if (/* IsSubstitutionDiagnostic */Record.readInt()) {
+ bool HasInvalidConstraint = Record.readInt();
+ if (HasInvalidConstraint) {
+ std::string InvalidConstraint = Record.readString();
+ char *InvalidConstraintBuf =
+ new (Record.getContext()) char[InvalidConstraint.size()];
+ std::copy(InvalidConstraint.begin(), InvalidConstraint.end(),
+ InvalidConstraintBuf);
R = new (Record.getContext()) concepts::NestedRequirement(
- readSubstitutionDiagnostic(Record));
+ Record.getContext(),
+ StringRef(InvalidConstraintBuf, InvalidConstraint.size()),
+ readConstraintSatisfaction(Record));
break;
}
Expr *E = Record.readExpr();
@@ -1827,13 +1833,19 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
E->Param = readDeclAs<ParmVarDecl>();
E->UsedContext = readDeclAs<DeclContext>();
E->CXXDefaultArgExprBits.Loc = readSourceLocation();
+ E->CXXDefaultArgExprBits.HasRewrittenInit = Record.readInt();
+ if (E->CXXDefaultArgExprBits.HasRewrittenInit)
+ *E->getTrailingObjects<Expr *>() = Record.readSubExpr();
}
void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
VisitExpr(E);
+ E->CXXDefaultInitExprBits.HasRewrittenInit = Record.readInt();
E->Field = readDeclAs<FieldDecl>();
E->UsedContext = readDeclAs<DeclContext>();
E->CXXDefaultInitExprBits.Loc = readSourceLocation();
+ if (E->CXXDefaultInitExprBits.HasRewrittenInit)
+ *E->getTrailingObjects<Expr *>() = Record.readSubExpr();
}
void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
@@ -2117,8 +2129,10 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
- E->ParamAndRef.setPointer(readDeclAs<NonTypeTemplateParmDecl>());
- E->ParamAndRef.setInt(Record.readInt());
+ E->AssociatedDeclAndRef.setPointer(readDeclAs<Decl>());
+ E->AssociatedDeclAndRef.setInt(Record.readInt());
+ E->Index = Record.readInt();
+ E->PackIndex = Record.readInt();
E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation();
E->Replacement = Record.readSubExpr();
}
@@ -2126,7 +2140,8 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
SubstNonTypeTemplateParmPackExpr *E) {
VisitExpr(E);
- E->Param = readDeclAs<NonTypeTemplateParmDecl>();
+ E->AssociatedDecl = readDeclAs<Decl>();
+ E->Index = Record.readInt();
TemplateArgument ArgPack = Record.readTemplateArgument();
if (ArgPack.getKind() != TemplateArgument::Pack)
return;
@@ -2167,6 +2182,31 @@ void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
E->Opcode = (BinaryOperatorKind)Record.readInt();
}
+void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
+ VisitExpr(E);
+ unsigned ExpectedNumExprs = Record.readInt();
+ assert(E->NumExprs == ExpectedNumExprs &&
+ "expected number of expressions does not equal the actual number of "
+ "serialized expressions.");
+ E->NumUserSpecifiedExprs = Record.readInt();
+ E->InitLoc = readSourceLocation();
+ E->LParenLoc = readSourceLocation();
+ E->RParenLoc = readSourceLocation();
+ for (unsigned I = 0; I < ExpectedNumExprs; I++)
+ E->getTrailingObjects<Expr *>()[I] = Record.readSubExpr();
+
+ bool HasArrayFillerOrUnionDecl = Record.readBool();
+ if (HasArrayFillerOrUnionDecl) {
+ bool HasArrayFiller = Record.readBool();
+ if (HasArrayFiller) {
+ E->setArrayFiller(Record.readSubExpr());
+ } else {
+ E->setInitializedFieldInUnion(readDeclAs<FieldDecl>());
+ }
+ }
+ E->updateDependence();
+}
+
void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
VisitExpr(E);
E->SourceExpr = Record.readSubExpr();
@@ -2412,6 +2452,13 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
VisitOMPExecutableDirective(D);
}
+void ASTStmtReader::VisitOMPErrorDirective(OMPErrorDirective *D) {
+ VisitStmt(D);
+ // The NumClauses field was read in ReadStmtFromStream.
+ Record.skipInts(1);
+ VisitOMPExecutableDirective(D);
+}
+
void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
@@ -3359,6 +3406,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
+ case STMT_OMP_ERROR_DIRECTIVE:
+ S = OMPErrorDirective::CreateEmpty(
+ Context, Record[ASTStmtReader::NumStmtFields], Empty);
+ break;
+
case STMT_OMP_TASKGROUP_DIRECTIVE:
S = OMPTaskgroupDirective::CreateEmpty(
Context, Record[ASTStmtReader::NumStmtFields], Empty);
@@ -3817,11 +3869,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case EXPR_CXX_DEFAULT_ARG:
- S = new (Context) CXXDefaultArgExpr(Empty);
+ S = CXXDefaultArgExpr::CreateEmpty(
+ Context, /*HasRewrittenInit=*/Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CXX_DEFAULT_INIT:
- S = new (Context) CXXDefaultInitExpr(Empty);
+ S = CXXDefaultInitExpr::CreateEmpty(
+ Context, /*HasRewrittenInit=*/Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_CXX_BIND_TEMPORARY:
@@ -3946,6 +4000,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) CXXFoldExpr(Empty);
break;
+ case EXPR_CXX_PAREN_LIST_INIT:
+ S = CXXParenListInitExpr::CreateEmpty(
+ Context, /*numExprs=*/Record[ASTStmtReader::NumExprFields], Empty);
+ break;
+
case EXPR_OPAQUE_VALUE:
S = new (Context) OpaqueValueExpr(Empty);
break;
@@ -3999,8 +4058,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case EXPR_CONCEPT_SPECIALIZATION: {
- unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields];
- S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs);
+ S = new (Context) ConceptSpecializationExpr(Empty);
break;
}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
index 0739dcc1ce60..bdf11001473e 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
@@ -77,7 +77,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
@@ -100,6 +99,7 @@
#include "llvm/Support/OnDiskHashTable.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SHA1.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -108,9 +108,9 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
-#include <deque>
#include <limits>
#include <memory>
+#include <optional>
#include <queue>
#include <tuple>
#include <utility>
@@ -161,12 +161,14 @@ static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) {
namespace {
-std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS,
- Module *RootModule) {
+std::set<const FileEntry *> GetAffectingModuleMaps(const Preprocessor &PP,
+ Module *RootModule) {
std::set<const FileEntry *> ModuleMaps{};
std::set<const Module *> ProcessedModules;
SmallVector<const Module *> ModulesToProcess{RootModule};
+ const HeaderSearch &HS = PP.getHeaderSearchInfo();
+
SmallVector<const FileEntry *, 16> FilesByUID;
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
@@ -190,30 +192,36 @@ std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS,
}
}
- while (!ModulesToProcess.empty()) {
- auto *CurrentModule = ModulesToProcess.pop_back_val();
- ProcessedModules.insert(CurrentModule);
+ const ModuleMap &MM = HS.getModuleMap();
+ SourceManager &SourceMgr = PP.getSourceManager();
- auto *ModuleMapFile =
- HS.getModuleMap().getModuleMapFileForUniquing(CurrentModule);
- if (!ModuleMapFile) {
- continue;
+ auto ForIncludeChain = [&](FileEntryRef F,
+ llvm::function_ref<void(FileEntryRef)> CB) {
+ CB(F);
+ FileID FID = SourceMgr.translateFile(F);
+ SourceLocation Loc = SourceMgr.getIncludeLoc(FID);
+ while (Loc.isValid()) {
+ FID = SourceMgr.getFileID(Loc);
+ CB(*SourceMgr.getFileEntryRefForID(FID));
+ Loc = SourceMgr.getIncludeLoc(FID);
}
+ };
- ModuleMaps.insert(ModuleMapFile);
-
- for (auto *ImportedModule : (CurrentModule)->Imports) {
- if (!ImportedModule ||
- ProcessedModules.find(ImportedModule) != ProcessedModules.end()) {
- continue;
- }
- ModulesToProcess.push_back(ImportedModule);
- }
+ auto ProcessModuleOnce = [&](const Module *M) {
+ for (const Module *Mod = M; Mod; Mod = Mod->Parent)
+ if (ProcessedModules.insert(Mod).second)
+ if (auto ModuleMapFile = MM.getModuleMapFileForUniquing(Mod))
+ ForIncludeChain(*ModuleMapFile, [&](FileEntryRef F) {
+ ModuleMaps.insert(F);
+ });
+ };
+ for (const Module *CurrentModule : ModulesToProcess) {
+ ProcessModuleOnce(CurrentModule);
+ for (const Module *ImportedModule : CurrentModule->Imports)
+ ProcessModuleOnce(ImportedModule);
for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses)
- if (UndeclaredModule &&
- ProcessedModules.find(UndeclaredModule) == ProcessedModules.end())
- ModulesToProcess.push_back(UndeclaredModule);
+ ProcessModuleOnce(UndeclaredModule);
}
return ModuleMaps;
@@ -437,7 +445,7 @@ void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
addSourceLocation(TL.getTypeofLoc());
addSourceLocation(TL.getLParenLoc());
addSourceLocation(TL.getRParenLoc());
- Record.AddTypeSourceInfo(TL.getUnderlyingTInfo());
+ Record.AddTypeSourceInfo(TL.getUnmodifiedTInfo());
}
void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
@@ -463,8 +471,9 @@ void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
addSourceLocation(TL.getLAngleLoc());
addSourceLocation(TL.getRAngleLoc());
for (unsigned I = 0; I < TL.getNumArgs(); ++I)
- Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
- TL.getArgLocInfo(I));
+ Record.AddTemplateArgumentLocInfo(
+ TL.getTypePtr()->getTypeConstraintArguments()[I].getKind(),
+ TL.getArgLocInfo(I));
}
Record.push_back(TL.isDecltypeAuto());
if (TL.isDecltypeAuto())
@@ -560,6 +569,7 @@ void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
addSourceLocation(TL.getNameLoc());
+ addSourceLocation(TL.getNameEndLoc());
}
void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
@@ -734,6 +744,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
RECORD(EXPR_USER_DEFINED_LITERAL);
RECORD(EXPR_CXX_STD_INITIALIZER_LIST);
RECORD(EXPR_CXX_BOOL_LITERAL);
+ RECORD(EXPR_CXX_PAREN_LIST_INIT);
RECORD(EXPR_CXX_NULL_PTR_LITERAL);
RECORD(EXPR_CXX_TYPEID_EXPR);
RECORD(EXPR_CXX_TYPEID_TYPE);
@@ -786,7 +797,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(MODULE_MAP_FILE);
RECORD(IMPORTS);
RECORD(ORIGINAL_FILE);
- RECORD(ORIGINAL_PCH_DIR);
RECORD(ORIGINAL_FILE_ID);
RECORD(INPUT_FILE_OFFSETS);
@@ -884,6 +894,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(SUBMODULE_TOPHEADER);
RECORD(SUBMODULE_UMBRELLA_DIR);
RECORD(SUBMODULE_IMPORTS);
+ RECORD(SUBMODULE_AFFECTING_MODULES);
RECORD(SUBMODULE_EXPORTS);
RECORD(SUBMODULE_REQUIRES);
RECORD(SUBMODULE_EXCLUDED_HEADER);
@@ -1017,6 +1028,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DECL_PRAGMA_DETECT_MISMATCH);
RECORD(DECL_OMP_DECLARE_REDUCTION);
RECORD(DECL_OMP_ALLOCATE);
+ RECORD(DECL_HLSL_BUFFER);
// Statements and Exprs can occur in the Decls and Types block.
AddStmtsExprs(Stream, Record);
@@ -1034,6 +1046,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(SIGNATURE);
RECORD(AST_BLOCK_HASH);
RECORD(DIAGNOSTIC_OPTIONS);
+ RECORD(HEADER_SEARCH_PATHS);
RECORD(DIAG_PRAGMA_MAPPINGS);
#undef RECORD
@@ -1164,6 +1177,35 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
Record.clear();
+ // Header search paths.
+ Record.clear();
+ const HeaderSearchOptions &HSOpts =
+ PP.getHeaderSearchInfo().getHeaderSearchOpts();
+
+ // Include entries.
+ Record.push_back(HSOpts.UserEntries.size());
+ for (unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) {
+ const HeaderSearchOptions::Entry &Entry = HSOpts.UserEntries[I];
+ AddString(Entry.Path, Record);
+ Record.push_back(static_cast<unsigned>(Entry.Group));
+ Record.push_back(Entry.IsFramework);
+ Record.push_back(Entry.IgnoreSysRoot);
+ }
+
+ // System header prefixes.
+ Record.push_back(HSOpts.SystemHeaderPrefixes.size());
+ for (unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) {
+ AddString(HSOpts.SystemHeaderPrefixes[I].Prefix, Record);
+ Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
+ }
+
+ // VFS overlay files.
+ Record.push_back(HSOpts.VFSOverlayFiles.size());
+ for (StringRef VFSOverlayFile : HSOpts.VFSOverlayFiles)
+ AddString(VFSOverlayFile, Record);
+
+ Stream.EmitRecord(HEADER_SEARCH_PATHS, Record);
+
// Write out the diagnostic/pragma mappings.
WritePragmaDiagnosticMappings(Diags, /* isModule = */ WritingModule);
@@ -1187,8 +1229,7 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
/// Write the control block.
void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
- StringRef isysroot,
- const std::string &OutputFile) {
+ StringRef isysroot) {
using namespace llvm;
Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
@@ -1283,7 +1324,12 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
if (auto *AdditionalModMaps =
Map.getAdditionalModuleMapFiles(WritingModule)) {
Record.push_back(AdditionalModMaps->size());
- for (const FileEntry *F : *AdditionalModMaps)
+ SmallVector<const FileEntry *, 1> ModMaps(AdditionalModMaps->begin(),
+ AdditionalModMaps->end());
+ llvm::sort(ModMaps, [](const FileEntry *A, const FileEntry *B) {
+ return A->getName() < B->getName();
+ });
+ for (const FileEntry *F : ModMaps)
AddPath(F->getName(), Record);
} else {
Record.push_back(0);
@@ -1385,27 +1431,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
// Header search options.
Record.clear();
- const HeaderSearchOptions &HSOpts
- = PP.getHeaderSearchInfo().getHeaderSearchOpts();
- AddString(HSOpts.Sysroot, Record);
-
- // Include entries.
- Record.push_back(HSOpts.UserEntries.size());
- for (unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) {
- const HeaderSearchOptions::Entry &Entry = HSOpts.UserEntries[I];
- AddString(Entry.Path, Record);
- Record.push_back(static_cast<unsigned>(Entry.Group));
- Record.push_back(Entry.IsFramework);
- Record.push_back(Entry.IgnoreSysRoot);
- }
-
- // System header prefixes.
- Record.push_back(HSOpts.SystemHeaderPrefixes.size());
- for (unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) {
- AddString(HSOpts.SystemHeaderPrefixes[I].Prefix, Record);
- Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
- }
+ const HeaderSearchOptions &HSOpts =
+ PP.getHeaderSearchInfo().getHeaderSearchOpts();
+ AddString(HSOpts.Sysroot, Record);
AddString(HSOpts.ResourceDir, Record);
AddString(HSOpts.ModuleCachePath, Record);
AddString(HSOpts.ModuleUserBuildPath, Record);
@@ -1463,38 +1492,16 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Record.clear();
Record.push_back(ORIGINAL_FILE);
- Record.push_back(SM.getMainFileID().getOpaqueValue());
+ AddFileID(SM.getMainFileID(), Record);
EmitRecordWithPath(FileAbbrevCode, Record, MainFile->getName());
}
Record.clear();
- Record.push_back(SM.getMainFileID().getOpaqueValue());
+ AddFileID(SM.getMainFileID(), Record);
Stream.EmitRecord(ORIGINAL_FILE_ID, Record);
- // Original PCH directory
- if (!OutputFile.empty() && OutputFile != "-") {
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
- unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
-
- SmallString<128> OutputPath(OutputFile);
- PreparePathForOutput(OutputPath);
- StringRef origDir = llvm::sys::path::parent_path(OutputPath);
-
- RecordData::value_type Record[] = {ORIGINAL_PCH_DIR};
- Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir);
- }
-
- std::set<const FileEntry *> AffectingModuleMaps;
- if (WritingModule) {
- AffectingModuleMaps =
- GetAllModuleMaps(PP.getHeaderSearchInfo(), WritingModule);
- }
-
WriteInputFiles(Context.SourceMgr,
- PP.getHeaderSearchInfo().getHeaderSearchOpts(),
- AffectingModuleMaps);
+ PP.getHeaderSearchInfo().getHeaderSearchOpts());
Stream.ExitBlock();
}
@@ -1502,19 +1509,20 @@ namespace {
/// An input file.
struct InputFileEntry {
- const FileEntry *File;
+ FileEntryRef File;
bool IsSystemFile;
bool IsTransient;
bool BufferOverridden;
bool IsTopLevelModuleMap;
uint32_t ContentHash[2];
+
+ InputFileEntry(FileEntryRef File) : File(File) {}
};
} // namespace
-void ASTWriter::WriteInputFiles(
- SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
- std::set<const FileEntry *> &AffectingModuleMaps) {
+void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
+ HeaderSearchOptions &HSOpts) {
using namespace llvm;
Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
@@ -1538,9 +1546,9 @@ void ASTWriter::WriteInputFiles(
IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
unsigned IFHAbbrevCode = Stream.EmitAbbrev(std::move(IFHAbbrev));
- // Get all ContentCache objects for files, sorted by whether the file is a
- // system one or not. System files go at the back, users files at the front.
- std::deque<InputFileEntry> SortedFiles;
+ // Get all ContentCache objects for files.
+ std::vector<InputFileEntry> UserFiles;
+ std::vector<InputFileEntry> SystemFiles;
for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
// Get this source location entry.
const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
@@ -1554,18 +1562,11 @@ void ASTWriter::WriteInputFiles(
if (!Cache->OrigEntry)
continue;
- if (isModuleMap(File.getFileCharacteristic()) &&
- !isSystem(File.getFileCharacteristic()) &&
- !AffectingModuleMaps.empty() &&
- AffectingModuleMaps.find(Cache->OrigEntry) ==
- AffectingModuleMaps.end()) {
- SkippedModuleMaps.insert(Cache->OrigEntry);
- // Do not emit modulemaps that do not affect current module.
+ // Do not emit input files that do not affect current module.
+ if (!IsSLocAffecting[I])
continue;
- }
- InputFileEntry Entry;
- Entry.File = Cache->OrigEntry;
+ InputFileEntry Entry(*Cache->OrigEntry);
Entry.IsSystemFile = isSystem(File.getFileCharacteristic());
Entry.IsTransient = Cache->IsTransient;
Entry.BufferOverridden = Cache->BufferOverridden;
@@ -1580,9 +1581,8 @@ void ASTWriter::WriteInputFiles(
if (MemBuff)
ContentHash = hash_value(MemBuff->getBuffer());
else
- // FIXME: The path should be taken from the FileEntryRef.
PP->Diag(SourceLocation(), diag::err_module_unable_to_hash_content)
- << Entry.File->getName();
+ << Entry.File.getName();
}
auto CH = llvm::APInt(64, ContentHash);
Entry.ContentHash[0] =
@@ -1591,11 +1591,15 @@ void ASTWriter::WriteInputFiles(
static_cast<uint32_t>(CH.getHiBits(32).getZExtValue());
if (Entry.IsSystemFile)
- SortedFiles.push_back(Entry);
+ SystemFiles.push_back(Entry);
else
- SortedFiles.push_front(Entry);
+ UserFiles.push_back(Entry);
}
+ // User files go at the front, system files at the back.
+ auto SortedFiles = llvm::concat<InputFileEntry>(std::move(UserFiles),
+ std::move(SystemFiles));
+
unsigned UserFilesNum = 0;
// Write out all of the input files.
std::vector<uint64_t> InputFileOffsets;
@@ -1618,14 +1622,13 @@ void ASTWriter::WriteInputFiles(
RecordData::value_type Record[] = {
INPUT_FILE,
InputFileOffsets.size(),
- (uint64_t)Entry.File->getSize(),
+ (uint64_t)Entry.File.getSize(),
(uint64_t)getTimestampForOutput(Entry.File),
Entry.BufferOverridden,
Entry.IsTransient,
Entry.IsTopLevelModuleMap};
- // FIXME: The path should be taken from the FileEntryRef.
- EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName());
+ EmitRecordWithPath(IFAbbrevCode, Record, Entry.File.getNameAsRequested());
}
// Emit content hash for this file.
@@ -1830,14 +1833,12 @@ namespace {
auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
- uint32_t Value = (ModID << 2) | (unsigned)Role;
- assert((Value >> 2) == ModID && "overflow in header module info");
+ uint32_t Value = (ModID << 3) | (unsigned)Role;
+ assert((Value >> 3) == ModID && "overflow in header module info");
LE.write<uint32_t>(Value);
}
};
- // FIXME: If the header is excluded, we should write out some
- // record of that fact.
for (auto ModInfo : Data.KnownHeaders)
EmitModule(ModInfo.getModule(), ModInfo.getRole());
if (Data.Unresolved.getPointer())
@@ -1879,7 +1880,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
// headers list when emitting resolved headers in the first loop below.
// FIXME: It'd be preferable to avoid doing this if we were given
// sufficient stat information in the module map.
- HS.getModuleMap().resolveHeaderDirectives(M, /*File=*/llvm::None);
+ HS.getModuleMap().resolveHeaderDirectives(M, /*File=*/std::nullopt);
// If the file didn't exist, we can still create a module if we were given
// enough information in the module map.
@@ -2001,6 +2002,14 @@ static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
// Compress the buffer if possible. We expect that almost all PCM
// consumers will not want its contents.
SmallVector<uint8_t, 0> CompressedBuffer;
+ if (llvm::compression::zstd::isAvailable()) {
+ llvm::compression::zstd::compress(
+ llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer, 9);
+ RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, Blob.size() - 1};
+ Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
+ llvm::toStringRef(CompressedBuffer));
+ return;
+ }
if (llvm::compression::zlib::isAvailable()) {
llvm::compression::zlib::compress(
llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer);
@@ -2054,7 +2063,6 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// Record the offset of this source-location entry.
uint64_t Offset = Stream.GetCurrentBitNo() - SLocEntryOffsetsBase;
assert((Offset >> 32) == 0 && "SLocEntry offset too large");
- SLocEntryOffsets.push_back(Offset);
// Figure out which record code to use.
unsigned Code;
@@ -2069,17 +2077,15 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Record.clear();
Record.push_back(Code);
- // Starting offset of this entry within this module, so skip the dummy.
- Record.push_back(SLoc->getOffset() - 2);
if (SLoc->isFile()) {
const SrcMgr::FileInfo &File = SLoc->getFile();
const SrcMgr::ContentCache *Content = &File.getContentCache();
- if (Content->OrigEntry && !SkippedModuleMaps.empty() &&
- SkippedModuleMaps.find(Content->OrigEntry) !=
- SkippedModuleMaps.end()) {
- // Do not emit files that were not listed as inputs.
+ // Do not emit files that were not listed as inputs.
+ if (!IsSLocAffecting[I])
continue;
- }
+ SLocEntryOffsets.push_back(Offset);
+ // Starting offset of this entry within this module, so skip the dummy.
+ Record.push_back(getAdjustedOffset(SLoc->getOffset()) - 2);
AddSourceLocation(File.getIncludeLoc(), Record);
Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
Record.push_back(File.hasLineDirectives());
@@ -2093,7 +2099,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
assert(InputFileIDs[Content->OrigEntry] != 0 && "Missed file entry");
Record.push_back(InputFileIDs[Content->OrigEntry]);
- Record.push_back(File.NumCreatedFIDs);
+ Record.push_back(getAdjustedNumCreatedFIDs(FID));
FileDeclIDsTy::iterator FDI = FileDeclIDs.find(FID);
if (FDI != FileDeclIDs.end()) {
@@ -2115,7 +2121,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// We add one to the size so that we capture the trailing NULL
// that is required by llvm::MemoryBuffer::getMemBuffer (on
// the reader side).
- llvm::Optional<llvm::MemoryBufferRef> Buffer =
+ std::optional<llvm::MemoryBufferRef> Buffer =
Content->getBufferOrNone(PP.getDiagnostics(), PP.getFileManager());
StringRef Name = Buffer ? Buffer->getBufferIdentifier() : "";
Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
@@ -2129,7 +2135,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
if (EmitBlob) {
// Include the implicit terminating null character in the on-disk buffer
// if we're writing it uncompressed.
- llvm::Optional<llvm::MemoryBufferRef> Buffer =
+ std::optional<llvm::MemoryBufferRef> Buffer =
Content->getBufferOrNone(PP.getDiagnostics(), PP.getFileManager());
if (!Buffer)
Buffer = llvm::MemoryBufferRef("<<<INVALID BUFFER>>>", "");
@@ -2140,6 +2146,9 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
} else {
// The source location entry is a macro expansion.
const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion();
+ SLocEntryOffsets.push_back(Offset);
+ // Starting offset of this entry within this module, so skip the dummy.
+ Record.push_back(getAdjustedOffset(SLoc->getOffset()) - 2);
LocSeq::State Seq;
AddSourceLocation(Expansion.getSpellingLoc(), Record, Seq);
AddSourceLocation(Expansion.getExpansionLocStart(), Record, Seq);
@@ -2153,7 +2162,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
SourceLocation::UIntTy NextOffset = SourceMgr.getNextLocalOffset();
if (I + 1 != N)
NextOffset = SourceMgr.getLocalSLocEntry(I + 1).getOffset();
- Record.push_back(NextOffset - SLoc->getOffset() - 1);
+ Record.push_back(getAdjustedOffset(NextOffset - SLoc->getOffset()) - 1);
Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv, Record);
}
}
@@ -2177,7 +2186,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
{
RecordData::value_type Record[] = {
SOURCE_LOCATION_OFFSETS, SLocEntryOffsets.size(),
- SourceMgr.getNextLocalOffset() - 1 /* skip dummy */,
+ getAdjustedOffset(SourceMgr.getNextLocalOffset()) - 1 /* skip dummy */,
SLocEntryOffsetsBase - SourceManagerBlockOffset};
Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
bytes(SLocEntryOffsets));
@@ -2213,8 +2222,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
if (L.first.ID < 0)
continue;
- // Emit the file ID
- Record.push_back(L.first.ID);
+ AddFileID(L.first, Record);
// Emit the line entries
Record.push_back(L.second.size());
@@ -2341,11 +2349,14 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
// Construct the list of identifiers with macro directives that need to be
// serialized.
SmallVector<const IdentifierInfo *, 128> MacroIdentifiers;
- for (auto &Id : PP.getIdentifierTable())
- if (Id.second->hadMacroDefinition() &&
- (!Id.second->isFromAST() ||
- Id.second->hasChangedSinceDeserialization()))
- MacroIdentifiers.push_back(Id.second);
+ // It is meaningless to emit macros for named modules. It only wastes times
+ // and spaces.
+ if (!isWritingStdCXXNamedModules())
+ for (auto &Id : PP.getIdentifierTable())
+ if (Id.second->hadMacroDefinition() &&
+ (!Id.second->isFromAST() ||
+ Id.second->hasChangedSinceDeserialization()))
+ MacroIdentifiers.push_back(Id.second);
// Sort the set of macro definitions that need to be serialized by the
// name of the macro, to provide a stable ordering.
llvm::sort(MacroIdentifiers, llvm::deref<std::less<>>());
@@ -2577,7 +2588,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
assert((Offset >> 32) == 0 && "Preprocessed entity offset too large");
PreprocessedEntityOffsets.push_back(
- PPEntityOffset((*E)->getSourceRange(), Offset));
+ PPEntityOffset(getAdjustedRange((*E)->getSourceRange()), Offset));
if (auto *MD = dyn_cast<MacroDefinitionRecord>(*E)) {
// Record this macro definition's ID.
@@ -2677,12 +2688,12 @@ unsigned ASTWriter::getLocalOrImportedSubmoduleID(const Module *Mod) {
}
unsigned ASTWriter::getSubmoduleID(Module *Mod) {
+ unsigned ID = getLocalOrImportedSubmoduleID(Mod);
// FIXME: This can easily happen, if we have a reference to a submodule that
// did not result in us loading a module file for that submodule. For
// instance, a cross-top-level-module 'conflict' declaration will hit this.
- unsigned ID = getLocalOrImportedSubmoduleID(Mod);
- assert((ID || !Mod) &&
- "asked for module ID for non-local, non-imported module");
+ // assert((ID || !Mod) &&
+ // "asked for module ID for non-local, non-imported module");
return ID;
}
@@ -2882,6 +2893,14 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
}
+ // Emit the modules affecting compilation that were not imported.
+ if (!Mod->AffectingClangModules.empty()) {
+ RecordData Record;
+ for (auto *I : Mod->AffectingClangModules)
+ Record.push_back(getSubmoduleID(I));
+ Stream.EmitRecord(SUBMODULE_AFFECTING_MODULES, Record);
+ }
+
// Emit the exports.
if (!Mod->Exports.empty()) {
RecordData Record;
@@ -3016,7 +3035,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
Record.push_back(FileIDAndFile.second.StateTransitions.size());
for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
- Record.push_back(StatePoint.Offset);
+ Record.push_back(getAdjustedOffset(StatePoint.Offset));
AddDiagState(StatePoint.State, false);
}
}
@@ -4350,7 +4369,8 @@ void ASTRecordWriter::AddAttr(const Attr *A) {
// FIXME: Clang can't handle the serialization/deserialization of
// preferred_name properly now. See
// https://github.com/llvm/llvm-project/issues/56490 for example.
- if (!A || (isa<PreferredNameAttr>(A) && Writer->isWritingNamedModules()))
+ if (!A || (isa<PreferredNameAttr>(A) &&
+ Writer->isWritingStdCXXNamedModules()))
return Record.push_back(0);
Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs
@@ -4375,15 +4395,37 @@ void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) {
AddSourceLocation(Tok.getLocation(), Record);
- Record.push_back(Tok.getLength());
-
- // FIXME: When reading literal tokens, reconstruct the literal pointer
- // if it is needed.
- AddIdentifierRef(Tok.getIdentifierInfo(), Record);
// FIXME: Should translate token kind to a stable encoding.
Record.push_back(Tok.getKind());
// FIXME: Should translate token flags to a stable encoding.
Record.push_back(Tok.getFlags());
+
+ if (Tok.isAnnotation()) {
+ AddSourceLocation(Tok.getAnnotationEndLoc(), Record);
+ switch (Tok.getKind()) {
+ case tok::annot_pragma_loop_hint: {
+ auto *Info = static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
+ AddToken(Info->PragmaName, Record);
+ AddToken(Info->Option, Record);
+ Record.push_back(Info->Toks.size());
+ for (const auto &T : Info->Toks)
+ AddToken(T, Record);
+ break;
+ }
+ // Some annotation tokens do not use the PtrData field.
+ case tok::annot_pragma_openmp:
+ case tok::annot_pragma_openmp_end:
+ case tok::annot_pragma_unused:
+ break;
+ default:
+ llvm_unreachable("missing serialization code for annotation token");
+ }
+ } else {
+ Record.push_back(Tok.getLength());
+ // FIXME: When reading literal tokens, reconstruct the literal pointer if it
+ // is needed.
+ AddIdentifierRef(Tok.getIdentifierInfo(), Record);
+ }
}
void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {
@@ -4425,11 +4467,11 @@ void ASTWriter::EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
void ASTWriter::AddVersionTuple(const VersionTuple &Version,
RecordDataImpl &Record) {
Record.push_back(Version.getMajor());
- if (Optional<unsigned> Minor = Version.getMinor())
+ if (std::optional<unsigned> Minor = Version.getMinor())
Record.push_back(*Minor + 1);
else
Record.push_back(0);
- if (Optional<unsigned> Subminor = Version.getSubminor())
+ if (std::optional<unsigned> Subminor = Version.getSubminor())
Record.push_back(*Subminor + 1);
else
Record.push_back(0);
@@ -4481,11 +4523,11 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
return IncludeTimestamps ? E->getModificationTime() : 0;
}
-ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
- const std::string &OutputFile,
+ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors,
bool ShouldCacheASTInMemory) {
+ llvm::TimeTraceScope scope("WriteAST", OutputFile);
WritingAST = true;
ASTHasCompilerErrors = hasErrors;
@@ -4501,8 +4543,7 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
Context = &SemaRef.Context;
PP = &SemaRef.PP;
this->WritingModule = WritingModule;
- ASTFileSignature Signature =
- WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule);
+ ASTFileSignature Signature = WriteASTCore(SemaRef, isysroot, WritingModule);
Context = nullptr;
PP = nullptr;
this->WritingModule = nullptr;
@@ -4527,8 +4568,69 @@ static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
}
}
+void ASTWriter::collectNonAffectingInputFiles() {
+ SourceManager &SrcMgr = PP->getSourceManager();
+ unsigned N = SrcMgr.local_sloc_entry_size();
+
+ IsSLocAffecting.resize(N, true);
+
+ if (!WritingModule)
+ return;
+
+ auto AffectingModuleMaps = GetAffectingModuleMaps(*PP, WritingModule);
+
+ unsigned FileIDAdjustment = 0;
+ unsigned OffsetAdjustment = 0;
+
+ NonAffectingFileIDAdjustments.reserve(N);
+ NonAffectingOffsetAdjustments.reserve(N);
+
+ NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
+ NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
+
+ for (unsigned I = 1; I != N; ++I) {
+ const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(I);
+ FileID FID = FileID::get(I);
+ assert(&SrcMgr.getSLocEntry(FID) == SLoc);
+
+ if (!SLoc->isFile())
+ continue;
+ const SrcMgr::FileInfo &File = SLoc->getFile();
+ const SrcMgr::ContentCache *Cache = &File.getContentCache();
+ if (!Cache->OrigEntry)
+ continue;
+
+ if (!isModuleMap(File.getFileCharacteristic()) ||
+ AffectingModuleMaps.empty() ||
+ AffectingModuleMaps.find(Cache->OrigEntry) != AffectingModuleMaps.end())
+ continue;
+
+ IsSLocAffecting[I] = false;
+
+ FileIDAdjustment += 1;
+ // Even empty files take up one element in the offset table.
+ OffsetAdjustment += SrcMgr.getFileIDSize(FID) + 1;
+
+ // If the previous file was non-affecting as well, just extend its entry
+ // with our information.
+ if (!NonAffectingFileIDs.empty() &&
+ NonAffectingFileIDs.back().ID == FID.ID - 1) {
+ NonAffectingFileIDs.back() = FID;
+ NonAffectingRanges.back().setEnd(SrcMgr.getLocForEndOfFile(FID));
+ NonAffectingFileIDAdjustments.back() = FileIDAdjustment;
+ NonAffectingOffsetAdjustments.back() = OffsetAdjustment;
+ continue;
+ }
+
+ NonAffectingFileIDs.push_back(FID);
+ NonAffectingRanges.emplace_back(SrcMgr.getLocForStartOfFile(FID),
+ SrcMgr.getLocForEndOfFile(FID));
+ NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
+ NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
+ }
+}
+
ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
- const std::string &OutputFile,
Module *WritingModule) {
using namespace llvm;
@@ -4541,6 +4643,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
ASTContext &Context = SemaRef.Context;
Preprocessor &PP = SemaRef.PP;
+ collectNonAffectingInputFiles();
+
// Set up predefined declaration IDs.
auto RegisterPredefDecl = [&] (Decl *D, PredefinedDeclIDs ID) {
if (D) {
@@ -4682,7 +4786,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
}
// Write the control block
- WriteControlBlock(PP, Context, isysroot, OutputFile);
+ WriteControlBlock(PP, Context, isysroot);
// Write the remaining AST contents.
Stream.FlushToWord();
@@ -5205,7 +5309,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
break;
case UPD_ADDED_ATTR_TO_RECORD:
- Record.AddAttributes(llvm::makeArrayRef(Update.getAttr()));
+ Record.AddAttributes(llvm::ArrayRef(Update.getAttr()));
break;
}
}
@@ -5229,8 +5333,75 @@ void ASTWriter::AddAlignPackInfo(const Sema::AlignPackInfo &Info,
Record.push_back(Raw);
}
+FileID ASTWriter::getAdjustedFileID(FileID FID) const {
+ if (FID.isInvalid() || PP->getSourceManager().isLoadedFileID(FID) ||
+ NonAffectingFileIDs.empty())
+ return FID;
+ auto It = llvm::lower_bound(NonAffectingFileIDs, FID);
+ unsigned Idx = std::distance(NonAffectingFileIDs.begin(), It);
+ unsigned Offset = NonAffectingFileIDAdjustments[Idx];
+ return FileID::get(FID.getOpaqueValue() - Offset);
+}
+
+unsigned ASTWriter::getAdjustedNumCreatedFIDs(FileID FID) const {
+ unsigned NumCreatedFIDs = PP->getSourceManager()
+ .getLocalSLocEntry(FID.ID)
+ .getFile()
+ .NumCreatedFIDs;
+
+ unsigned AdjustedNumCreatedFIDs = 0;
+ for (unsigned I = FID.ID, N = I + NumCreatedFIDs; I != N; ++I)
+ if (IsSLocAffecting[I])
+ ++AdjustedNumCreatedFIDs;
+ return AdjustedNumCreatedFIDs;
+}
+
+SourceLocation ASTWriter::getAdjustedLocation(SourceLocation Loc) const {
+ if (Loc.isInvalid())
+ return Loc;
+ return Loc.getLocWithOffset(-getAdjustment(Loc.getOffset()));
+}
+
+SourceRange ASTWriter::getAdjustedRange(SourceRange Range) const {
+ return SourceRange(getAdjustedLocation(Range.getBegin()),
+ getAdjustedLocation(Range.getEnd()));
+}
+
+SourceLocation::UIntTy
+ASTWriter::getAdjustedOffset(SourceLocation::UIntTy Offset) const {
+ return Offset - getAdjustment(Offset);
+}
+
+SourceLocation::UIntTy
+ASTWriter::getAdjustment(SourceLocation::UIntTy Offset) const {
+ if (NonAffectingRanges.empty())
+ return 0;
+
+ if (PP->getSourceManager().isLoadedOffset(Offset))
+ return 0;
+
+ if (Offset > NonAffectingRanges.back().getEnd().getOffset())
+ return NonAffectingOffsetAdjustments.back();
+
+ if (Offset < NonAffectingRanges.front().getBegin().getOffset())
+ return 0;
+
+ auto Contains = [](const SourceRange &Range, SourceLocation::UIntTy Offset) {
+ return Range.getEnd().getOffset() < Offset;
+ };
+
+ auto It = llvm::lower_bound(NonAffectingRanges, Offset, Contains);
+ unsigned Idx = std::distance(NonAffectingRanges.begin(), It);
+ return NonAffectingOffsetAdjustments[Idx];
+}
+
+void ASTWriter::AddFileID(FileID FID, RecordDataImpl &Record) {
+ Record.push_back(getAdjustedFileID(FID).getOpaqueValue());
+}
+
void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record,
SourceLocationSequence *Seq) {
+ Loc = getAdjustedLocation(Loc);
Record.push_back(SourceLocationEncoding::encode(Loc, Seq));
}
@@ -5472,7 +5643,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) {
// a function/objc method, should not have TU as lexical context.
// TemplateTemplateParmDecls that are part of an alias template, should not
// have TU as lexical context.
- if (isa<ParmVarDecl>(D) || isa<TemplateTemplateParmDecl>(D))
+ if (isa<ParmVarDecl, TemplateTemplateParmDecl>(D))
return;
SourceManager &SM = Context->getSourceManager();
@@ -5484,6 +5655,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) {
if (FID.isInvalid())
return;
assert(SM.getSLocEntry(FID).isFile());
+ assert(IsSLocAffecting[FID.ID]);
std::unique_ptr<DeclIDInFileInfo> &Info = FileDeclIDs[FID];
if (!Info)
@@ -5775,7 +5947,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
AddDeclRef(D->getLambdaContextDecl());
AddTypeSourceInfo(Lambda.MethodTyInfo);
for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
- const LambdaCapture &Capture = Lambda.Captures[I];
+ const LambdaCapture &Capture = Lambda.Captures.front()[I];
AddSourceLocation(Capture.getLocation());
Record->push_back(Capture.isImplicit());
Record->push_back(Capture.getCaptureKind());
@@ -5786,7 +5958,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
break;
case LCK_ByCopy:
case LCK_ByRef:
- VarDecl *Var =
+ ValueDecl *Var =
Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
AddDeclRef(Var);
AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc()
@@ -6618,9 +6790,12 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
Record.push_back(C->getTotalComponentListNum());
Record.push_back(C->getTotalComponentsNum());
Record.AddSourceLocation(C->getLParenLoc());
+ bool HasIteratorModifier = false;
for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
Record.push_back(C->getMapTypeModifier(I));
Record.AddSourceLocation(C->getMapTypeModifierLoc(I));
+ if (C->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator)
+ HasIteratorModifier = true;
}
Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
Record.AddDeclarationNameInfo(C->getMapperIdInfo());
@@ -6631,6 +6806,8 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
Record.AddStmt(E);
for (auto *E : C->mapperlists())
Record.AddStmt(E);
+ if (HasIteratorModifier)
+ Record.AddStmt(C->getIteratorModifier());
for (auto *D : C->all_decls())
Record.AddDeclRef(D);
for (auto N : C->all_num_lists())
@@ -6672,13 +6849,17 @@ void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) {
void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
VisitOMPClauseWithPreInit(C);
+ Record.writeEnum(C->getModifier());
Record.AddStmt(C->getGrainsize());
+ Record.AddSourceLocation(C->getModifierLoc());
Record.AddSourceLocation(C->getLParenLoc());
}
void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
VisitOMPClauseWithPreInit(C);
+ Record.writeEnum(C->getModifier());
Record.AddStmt(C->getNumTasks());
+ Record.AddSourceLocation(C->getModifierLoc());
Record.AddSourceLocation(C->getLParenLoc());
}
@@ -6866,6 +7047,23 @@ void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
}
+void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
+ Record.push_back(C->getAtKind());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getAtKindKwLoc());
+}
+
+void OMPClauseWriter::VisitOMPSeverityClause(OMPSeverityClause *C) {
+ Record.push_back(C->getSeverityKind());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getSeverityKindKwLoc());
+}
+
+void OMPClauseWriter::VisitOMPMessageClause(OMPMessageClause *C) {
+ Record.AddStmt(C->getMessageString());
+ Record.AddSourceLocation(C->getLParenLoc());
+}
+
void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
Record.push_back(C->varlist_size());
Record.AddSourceLocation(C->getLParenLoc());
@@ -6891,8 +7089,10 @@ void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) {
void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) {
Record.writeEnum(C->getKind());
+ Record.writeEnum(C->getModifier());
Record.AddSourceLocation(C->getLParenLoc());
Record.AddSourceLocation(C->getKindKwLoc());
+ Record.AddSourceLocation(C->getModifierKwLoc());
}
void OMPClauseWriter::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) {
@@ -6922,6 +7122,12 @@ void OMPClauseWriter::VisitOMPBindClause(OMPBindClause *C) {
Record.AddSourceLocation(C->getBindKindLoc());
}
+void OMPClauseWriter::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) {
+ VisitOMPClauseWithPreInit(C);
+ Record.AddStmt(C->getSize());
+ Record.AddSourceLocation(C->getLParenLoc());
+}
+
void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo *TI) {
writeUInt32(TI->Sets.size());
for (const auto &Set : TI->Sets) {
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
index 35b8db27bd0e..a58e0d796b31 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -23,6 +23,7 @@
#include "clang/Serialization/ASTRecordWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
#include "llvm/Support/ErrorHandling.h"
+#include <optional>
using namespace clang;
using namespace serialization;
@@ -107,6 +108,8 @@ namespace clang {
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
void VisitConceptDecl(ConceptDecl *D);
+ void VisitImplicitConceptSpecializationDecl(
+ ImplicitConceptSpecializationDecl *D);
void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
@@ -122,6 +125,7 @@ namespace clang {
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
void VisitExportDecl(ExportDecl *D);
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+ void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
void VisitImportDecl(ImportDecl *D);
void VisitAccessSpecDecl(AccessSpecDecl *D);
void VisitFriendDecl(FriendDecl *D);
@@ -131,10 +135,9 @@ namespace clang {
void VisitCapturedDecl(CapturedDecl *D);
void VisitEmptyDecl(EmptyDecl *D);
void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
-
void VisitDeclContext(DeclContext *DC);
template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
-
+ void VisitHLSLBufferDecl(HLSLBufferDecl *D);
// FIXME: Put in the same order is DeclNodes.td?
void VisitObjCMethodDecl(ObjCMethodDecl *D);
@@ -167,7 +170,7 @@ namespace clang {
}
Record.push_back(typeParams->size());
- for (auto typeParam : *typeParams) {
+ for (auto *typeParam : *typeParams) {
Record.AddDeclRef(typeParam);
}
Record.AddSourceLocation(typeParams->getLAngleLoc());
@@ -203,7 +206,7 @@ namespace clang {
return Common->PartialSpecializations;
}
ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) {
- return None;
+ return std::nullopt;
}
template<typename DeclTy>
@@ -221,7 +224,7 @@ namespace clang {
ArrayRef<DeclID> LazySpecializations;
if (auto *LS = Common->LazySpecializations)
- LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
+ LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]);
// Add a slot to the record for the number of specializations.
unsigned I = Record.size();
@@ -488,6 +491,10 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
Record.push_back(D->hasNonTrivialToPrimitiveCopyCUnion());
Record.push_back(D->isParamDestroyedInCallee());
Record.push_back(D->getArgPassingRestrictions());
+ // Only compute this for C/Objective-C, in C++ this is computed as part
+ // of CXXRecordDecl.
+ if (!isa<CXXRecordDecl>(D))
+ Record.push_back(D->getODRHash());
if (D->getDeclContext() == D->getLexicalDeclContext() &&
!D->hasAttrs() &&
@@ -540,46 +547,6 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitRedeclarable(D);
- VisitDeclaratorDecl(D);
- Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
- Record.push_back(D->getIdentifierNamespace());
-
- // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
- // after everything else is written.
- Record.push_back(static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
- Record.push_back(D->isInlineSpecified());
- Record.push_back(D->isInlined());
- Record.push_back(D->isVirtualAsWritten());
- Record.push_back(D->isPure());
- Record.push_back(D->hasInheritedPrototype());
- Record.push_back(D->hasWrittenPrototype());
- Record.push_back(D->isDeletedBit());
- Record.push_back(D->isTrivial());
- Record.push_back(D->isTrivialForCall());
- Record.push_back(D->isDefaulted());
- Record.push_back(D->isExplicitlyDefaulted());
- Record.push_back(D->hasImplicitReturnZero());
- Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
- Record.push_back(D->usesSEHTry());
- Record.push_back(D->hasSkippedBody());
- Record.push_back(D->isMultiVersion());
- Record.push_back(D->isLateTemplateParsed());
- Record.push_back(D->getLinkageInternal());
- Record.AddSourceLocation(D->getEndLoc());
-
- Record.push_back(D->getODRHash());
-
- if (D->isDefaulted()) {
- if (auto *FDI = D->getDefaultedFunctionInfo()) {
- Record.push_back(FDI->getUnqualifiedLookups().size());
- for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
- Record.AddDeclRef(P.getDecl());
- Record.push_back(P.getAccess());
- }
- } else {
- Record.push_back(0);
- }
- }
Record.push_back(D->getTemplatedKind());
switch (D->getTemplatedKind()) {
@@ -660,8 +627,53 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
}
}
+ VisitDeclaratorDecl(D);
+ Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
+ Record.push_back(D->getIdentifierNamespace());
+
+ // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
+ // after everything else is written.
+ Record.push_back(
+ static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
+ Record.push_back(D->isInlineSpecified());
+ Record.push_back(D->isInlined());
+ Record.push_back(D->isVirtualAsWritten());
+ Record.push_back(D->isPure());
+ Record.push_back(D->hasInheritedPrototype());
+ Record.push_back(D->hasWrittenPrototype());
+ Record.push_back(D->isDeletedBit());
+ Record.push_back(D->isTrivial());
+ Record.push_back(D->isTrivialForCall());
+ Record.push_back(D->isDefaulted());
+ Record.push_back(D->isExplicitlyDefaulted());
+ Record.push_back(D->isIneligibleOrNotSelected());
+ Record.push_back(D->hasImplicitReturnZero());
+ Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
+ Record.push_back(D->usesSEHTry());
+ Record.push_back(D->hasSkippedBody());
+ Record.push_back(D->isMultiVersion());
+ Record.push_back(D->isLateTemplateParsed());
+ Record.push_back(D->FriendConstraintRefersToEnclosingTemplate());
+ Record.push_back(D->getLinkageInternal());
+ Record.AddSourceLocation(D->getEndLoc());
+ Record.AddSourceLocation(D->getDefaultLoc());
+
+ Record.push_back(D->getODRHash());
+
+ if (D->isDefaulted()) {
+ if (auto *FDI = D->getDefaultedFunctionInfo()) {
+ Record.push_back(FDI->getUnqualifiedLookups().size());
+ for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
+ Record.AddDeclRef(P.getDecl());
+ Record.push_back(P.getAccess());
+ }
+ } else {
+ Record.push_back(0);
+ }
+ }
+
Record.push_back(D->param_size());
- for (auto P : D->parameters())
+ for (auto *P : D->parameters())
Record.AddDeclRef(P);
Code = serialization::DECL_FUNCTION;
}
@@ -763,6 +775,7 @@ void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Record.AddTypeSourceInfo(D->getSuperClassTInfo());
Record.AddSourceLocation(D->getEndOfDefinitionLoc());
Record.push_back(Data.HasDesignatedInitializers);
+ Record.push_back(D->getODRHash());
// Write out the protocols that are directly referenced by the @interface.
Record.push_back(Data.ReferencedProtocols.size());
@@ -825,6 +838,7 @@ void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Record.AddDeclRef(I);
for (const auto &PL : D->protocol_locs())
Record.AddSourceLocation(PL);
+ Record.push_back(D->getODRHash());
}
Code = serialization::DECL_OBJC_PROTOCOL;
@@ -900,7 +914,7 @@ void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
Record.push_back(D->NumIvarInitializers);
if (D->NumIvarInitializers)
Record.AddCXXCtorInitializers(
- llvm::makeArrayRef(D->init_begin(), D->init_end()));
+ llvm::ArrayRef(D->init_begin(), D->init_end()));
Code = serialization::DECL_OBJC_IMPLEMENTATION;
}
@@ -1030,8 +1044,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
if (D->getStorageDuration() == SD_Static) {
bool ModulesCodegen = false;
if (Writer.WritingModule &&
- !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
- !isa<VarTemplateSpecializationDecl>(D)) {
+ !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo()) {
// When building a C++20 module interface unit or a partition unit, a
// strong definition in the module interface is provided by the
// compilation of that unit, not by its users. (Inline variables are still
@@ -1165,6 +1178,12 @@ void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
Code = serialization::DECL_FILE_SCOPE_ASM;
}
+void ASTDeclWriter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
+ VisitDecl(D);
+ Record.AddStmt(D->getStmt());
+ Code = serialization::DECL_TOP_LEVEL_STMT_DECL;
+}
+
void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
VisitDecl(D);
Code = serialization::DECL_EMPTY;
@@ -1246,6 +1265,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
VisitRedeclarable(D);
VisitNamedDecl(D);
Record.push_back(D->isInline());
+ Record.push_back(D->isNested());
Record.AddSourceLocation(D->getBeginLoc());
Record.AddSourceLocation(D->getRBraceLoc());
@@ -1293,7 +1313,7 @@ void ASTDeclWriter::VisitUsingEnumDecl(UsingEnumDecl *D) {
VisitNamedDecl(D);
Record.AddSourceLocation(D->getUsingLoc());
Record.AddSourceLocation(D->getEnumLoc());
- Record.AddDeclRef(D->getEnumDecl());
+ Record.AddTypeSourceInfo(D->getEnumType());
Record.AddDeclRef(D->FirstUsingShadow.getPointer());
Record.AddDeclRef(Context.getInstantiatedFromUsingEnumDecl(D));
Code = serialization::DECL_USING_ENUM;
@@ -1404,14 +1424,12 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
}
if (D->getDeclContext() == D->getLexicalDeclContext() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->hasAttrs() &&
- !D->isTopLevelDeclInObjCContainer() &&
+ D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
+ !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->hasExtInfo() &&
- !D->hasInheritedPrototype() &&
- D->hasWrittenPrototype())
+ !D->hasExtInfo() && !D->hasInheritedPrototype() &&
+ D->hasWrittenPrototype() &&
+ D->getTemplatedKind() == FunctionDecl::TK_NonTemplate)
AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
Code = serialization::DECL_CXX_METHOD;
@@ -1505,8 +1523,8 @@ void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
VisitNamedDecl(D);
- Record.AddDeclRef(D->getTemplatedDecl());
Record.AddTemplateParameterList(D->getTemplateParameters());
+ Record.AddDeclRef(D->getTemplatedDecl());
}
void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
@@ -1515,6 +1533,15 @@ void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
Code = serialization::DECL_CONCEPT;
}
+void ASTDeclWriter::VisitImplicitConceptSpecializationDecl(
+ ImplicitConceptSpecializationDecl *D) {
+ Record.push_back(D->getTemplateArguments().size());
+ VisitDecl(D);
+ for (const TemplateArgument &Arg : D->getTemplateArguments())
+ Record.AddTemplateArgument(Arg);
+ Code = serialization::DECL_IMPLICIT_CONCEPT_SPECIALIZATION;
+}
+
void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
Code = serialization::DECL_REQUIRES_EXPR_BODY;
}
@@ -1607,8 +1634,6 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
VarTemplateSpecializationDecl *D) {
RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
- VisitVarDecl(D);
-
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
InstFrom = D->getSpecializedTemplateOrPartial();
if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
@@ -1629,6 +1654,9 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
Record.AddSourceLocation(D->getPointOfInstantiation());
Record.push_back(D->getSpecializationKind());
Record.push_back(D->IsCompleteDefinition);
+
+ VisitVarDecl(D);
+
Record.push_back(D->isCanonicalDecl());
if (D->isCanonicalDecl()) {
@@ -1864,6 +1892,17 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
}
}
+void ASTDeclWriter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
+ VisitNamedDecl(D);
+ VisitDeclContext(D);
+ Record.push_back(D->isCBuffer());
+ Record.AddSourceLocation(D->getLocStart());
+ Record.AddSourceLocation(D->getLBraceLoc());
+ Record.AddSourceLocation(D->getRBraceLoc());
+
+ Code = serialization::DECL_HLSL_BUFFER;
+}
+
void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
Record.writeOMPChildren(D->Data);
VisitDecl(D);
@@ -2093,6 +2132,8 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
// getArgPassingRestrictions
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
+ // ODRHash
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 26));
// DC
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
@@ -2233,6 +2274,8 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
// RedeclarableDecl
Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
+ // FIXME: Implement abbreviation for other template kinds.
+ Abv->Add(BitCodeAbbrevOp(FunctionDecl::TK_NonTemplate)); // TemplateKind
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
@@ -2269,20 +2312,22 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // TrivialForCall
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsIneligibleOrNotSelected
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Constexpr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // MultiVersion
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FriendConstraintRefersToEnclosingTemplate
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Default
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
// This Array slurps the rest of the record. Fortunately we want to encode
// (nearly) all the remaining (variable number of) fields in the same way.
//
- // This is the function template information if any, then
+ // This is:
// NumParams and Params[] from FunctionDecl, and
// NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
//
@@ -2389,7 +2434,7 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context,
// File scoped assembly or obj-c or OMP declare target implementation must be
// seen.
- if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
+ if (isa<FileScopeAsmDecl, TopLevelStmtDecl, ObjCImplDecl>(D))
return true;
if (WritingModule && isPartOfPerModuleInitializer(D)) {
@@ -2429,11 +2474,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
SourceLocation Loc = D->getLocation();
unsigned Index = ID - FirstDeclID;
if (DeclOffsets.size() == Index)
- DeclOffsets.emplace_back(Loc, Offset, DeclTypesBlockStartOffset);
+ DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset,
+ DeclTypesBlockStartOffset);
else if (DeclOffsets.size() < Index) {
// FIXME: Can/should this happen?
DeclOffsets.resize(Index+1);
- DeclOffsets[Index].setLocation(Loc);
+ DeclOffsets[Index].setLocation(getAdjustedLocation(Loc));
DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset);
} else {
llvm_unreachable("declarations should be emitted in ID order");
@@ -2456,7 +2502,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
assert(FD->doesThisDeclarationHaveABody());
bool ModulesCodegen = false;
if (!FD->isDependentContext()) {
- Optional<GVALinkage> Linkage;
+ std::optional<GVALinkage> Linkage;
if (Writer->WritingModule &&
Writer->WritingModule->isInterfaceOrPartition()) {
// When building a C++20 module interface unit or a partition unit, a
@@ -2486,8 +2532,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
Record->push_back(CD->getNumCtorInitializers());
if (CD->getNumCtorInitializers())
- AddCXXCtorInitializers(
- llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
+ AddCXXCtorInitializers(llvm::ArrayRef(CD->init_begin(), CD->init_end()));
}
AddStmt(FD->getBody());
}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
index 5e5a86ee01a2..b35a7cee5af2 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -402,6 +402,7 @@ static void
addConstraintSatisfaction(ASTRecordWriter &Record,
const ASTConstraintSatisfaction &Satisfaction) {
Record.push_back(Satisfaction.IsSatisfied);
+ Record.push_back(Satisfaction.ContainsErrors);
if (!Satisfaction.IsSatisfied) {
Record.push_back(Satisfaction.NumRecords);
for (const auto &DetailRecord : Satisfaction) {
@@ -432,16 +433,13 @@ addSubstitutionDiagnostic(
void ASTStmtWriter::VisitConceptSpecializationExpr(
ConceptSpecializationExpr *E) {
VisitExpr(E);
- ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments();
- Record.push_back(TemplateArgs.size());
Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc());
Record.AddSourceLocation(E->getTemplateKWLoc());
Record.AddDeclarationNameInfo(E->getConceptNameInfo());
Record.AddDeclRef(E->getNamedConcept());
Record.AddDeclRef(E->getFoundDecl());
+ Record.AddDeclRef(E->getSpecializationDecl());
Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
- for (const TemplateArgument &Arg : TemplateArgs)
- Record.AddTemplateArgument(Arg);
if (!E->isValueDependent())
addConstraintSatisfaction(Record, E->getSatisfaction());
@@ -495,12 +493,12 @@ void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
} else {
auto *NestedReq = cast<concepts::NestedRequirement>(R);
Record.push_back(concepts::Requirement::RK_Nested);
- Record.push_back(NestedReq->isSubstitutionFailure());
- if (NestedReq->isSubstitutionFailure()){
- addSubstitutionDiagnostic(Record,
- NestedReq->getSubstitutionDiagnostic());
+ Record.push_back(NestedReq->hasInvalidConstraint());
+ if (NestedReq->hasInvalidConstraint()) {
+ Record.AddString(NestedReq->getInvalidConstraintEntity());
+ addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
} else {
- Record.AddStmt(NestedReq->Value.get<Expr *>());
+ Record.AddStmt(NestedReq->getConstraintExpr());
if (!NestedReq->isDependent())
addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
}
@@ -1747,14 +1745,20 @@ void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
Record.AddDeclRef(E->getParam());
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
Record.AddSourceLocation(E->getUsedLocation());
+ Record.push_back(E->hasRewrittenInit());
+ if (E->hasRewrittenInit())
+ Record.AddStmt(E->getRewrittenExpr());
Code = serialization::EXPR_CXX_DEFAULT_ARG;
}
void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
VisitExpr(E);
+ Record.push_back(E->hasRewrittenInit());
Record.AddDeclRef(E->getField());
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
Record.AddSourceLocation(E->getExprLoc());
+ if (E->hasRewrittenInit())
+ Record.AddStmt(E->getRewrittenExpr());
Code = serialization::EXPR_CXX_DEFAULT_INIT;
}
@@ -2027,8 +2031,13 @@ void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
- Record.AddDeclRef(E->getParameter());
+ Record.AddDeclRef(E->getAssociatedDecl());
Record.push_back(E->isReferenceParameter());
+ Record.push_back(E->getIndex());
+ if (auto PackIndex = E->getPackIndex())
+ Record.push_back(*PackIndex + 1);
+ else
+ Record.push_back(0);
Record.AddSourceLocation(E->getNameLoc());
Record.AddStmt(E->getReplacement());
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
@@ -2037,7 +2046,8 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
SubstNonTypeTemplateParmPackExpr *E) {
VisitExpr(E);
- Record.AddDeclRef(E->getParameterPack());
+ Record.AddDeclRef(E->getAssociatedDecl());
+ Record.push_back(E->getIndex());
Record.AddTemplateArgument(E->getArgumentPack());
Record.AddSourceLocation(E->getParameterPackLocation());
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
@@ -2077,6 +2087,30 @@ void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
Code = serialization::EXPR_CXX_FOLD;
}
+void ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
+ VisitExpr(E);
+ ArrayRef<Expr *> InitExprs = E->getInitExprs();
+ Record.push_back(InitExprs.size());
+ Record.push_back(E->getUserSpecifiedInitExprs().size());
+ Record.AddSourceLocation(E->getInitLoc());
+ Record.AddSourceLocation(E->getBeginLoc());
+ Record.AddSourceLocation(E->getEndLoc());
+ for (Expr *InitExpr : E->getInitExprs())
+ Record.AddStmt(InitExpr);
+ Expr *ArrayFiller = E->getArrayFiller();
+ FieldDecl *UnionField = E->getInitializedFieldInUnion();
+ bool HasArrayFillerOrUnionDecl = ArrayFiller || UnionField;
+ Record.push_back(HasArrayFillerOrUnionDecl);
+ if (HasArrayFillerOrUnionDecl) {
+ Record.push_back(static_cast<bool>(ArrayFiller));
+ if (ArrayFiller)
+ Record.AddStmt(ArrayFiller);
+ else
+ Record.AddDeclRef(UnionField);
+ }
+ Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
+}
+
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
VisitExpr(E);
Record.AddStmt(E->getSourceExpr());
@@ -2392,6 +2426,13 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPErrorDirective(OMPErrorDirective *D) {
+ VisitStmt(D);
+ Record.push_back(D->getNumClauses());
+ VisitOMPExecutableDirective(D);
+ Code = serialization::STMT_OMP_ERROR_DIRECTIVE;
+}
+
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
diff --git a/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp b/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp
index 4fd217cf7a6e..81dd54692d77 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ModuleManager.cpp
@@ -249,7 +249,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
return NewlyLoaded;
}
-void ModuleManager::removeModules(ModuleIterator First, ModuleMap *modMap) {
+void ModuleManager::removeModules(ModuleIterator First) {
auto Last = end();
if (First == Last)
return;
@@ -280,19 +280,10 @@ void ModuleManager::removeModules(ModuleIterator First, ModuleMap *modMap) {
}
}
- // Delete the modules and erase them from the various structures.
- for (ModuleIterator victim = First; victim != Last; ++victim) {
+ // Delete the modules.
+ for (ModuleIterator victim = First; victim != Last; ++victim)
Modules.erase(victim->File);
- if (modMap) {
- StringRef ModuleName = victim->ModuleName;
- if (Module *mod = modMap->findModule(ModuleName)) {
- mod->setASTFile(None);
- }
- }
- }
-
- // Delete the modules.
Chain.erase(Chain.begin() + (First - begin()), Chain.end());
}
@@ -453,14 +444,14 @@ void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
bool ModuleManager::lookupModuleFile(StringRef FileName, off_t ExpectedSize,
time_t ExpectedModTime,
- Optional<FileEntryRef> &File) {
- File = None;
+ OptionalFileEntryRef &File) {
+ File = std::nullopt;
if (FileName == "-")
return false;
// Open the file immediately to ensure there is no race between stat'ing and
// opening the file.
- Optional<FileEntryRef> FileOrErr =
+ OptionalFileEntryRef FileOrErr =
expectedToOptional(FileMgr.getFileRef(FileName, /*OpenFile=*/true,
/*CacheFailure=*/false));
if (!FileOrErr)