aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Serialization
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-07-27 23:34:35 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-10-23 18:26:01 +0000
commit0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch)
tree6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/clang/lib/Serialization
parent6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff)
parentac9a064cb179f3425b310fa2847f8764ac970a4d (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Serialization')
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp18
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTCommon.h24
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp1215
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp346
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h10
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp180
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp1860
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp179
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp117
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/GeneratePCH.cpp87
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/GlobalModuleIndex.cpp14
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ModuleFile.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/ModuleFileExtension.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/MultiOnDiskHashTable.h4
-rw-r--r--contrib/llvm-project/clang/lib/Serialization/PCHContainerOperations.cpp2
15 files changed, 2734 insertions, 1330 deletions
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
index 6110e287b7fb..444a8a3d3a51 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
@@ -186,6 +186,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::Overload:
ID = PREDEF_TYPE_OVERLOAD_ID;
break;
+ case BuiltinType::UnresolvedTemplate:
+ ID = PREDEF_TYPE_UNRESOLVED_TEMPLATE;
+ break;
case BuiltinType::BoundMember:
ID = PREDEF_TYPE_BOUND_MEMBER;
break;
@@ -255,14 +258,19 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
ID = PREDEF_TYPE_##Id##_ID; \
break;
#include "clang/Basic/WebAssemblyReferenceTypes.def"
+#define AMDGPU_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id: \
+ ID = PREDEF_TYPE_##Id##_ID; \
+ break;
+#include "clang/Basic/AMDGPUTypes.def"
case BuiltinType::BuiltinFn:
ID = PREDEF_TYPE_BUILTIN_FN;
break;
case BuiltinType::IncompleteMatrixIdx:
ID = PREDEF_TYPE_INCOMPLETE_MATRIX_IDX;
break;
- case BuiltinType::OMPArraySection:
- ID = PREDEF_TYPE_OMP_ARRAY_SECTION;
+ case BuiltinType::ArraySection:
+ ID = PREDEF_TYPE_ARRAY_SECTION;
break;
case BuiltinType::OMPArrayShaping:
ID = PREDEF_TYPE_OMP_ARRAY_SHAPING;
@@ -275,7 +283,7 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
break;
}
- return TypeIdx(ID);
+ return TypeIdx(0, ID);
}
unsigned serialization::ComputeHash(Selector Sel) {
@@ -284,7 +292,7 @@ unsigned serialization::ComputeHash(Selector Sel) {
++N;
unsigned R = 5381;
for (unsigned I = 0; I != N; ++I)
- if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
+ if (const IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
R = llvm::djbHash(II->getName(), R);
return R;
}
@@ -338,7 +346,7 @@ serialization::getDefinitiveDeclContext(const DeclContext *DC) {
// FIXME: These are defined in one place, but properties in class extensions
// end up being back-patched into the main interface. See
- // Sema::HandlePropertyInClassExtension for the offending code.
+ // SemaObjC::HandlePropertyInClassExtension for the offending code.
case Decl::ObjCInterface:
return nullptr;
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTCommon.h b/contrib/llvm-project/clang/lib/Serialization/ASTCommon.h
index 296642e3674a..0230908d3e05 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTCommon.h
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTCommon.h
@@ -46,30 +46,6 @@ enum DeclUpdateKind {
TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
-template <typename IdxForTypeTy>
-TypeID MakeTypeID(ASTContext &Context, QualType T, IdxForTypeTy IdxForType) {
- if (T.isNull())
- return PREDEF_TYPE_NULL_ID;
-
- unsigned FastQuals = T.getLocalFastQualifiers();
- T.removeLocalFastQualifiers();
-
- if (T.hasLocalNonFastQualifiers())
- return IdxForType(T).asTypeID(FastQuals);
-
- assert(!T.hasLocalQualifiers());
-
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
- return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
-
- if (T == Context.AutoDeductTy)
- return TypeIdx(PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
- if (T == Context.AutoRRefDeductTy)
- return TypeIdx(PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
-
- return IdxForType(T).asTypeID(FastQuals);
-}
-
unsigned ComputeHash(Selector Sel);
/// Retrieve the "definitive" declaration that provides all of the
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
index 490b8cb10a48..3cb96df12e4d 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
@@ -31,7 +31,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ODRDiagsEmitter.h"
-#include "clang/AST/ODRHash.h"
+#include "clang/AST/OpenACCClause.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateBase.h"
@@ -40,9 +40,11 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/ASTSourceDescriptor.h"
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticError.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/ExceptionSpecificationType.h"
@@ -53,6 +55,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PragmaKinds.h"
@@ -76,6 +79,8 @@
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaCUDA.h"
+#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/Weak.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTDeserializationListener.h"
@@ -827,36 +832,37 @@ bool SimpleASTReaderListener::ReadPreprocessorOptions(
OptionValidateNone);
}
-/// Check the header search options deserialized from the control block
-/// against the header search options in an existing preprocessor.
+/// Check that the specified and the existing module cache paths are equivalent.
///
/// \param Diags If non-null, produce diagnostics for any mismatches incurred.
-static bool checkHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- StringRef ExistingModuleCachePath,
- DiagnosticsEngine *Diags,
- const LangOptions &LangOpts,
- const PreprocessorOptions &PPOpts) {
- if (LangOpts.Modules) {
- if (SpecificModuleCachePath != ExistingModuleCachePath &&
- !PPOpts.AllowPCHWithDifferentModulesCachePath) {
- if (Diags)
- Diags->Report(diag::err_pch_modulecache_mismatch)
- << SpecificModuleCachePath << ExistingModuleCachePath;
- return true;
- }
- }
-
- return false;
+/// \returns true when the module cache paths differ.
+static bool checkModuleCachePath(llvm::vfs::FileSystem &VFS,
+ StringRef SpecificModuleCachePath,
+ StringRef ExistingModuleCachePath,
+ DiagnosticsEngine *Diags,
+ const LangOptions &LangOpts,
+ const PreprocessorOptions &PPOpts) {
+ if (!LangOpts.Modules || PPOpts.AllowPCHWithDifferentModulesCachePath ||
+ SpecificModuleCachePath == ExistingModuleCachePath)
+ return false;
+ auto EqualOrErr =
+ VFS.equivalent(SpecificModuleCachePath, ExistingModuleCachePath);
+ if (EqualOrErr && *EqualOrErr)
+ return false;
+ if (Diags)
+ Diags->Report(diag::err_pch_modulecache_mismatch)
+ << SpecificModuleCachePath << ExistingModuleCachePath;
+ return true;
}
bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef SpecificModuleCachePath,
bool Complain) {
- return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- PP.getHeaderSearchInfo().getModuleCachePath(),
- Complain ? &Reader.Diags : nullptr,
- PP.getLangOpts(), PP.getPreprocessorOpts());
+ return checkModuleCachePath(Reader.getFileManager().getVirtualFileSystem(),
+ SpecificModuleCachePath,
+ PP.getHeaderSearchInfo().getModuleCachePath(),
+ Complain ? &Reader.Diags : nullptr,
+ PP.getLangOpts(), PP.getPreprocessorOpts());
}
void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) {
@@ -902,6 +908,39 @@ unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
return serialization::ComputeHash(Sel);
}
+LocalDeclID LocalDeclID::get(ASTReader &Reader, ModuleFile &MF, DeclID Value) {
+ LocalDeclID ID(Value);
+#ifndef NDEBUG
+ if (!MF.ModuleOffsetMap.empty())
+ Reader.ReadModuleOffsetMap(MF);
+
+ unsigned ModuleFileIndex = ID.getModuleFileIndex();
+ unsigned LocalDeclID = ID.getLocalDeclIndex();
+
+ assert(ModuleFileIndex <= MF.TransitiveImports.size());
+
+ ModuleFile *OwningModuleFile =
+ ModuleFileIndex == 0 ? &MF : MF.TransitiveImports[ModuleFileIndex - 1];
+ assert(OwningModuleFile);
+
+ unsigned LocalNumDecls = OwningModuleFile->LocalNumDecls;
+
+ if (!ModuleFileIndex)
+ LocalNumDecls += NUM_PREDEF_DECL_IDS;
+
+ assert(LocalDeclID < LocalNumDecls);
+#endif
+ (void)Reader;
+ (void)MF;
+ return ID;
+}
+
+LocalDeclID LocalDeclID::get(ASTReader &Reader, ModuleFile &MF,
+ unsigned ModuleFileIndex, unsigned LocalDeclID) {
+ DeclID Value = (DeclID)ModuleFileIndex << 32 | (DeclID)LocalDeclID;
+ return LocalDeclID::get(Reader, MF, Value);
+}
+
std::pair<unsigned, unsigned>
ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
return readULEBKeyDataLength(d);
@@ -912,20 +951,19 @@ ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
using namespace llvm::support;
SelectorTable &SelTable = Reader.getContext().Selectors;
- unsigned N =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
- IdentifierInfo *FirstII = Reader.getLocalIdentifier(
- F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d));
+ unsigned N = endian::readNext<uint16_t, llvm::endianness::little>(d);
+ const IdentifierInfo *FirstII = Reader.getLocalIdentifier(
+ F, endian::readNext<IdentifierID, llvm::endianness::little>(d));
if (N == 0)
return SelTable.getNullarySelector(FirstII);
else if (N == 1)
return SelTable.getUnarySelector(FirstII);
- SmallVector<IdentifierInfo *, 16> Args;
+ SmallVector<const IdentifierInfo *, 16> Args;
Args.push_back(FirstII);
for (unsigned I = 1; I != N; ++I)
Args.push_back(Reader.getLocalIdentifier(
- F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)));
+ F, endian::readNext<IdentifierID, llvm::endianness::little>(d)));
return SelTable.getSelector(N, Args.data());
}
@@ -938,11 +976,11 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
data_type Result;
Result.ID = Reader.getGlobalSelectorID(
- F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d));
+ F, endian::readNext<uint32_t, llvm::endianness::little>(d));
unsigned FullInstanceBits =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
+ endian::readNext<uint16_t, llvm::endianness::little>(d);
unsigned FullFactoryBits =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
+ endian::readNext<uint16_t, llvm::endianness::little>(d);
Result.InstanceBits = FullInstanceBits & 0x3;
Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1;
Result.FactoryBits = FullFactoryBits & 0x3;
@@ -953,16 +991,18 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
// Load instance methods
for (unsigned I = 0; I != NumInstanceMethods; ++I) {
if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
- F,
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)))
+ F, LocalDeclID::get(
+ Reader, F,
+ endian::readNext<DeclID, llvm::endianness::little>(d))))
Result.Instance.push_back(Method);
}
// Load factory methods
for (unsigned I = 0; I != NumFactoryMethods; ++I) {
if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
- F,
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)))
+ F, LocalDeclID::get(
+ Reader, F,
+ endian::readNext<DeclID, llvm::endianness::little>(d))))
Result.Factory.push_back(Method);
}
@@ -985,11 +1025,14 @@ ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) {
}
/// Whether the given identifier is "interesting".
-static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II,
+static bool isInterestingIdentifier(ASTReader &Reader, const IdentifierInfo &II,
bool IsModule) {
+ bool IsInteresting =
+ II.getNotableIdentifierID() != tok::NotableIdentifierKind::not_notable ||
+ II.getBuiltinID() != Builtin::ID::NotBuiltin ||
+ II.getObjCKeywordID() != tok::ObjCKeywordKind::objc_not_keyword;
return II.hadMacroDefinition() || II.isPoisoned() ||
- (!IsModule && II.getObjCOrBuiltinID()) ||
- II.hasRevertedTokenIDToIdentifier() ||
+ (!IsModule && IsInteresting) || II.hasRevertedTokenIDToIdentifier() ||
(!(IsModule && Reader.getPreprocessor().getLangOpts().CPlusPlus) &&
II.getFETokenInfo());
}
@@ -1000,11 +1043,11 @@ static bool readBit(unsigned &Bits) {
return Value;
}
-IdentID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) {
+IdentifierID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) {
using namespace llvm::support;
- unsigned RawID =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
+ IdentifierID RawID =
+ endian::readNext<IdentifierID, llvm::endianness::little>(d);
return Reader.getGlobalIdentifierID(F, RawID >> 1);
}
@@ -1022,10 +1065,12 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
unsigned DataLen) {
using namespace llvm::support;
- unsigned RawID =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
+ IdentifierID RawID =
+ endian::readNext<IdentifierID, llvm::endianness::little>(d);
bool IsInteresting = RawID & 0x01;
+ DataLen -= sizeof(IdentifierID);
+
// Wipe out the "is interesting" bit.
RawID = RawID >> 1;
@@ -1038,7 +1083,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
markIdentifierFromAST(Reader, *II);
Reader.markIdentifierUpToDate(II);
- IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
+ IdentifierID ID = Reader.getGlobalIdentifierID(F, RawID);
if (!IsInteresting) {
// For uninteresting identifiers, there's nothing else to do. Just notify
// the reader that we've finished loading this identifier.
@@ -1047,9 +1092,8 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
}
unsigned ObjCOrBuiltinID =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
- unsigned Bits =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
+ endian::readNext<uint16_t, llvm::endianness::little>(d);
+ unsigned Bits = endian::readNext<uint16_t, llvm::endianness::little>(d);
bool CPlusPlusOperatorKeyword = readBit(Bits);
bool HasRevertedTokenIDToIdentifier = readBit(Bits);
bool Poisoned = readBit(Bits);
@@ -1057,7 +1101,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
bool HadMacroDefinition = readBit(Bits);
assert(Bits == 0 && "Extra bits in the identifier?");
- DataLen -= 8;
+ DataLen -= sizeof(uint16_t) * 2;
// Set or check the various bits in the IdentifierInfo structure.
// Token IDs are read-only.
@@ -1078,7 +1122,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
// definition.
if (HadMacroDefinition) {
uint32_t MacroDirectivesOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
+ endian::readNext<uint32_t, llvm::endianness::little>(d);
DataLen -= 4;
Reader.addPendingMacro(II, &F, MacroDirectivesOffset);
@@ -1089,11 +1133,12 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
// Read all of the declarations visible at global scope with this
// name.
if (DataLen > 0) {
- SmallVector<uint32_t, 4> DeclIDs;
- for (; DataLen > 0; DataLen -= 4)
+ SmallVector<GlobalDeclID, 4> DeclIDs;
+ for (; DataLen > 0; DataLen -= sizeof(DeclID))
DeclIDs.push_back(Reader.getGlobalDeclID(
- F,
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)));
+ F, LocalDeclID::get(
+ Reader, F,
+ endian::readNext<DeclID, llvm::endianness::little>(d))));
Reader.SetGloballyVisibleDecls(II, DeclIDs);
}
@@ -1155,7 +1200,7 @@ unsigned DeclarationNameKey::getHash() const {
break;
}
- return ID.ComputeHash();
+ return ID.computeStableHash();
}
ModuleFile *
@@ -1163,7 +1208,7 @@ ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) {
using namespace llvm::support;
uint32_t ModuleFileID =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
+ endian::readNext<uint32_t, llvm::endianness::little>(d);
return Reader.getLocalModuleFile(F, ModuleFileID);
}
@@ -1183,18 +1228,15 @@ ASTDeclContextNameLookupTrait::ReadKey(const unsigned char *d, unsigned) {
case DeclarationName::CXXLiteralOperatorName:
case DeclarationName::CXXDeductionGuideName:
Data = (uint64_t)Reader.getLocalIdentifier(
- F, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d));
+ F, endian::readNext<IdentifierID, llvm::endianness::little>(d));
break;
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- Data =
- (uint64_t)Reader
- .getLocalSelector(
- F,
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(
- d))
- .getAsOpaquePtr();
+ Data = (uint64_t)Reader
+ .getLocalSelector(
+ F, endian::readNext<uint32_t, llvm::endianness::little>(d))
+ .getAsOpaquePtr();
break;
case DeclarationName::CXXOperatorName:
Data = *d++; // OverloadedOperatorKind
@@ -1216,10 +1258,10 @@ void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type,
data_type_builder &Val) {
using namespace llvm::support;
- for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) {
- uint32_t LocalID =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
- Val.insert(Reader.getGlobalDeclID(F, LocalID));
+ for (unsigned NumDecls = DataLen / sizeof(DeclID); NumDecls; --NumDecls) {
+ LocalDeclID ID = LocalDeclID::get(
+ Reader, F, endian::readNext<DeclID, llvm::endianness::little>(d));
+ Val.insert(Reader.getGlobalDeclID(F, ID));
}
}
@@ -1265,9 +1307,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
if (!Lex.first) {
Lex = std::make_pair(
&M, llvm::ArrayRef(
- reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
- Blob.data()),
- Blob.size() / 4));
+ reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
+ Blob.size() / sizeof(DeclID)));
}
DC->setHasExternalLexicalStorage(true);
return false;
@@ -1276,7 +1317,7 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
BitstreamCursor &Cursor,
uint64_t Offset,
- DeclID ID) {
+ GlobalDeclID ID) {
assert(Offset != 0);
SavedStreamPosition SavedPosition(Cursor);
@@ -1651,15 +1692,14 @@ bool ASTReader::ReadSLocEntry(int ID) {
FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
FileID FID = SourceMgr.createFileID(*File, IncludeLoc, FileCharacter, ID,
BaseOffset + Record[0]);
- SrcMgr::FileInfo &FileInfo =
- const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());
+ SrcMgr::FileInfo &FileInfo = SourceMgr.getSLocEntry(FID).getFile();
FileInfo.NumCreatedFIDs = Record[5];
if (Record[3])
FileInfo.setHasLineDirectives();
unsigned NumFileDecls = Record[7];
if (NumFileDecls && ContextObj) {
- const DeclID *FirstDecl = F->FileSortedDecls + Record[6];
+ const unaligned_decl_id_t *FirstDecl = F->FileSortedDecls + Record[6];
assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");
FileDeclIDs[FID] =
FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls));
@@ -1695,8 +1735,7 @@ bool ASTReader::ReadSLocEntry(int ID) {
FileID FID = SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID,
BaseOffset + Offset, IncludeLoc);
if (Record[3]) {
- auto &FileInfo =
- const_cast<SrcMgr::FileInfo &>(SourceMgr.getSLocEntry(FID).getFile());
+ auto &FileInfo = SourceMgr.getSLocEntry(FID).getFile();
FileInfo.setHasLineDirectives();
}
break;
@@ -1993,7 +2032,10 @@ const FileEntry *HeaderFileInfoTrait::getFile(const internal_key_type &Key) {
}
unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) {
- return llvm::hash_combine(ikey.Size, ikey.ModTime);
+ uint8_t buf[sizeof(ikey.Size) + sizeof(ikey.ModTime)];
+ memcpy(buf, &ikey.Size, sizeof(ikey.Size));
+ memcpy(buf + sizeof(ikey.Size), &ikey.ModTime, sizeof(ikey.ModTime));
+ return llvm::xxh3_64bits(buf);
}
HeaderFileInfoTrait::internal_key_type
@@ -2027,10 +2069,9 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {
using namespace llvm::support;
internal_key_type ikey;
- ikey.Size =
- off_t(endian::readNext<uint64_t, llvm::endianness::little, unaligned>(d));
- ikey.ModTime = time_t(
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(d));
+ ikey.Size = off_t(endian::readNext<uint64_t, llvm::endianness::little>(d));
+ ikey.ModTime =
+ time_t(endian::readNext<uint64_t, llvm::endianness::little>(d));
ikey.Filename = (const char *)d;
ikey.Imported = true;
return ikey;
@@ -2057,10 +2098,10 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
HFI.isPragmaOnce |= (Flags >> 4) & 0x01;
HFI.DirInfo = (Flags >> 1) & 0x07;
HFI.IndexHeaderMapHeader = Flags & 0x01;
- HFI.ControllingMacroID = Reader.getGlobalIdentifierID(
- M, endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d));
+ HFI.LazyControllingMacro = Reader.getGlobalIdentifierID(
+ M, endian::readNext<IdentifierID, llvm::endianness::little>(d));
if (unsigned FrameworkOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d)) {
+ endian::readNext<uint32_t, llvm::endianness::little>(d)) {
// The framework offset is 1 greater than the actual offset,
// since 0 is used as an indicator for "no framework name".
StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
@@ -2071,7 +2112,7 @@ 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, llvm::endianness::little, unaligned>(d);
+ endian::readNext<uint32_t, llvm::endianness::little>(d);
auto HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>(LocalSMID & 7);
LocalSMID >>= 3;
@@ -2091,7 +2132,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
Module::Header H = {std::string(key.Filename), "", *FE};
ModMap.addHeader(Mod, H, HeaderRole, /*Imported=*/true);
}
- HFI.isModuleHeader |= ModuleMap::isModular(HeaderRole);
+ HFI.mergeModuleMembership(HeaderRole);
}
// This HeaderFileInfo was externally loaded.
@@ -2224,7 +2265,7 @@ namespace {
} // namespace
-void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
+void ASTReader::updateOutOfDateIdentifier(const IdentifierInfo &II) {
// Note that we are loading an identifier.
Deserializing AnIdentifier(this);
@@ -2249,11 +2290,11 @@ void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
markIdentifierUpToDate(&II);
}
-void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
+void ASTReader::markIdentifierUpToDate(const IdentifierInfo *II) {
if (!II)
return;
- II->setOutOfDate(false);
+ const_cast<IdentifierInfo *>(II)->setOutOfDate(false);
// Update the generation for this identifier.
if (getContext().getLangOpts().Modules)
@@ -2587,7 +2628,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
"We should only check the content of the inputs with "
"ValidateASTInputFilesContent enabled.");
- if (StoredContentHash == static_cast<uint64_t>(llvm::hash_code(-1)))
+ if (StoredContentHash == 0)
return OriginalChange;
auto MemBuffOrError = FileMgr.getBufferForFile(*File);
@@ -2601,8 +2642,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
return OriginalChange;
}
- // FIXME: hash_value is not guaranteed to be stable!
- auto ContentHash = hash_value(MemBuffOrError.get()->getBuffer());
+ auto ContentHash = xxh3_64bits(MemBuffOrError.get()->getBuffer());
if (StoredContentHash == static_cast<uint64_t>(ContentHash))
return Change{Change::None};
@@ -2635,6 +2675,14 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
F.StandardCXXModule && FileChange.Kind == Change::None)
FileChange = HasInputContentChanged(FileChange);
+ // When we have StoredTime equal to zero and ValidateASTInputFilesContent,
+ // it is better to check the content of the input files because we cannot rely
+ // on the file modification time, which will be the same (zero) for these
+ // files.
+ if (!StoredTime && ValidateASTInputFilesContent &&
+ FileChange.Kind == Change::None)
+ FileChange = HasInputContentChanged(FileChange);
+
// For an overridden file, there is nothing to validate.
if (!Overridden && FileChange.Kind != Change::None) {
if (Complain && !Diags.isDiagnosticInFlight()) {
@@ -3035,8 +3083,10 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// The import location will be the local one for now; we will adjust
// all import locations of module imports after the global source
// location info are setup, in ReadAST.
- SourceLocation ImportLoc =
+ auto [ImportLoc, ImportModuleFileIndex] =
ReadUntranslatedSourceLocation(Record[Idx++]);
+ // The import location must belong to the current module file itself.
+ assert(ImportModuleFileIndex == 0);
off_t StoredSize = !IsImportingStdCXXModule ? (off_t)Record[Idx++] : 0;
time_t StoredModTime =
!IsImportingStdCXXModule ? (time_t)Record[Idx++] : 0;
@@ -3344,22 +3394,13 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"duplicate TYPE_OFFSET record in AST file");
- F.TypeOffsets = reinterpret_cast<const UnderalignedInt64 *>(Blob.data());
+ F.TypeOffsets = reinterpret_cast<const UnalignedUInt64 *>(Blob.data());
F.LocalNumTypes = Record[0];
- unsigned LocalBaseTypeIndex = Record[1];
F.BaseTypeIndex = getTotalNumTypes();
- if (F.LocalNumTypes > 0) {
- // Introduce the global -> local mapping for types within this module.
- GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));
-
- // Introduce the local -> global mapping for types within this module.
- F.TypeRemap.insertOrReplace(
- std::make_pair(LocalBaseTypeIndex,
- F.BaseTypeIndex - LocalBaseTypeIndex));
-
+ if (F.LocalNumTypes > 0)
TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);
- }
+
break;
}
@@ -3370,35 +3411,19 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
"duplicate DECL_OFFSET record in AST file");
F.DeclOffsets = (const DeclOffset *)Blob.data();
F.LocalNumDecls = Record[0];
- unsigned LocalBaseDeclID = Record[1];
- F.BaseDeclID = getTotalNumDecls();
-
- if (F.LocalNumDecls > 0) {
- // Introduce the global -> local mapping for declarations within this
- // module.
- GlobalDeclMap.insert(
- std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));
-
- // Introduce the local -> global mapping for declarations within this
- // module.
- F.DeclRemap.insertOrReplace(
- std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID));
-
- // Introduce the global -> local mapping for declarations within this
- // module.
- F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID;
+ F.BaseDeclIndex = getTotalNumDecls();
+ if (F.LocalNumDecls > 0)
DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);
- }
+
break;
}
case TU_UPDATE_LEXICAL: {
DeclContext *TU = ContextObj->getTranslationUnitDecl();
LexicalContents Contents(
- reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
- Blob.data()),
- static_cast<unsigned int>(Blob.size() / 4));
+ reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
+ static_cast<unsigned int>(Blob.size() / sizeof(DeclID)));
TULexicalDecls.push_back(std::make_pair(&F, Contents));
TU->setHasExternalLexicalStorage(true);
break;
@@ -3406,7 +3431,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
case UPDATE_VISIBLE: {
unsigned Idx = 0;
- serialization::DeclID ID = ReadDeclID(F, Record, Idx);
+ GlobalDeclID ID = ReadDeclID(F, Record, Idx);
auto *Data = (const unsigned char*)Blob.data();
PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data});
// If we've already loaded the decl, perform the updates when we finish
@@ -3438,24 +3463,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
"duplicate IDENTIFIER_OFFSET record in AST file");
F.IdentifierOffsets = (const uint32_t *)Blob.data();
F.LocalNumIdentifiers = Record[0];
- unsigned LocalBaseIdentifierID = Record[1];
F.BaseIdentifierID = getTotalNumIdentifiers();
- if (F.LocalNumIdentifiers > 0) {
- // Introduce the global -> local mapping for identifiers within this
- // module.
- GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1,
- &F));
-
- // Introduce the local -> global mapping for identifiers within this
- // module.
- F.IdentifierRemap.insertOrReplace(
- std::make_pair(LocalBaseIdentifierID,
- F.BaseIdentifierID - LocalBaseIdentifierID));
-
+ if (F.LocalNumIdentifiers > 0)
IdentifiersLoaded.resize(IdentifiersLoaded.size()
+ F.LocalNumIdentifiers);
- }
break;
}
@@ -3466,8 +3478,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
case EAGERLY_DESERIALIZED_DECLS:
// FIXME: Skip reading this record if our ASTConsumer doesn't care
// about "interesting" decls (for instance, if we're building a module).
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ EagerlyDeserializedDecls.push_back(ReadDeclID(F, Record, I));
break;
case MODULAR_CODEGEN_DECLS:
@@ -3475,8 +3487,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
// them (ie: if we're not codegenerating this module).
if (F.Kind == MK_MainFile ||
getContext().getLangOpts().BuildingPCHWithObjectFile)
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ EagerlyDeserializedDecls.push_back(ReadDeclID(F, Record, I));
break;
case SPECIAL_TYPES:
@@ -3507,13 +3519,13 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
case UNUSED_FILESCOPED_DECLS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ UnusedFileScopedDecls.push_back(ReadDeclID(F, Record, I));
break;
case DELEGATING_CTORS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ DelegatingCtorDecls.push_back(ReadDeclID(F, Record, I));
break;
case WEAK_UNDECLARED_IDENTIFIERS:
@@ -3588,6 +3600,17 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
}
+ case PP_UNSAFE_BUFFER_USAGE: {
+ if (!Record.empty()) {
+ SmallVector<SourceLocation, 64> SrcLocs;
+ unsigned Idx = 0;
+ while (Idx < Record.size())
+ SrcLocs.push_back(ReadSourceLocation(F, Record, Idx));
+ PP.setDeserializedSafeBufferOptOutMap(SrcLocs);
+ }
+ break;
+ }
+
case PP_CONDITIONAL_STACK:
if (!Record.empty()) {
unsigned Idx = 0, End = Record.size() - 1;
@@ -3621,7 +3644,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
case FILE_SORTED_DECLS:
- F.FileSortedDecls = (const DeclID *)Blob.data();
+ F.FileSortedDecls = (const unaligned_decl_id_t *)Blob.data();
F.NumFileSortedDecls = Record[0];
break;
@@ -3655,13 +3678,6 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset
- SLocSpaceSize,&F));
- // Initialize the remapping table.
- // Invalid stays invalid.
- F.SLocRemap.insertOrReplace(std::make_pair(0U, 0));
- // This module. Base was 2 when being compiled.
- F.SLocRemap.insertOrReplace(std::make_pair(
- 2U, static_cast<SourceLocation::IntTy>(F.SLocEntryBaseOffset - 2)));
-
TotalNumSLocEntries += F.LocalNumSLocEntries;
break;
}
@@ -3675,8 +3691,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
case EXT_VECTOR_DECLS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ ExtVectorDecls.push_back(ReadDeclID(F, Record, I));
break;
case VTABLE_USES:
@@ -3690,18 +3706,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
VTableUses.clear();
for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
- VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));
VTableUses.push_back(
- ReadSourceLocation(F, Record, Idx).getRawEncoding());
- VTableUses.push_back(Record[Idx++]);
+ {ReadDeclID(F, Record, Idx),
+ ReadSourceLocation(F, Record, Idx).getRawEncoding(),
+ (bool)Record[Idx++]});
}
break;
case PENDING_IMPLICIT_INSTANTIATIONS:
- if (PendingInstantiations.size() % 2 != 0)
- return llvm::createStringError(
- std::errc::illegal_byte_sequence,
- "Invalid existing PendingInstantiations");
if (Record.size() % 2 != 0)
return llvm::createStringError(
@@ -3709,9 +3721,9 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
- PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));
PendingInstantiations.push_back(
- ReadSourceLocation(F, Record, I).getRawEncoding());
+ {ReadDeclID(F, Record, I),
+ ReadSourceLocation(F, Record, I).getRawEncoding()});
}
break;
@@ -3719,8 +3731,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
if (Record.size() != 3)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"Invalid SEMA_DECL_REFS block");
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ SemaDeclRefs.push_back(ReadDeclID(F, Record, I));
break;
case PPD_ENTITIES_OFFSETS: {
@@ -3778,9 +3790,9 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"invalid DECL_UPDATE_OFFSETS block in AST file");
- for (unsigned I = 0, N = Record.size(); I != N; I += 2) {
- GlobalDeclID ID = getGlobalDeclID(F, Record[I]);
- DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) {
+ GlobalDeclID ID = ReadDeclID(F, Record, I);
+ DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I++]));
// If we've already loaded the decl, perform the updates when we finish
// loading this block.
@@ -3790,6 +3802,33 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
}
break;
+ case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
+ if (Record.size() % 3 != 0)
+ return llvm::createStringError(
+ std::errc::illegal_byte_sequence,
+ "invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
+ "file");
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) {
+ GlobalDeclID ID = ReadDeclID(F, Record, I);
+
+ uint64_t BaseOffset = F.DeclsBlockStartOffset;
+ assert(BaseOffset && "Invalid DeclsBlockStartOffset for module file!");
+ uint64_t LocalLexicalOffset = Record[I++];
+ uint64_t LexicalOffset =
+ LocalLexicalOffset ? BaseOffset + LocalLexicalOffset : 0;
+ uint64_t LocalVisibleOffset = Record[I++];
+ uint64_t VisibleOffset =
+ LocalVisibleOffset ? BaseOffset + LocalVisibleOffset : 0;
+
+ DelayedNamespaceOffsetMap[ID] = {LexicalOffset, VisibleOffset};
+
+ assert(!GetExistingDecl(ID) &&
+ "We shouldn't load the namespace in the front of delayed "
+ "namespace lexical and visible block");
+ }
+ break;
+ }
+
case OBJC_CATEGORIES_MAP:
if (F.LocalNumObjCCategoriesInMap != 0)
return llvm::createStringError(
@@ -3808,8 +3847,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
// Later tables overwrite earlier ones.
// FIXME: Modules will have trouble with this.
CUDASpecialDeclRefs.clear();
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ CUDASpecialDeclRefs.push_back(ReadDeclID(F, Record, I));
break;
case HEADER_SEARCH_TABLE:
@@ -3849,33 +3888,29 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
case TENTATIVE_DEFINITIONS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ TentativeDefinitions.push_back(ReadDeclID(F, Record, I));
break;
case KNOWN_NAMESPACES:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ KnownNamespaces.push_back(ReadDeclID(F, Record, I));
break;
case UNDEFINED_BUT_USED:
- if (UndefinedButUsed.size() % 2 != 0)
- return llvm::createStringError(std::errc::illegal_byte_sequence,
- "Invalid existing UndefinedButUsed");
-
if (Record.size() % 2 != 0)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"invalid undefined-but-used record");
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
- UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++]));
UndefinedButUsed.push_back(
- ReadSourceLocation(F, Record, I).getRawEncoding());
+ {ReadDeclID(F, Record, I),
+ ReadSourceLocation(F, Record, I).getRawEncoding()});
}
break;
case DELETE_EXPRS_TO_ANALYZE:
for (unsigned I = 0, N = Record.size(); I != N;) {
- DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++]));
+ DelayedDeleteExprs.push_back(ReadDeclID(F, Record, I).getRawValue());
const uint64_t Count = Record[I++];
DelayedDeleteExprs.push_back(Count);
for (uint64_t C = 0; C < Count; ++C) {
@@ -3958,16 +3993,15 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;
case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- UnusedLocalTypedefNameCandidates.push_back(
- getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ UnusedLocalTypedefNameCandidates.push_back(ReadDeclID(F, Record, I));
break;
case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH:
if (Record.size() != 1)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"invalid cuda pragma options record");
- ForceCUDAHostDeviceDepth = Record[0];
+ ForceHostDeviceDepth = Record[0];
break;
case ALIGN_PACK_PRAGMA_OPTIONS: {
@@ -4015,8 +4049,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
}
case DECLS_TO_CHECK_FOR_DEFERRED_DIAGS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- DeclsToCheckForDeferredDiags.insert(getGlobalDeclID(F, Record[I]));
+ for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
+ DeclsToCheckForDeferredDiags.insert(ReadDeclID(F, Record, I));
break;
}
}
@@ -4030,25 +4064,14 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
const unsigned char *DataEnd = Data + F.ModuleOffsetMap.size();
F.ModuleOffsetMap = StringRef();
- // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders.
- if (F.SLocRemap.find(0) == F.SLocRemap.end()) {
- F.SLocRemap.insert(std::make_pair(0U, 0));
- F.SLocRemap.insert(std::make_pair(2U, 1));
- }
-
- // Continuous range maps we may be updating in our module.
- using SLocRemapBuilder =
- ContinuousRangeMap<SourceLocation::UIntTy, SourceLocation::IntTy,
- 2>::Builder;
using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder;
- SLocRemapBuilder SLocRemap(F.SLocRemap);
- RemapBuilder IdentifierRemap(F.IdentifierRemap);
RemapBuilder MacroRemap(F.MacroRemap);
RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap);
RemapBuilder SubmoduleRemap(F.SubmoduleRemap);
RemapBuilder SelectorRemap(F.SelectorRemap);
- RemapBuilder DeclRemap(F.DeclRemap);
- RemapBuilder TypeRemap(F.TypeRemap);
+
+ auto &ImportedModuleVector = F.TransitiveImports;
+ assert(ImportedModuleVector.empty());
while (Data < DataEnd) {
// FIXME: Looking up dependency modules by filename is horrible. Let's
@@ -4056,9 +4079,8 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
// how it goes...
using namespace llvm::support;
ModuleKind Kind = static_cast<ModuleKind>(
- endian::readNext<uint8_t, llvm::endianness::little, unaligned>(Data));
- uint16_t Len =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(Data);
+ endian::readNext<uint8_t, llvm::endianness::little>(Data));
+ uint16_t Len = endian::readNext<uint16_t, llvm::endianness::little>(Data);
StringRef Name = StringRef((const char*)Data, Len);
Data += Len;
ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule ||
@@ -4066,29 +4088,22 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
? ModuleMgr.lookupByModuleName(Name)
: ModuleMgr.lookupByFileName(Name));
if (!OM) {
- std::string Msg =
- "SourceLocation remap refers to unknown module, cannot find ";
+ std::string Msg = "refers to unknown module, cannot find ";
Msg.append(std::string(Name));
Error(Msg);
return;
}
- SourceLocation::UIntTy SLocOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
- uint32_t IdentifierIDOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
+ ImportedModuleVector.push_back(OM);
+
uint32_t MacroIDOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
+ endian::readNext<uint32_t, llvm::endianness::little>(Data);
uint32_t PreprocessedEntityIDOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
+ endian::readNext<uint32_t, llvm::endianness::little>(Data);
uint32_t SubmoduleIDOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
+ endian::readNext<uint32_t, llvm::endianness::little>(Data);
uint32_t SelectorIDOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
- uint32_t DeclIDOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
- uint32_t TypeIndexOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Data);
+ endian::readNext<uint32_t, llvm::endianness::little>(Data);
auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset,
RemapBuilder &Remap) {
@@ -4098,24 +4113,11 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
static_cast<int>(BaseOffset - Offset)));
};
- constexpr SourceLocation::UIntTy SLocNone =
- std::numeric_limits<SourceLocation::UIntTy>::max();
- if (SLocOffset != SLocNone)
- SLocRemap.insert(std::make_pair(
- SLocOffset, static_cast<SourceLocation::IntTy>(
- OM->SLocEntryBaseOffset - SLocOffset)));
-
- mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap);
mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap);
mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID,
PreprocessedEntityRemap);
mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap);
mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap);
- mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap);
- mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap);
-
- // Global -> local mappings.
- F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;
}
}
@@ -4229,9 +4231,9 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
/// Move the given method to the back of the global list of methods.
static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {
// Find the entry for this selector in the method pool.
- Sema::GlobalMethodPool::iterator Known
- = S.MethodPool.find(Method->getSelector());
- if (Known == S.MethodPool.end())
+ SemaObjC::GlobalMethodPool::iterator Known =
+ S.ObjC().MethodPool.find(Method->getSelector());
+ if (Known == S.ObjC().MethodPool.end())
return;
// Retrieve the appropriate method list.
@@ -4641,8 +4643,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type,
if (ContextObj) {
for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) {
loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(),
- ObjCClassesLoaded[I],
- PreviousGeneration);
+ ObjCClassesLoaded[I], PreviousGeneration);
}
}
@@ -4977,7 +4978,7 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
}
case HEADER_SEARCH_PATHS: {
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
- if (!AllowCompatibleConfigurationMismatch &&
+ if (Listener && !AllowCompatibleConfigurationMismatch &&
ParseHeaderSearchPaths(Record, Complain, *Listener))
Result = ConfigurationMismatch;
break;
@@ -4992,15 +4993,12 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
Record.begin(), Record.end());
break;
case HEADER_SEARCH_ENTRY_USAGE:
- if (!F)
- break;
- unsigned Count = Record[0];
- const char *Byte = Blob.data();
- F->SearchPathUsage = llvm::BitVector(Count, false);
- for (unsigned I = 0; I < Count; ++Byte)
- for (unsigned Bit = 0; Bit < 8 && I < Count; ++Bit, ++I)
- if (*Byte & (1 << Bit))
- F->SearchPathUsage[I] = true;
+ if (F)
+ F->SearchPathUsage = ReadBitVector(Record, Blob);
+ break;
+ case VFS_USAGE:
+ if (F)
+ F->VFSUsage = ReadBitVector(Record, Blob);
break;
}
}
@@ -5089,20 +5087,21 @@ void ASTReader::InitializeContext() {
// If there's a listener, notify them that we "read" the translation unit.
if (DeserializationListener)
- DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID,
- Context.getTranslationUnitDecl());
+ DeserializationListener->DeclRead(
+ GlobalDeclID(PREDEF_DECL_TRANSLATION_UNIT_ID),
+ Context.getTranslationUnitDecl());
// FIXME: Find a better way to deal with collisions between these
// built-in types. Right now, we just ignore the problem.
// Load the special types.
if (SpecialTypes.size() >= NumSpecialTypeIDs) {
- if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
+ if (TypeID String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
if (!Context.CFConstantStringTypeDecl)
Context.setCFConstantStringType(GetType(String));
}
- if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
+ if (TypeID File = SpecialTypes[SPECIAL_TYPE_FILE]) {
QualType FileType = GetType(File);
if (FileType.isNull()) {
Error("FILE type is NULL");
@@ -5123,7 +5122,7 @@ void ASTReader::InitializeContext() {
}
}
- if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {
+ if (TypeID Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {
QualType Jmp_bufType = GetType(Jmp_buf);
if (Jmp_bufType.isNull()) {
Error("jmp_buf type is NULL");
@@ -5144,7 +5143,7 @@ void ASTReader::InitializeContext() {
}
}
- if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {
+ if (TypeID Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {
QualType Sigjmp_bufType = GetType(Sigjmp_buf);
if (Sigjmp_bufType.isNull()) {
Error("sigjmp_buf type is NULL");
@@ -5162,25 +5161,24 @@ void ASTReader::InitializeContext() {
}
}
- if (unsigned ObjCIdRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {
+ if (TypeID ObjCIdRedef = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {
if (Context.ObjCIdRedefinitionType.isNull())
Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef);
}
- if (unsigned ObjCClassRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {
+ if (TypeID ObjCClassRedef =
+ SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {
if (Context.ObjCClassRedefinitionType.isNull())
Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef);
}
- if (unsigned ObjCSelRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {
+ if (TypeID ObjCSelRedef =
+ SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {
if (Context.ObjCSelRedefinitionType.isNull())
Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef);
}
- if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) {
+ if (TypeID Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) {
QualType Ucontext_tType = GetType(Ucontext_t);
if (Ucontext_tType.isNull()) {
Error("ucontext_t type is NULL");
@@ -5376,9 +5374,9 @@ namespace {
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef SpecificModuleCachePath,
bool Complain) override {
- return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- ExistingModuleCachePath, nullptr,
- ExistingLangOpts, ExistingPPOpts);
+ return checkModuleCachePath(
+ FileMgr.getVirtualFileSystem(), SpecificModuleCachePath,
+ ExistingModuleCachePath, nullptr, ExistingLangOpts, ExistingPPOpts);
}
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
@@ -5398,7 +5396,8 @@ bool ASTReader::readASTFileControlBlock(
StringRef Filename, FileManager &FileMgr,
const InMemoryModuleCache &ModuleCache,
const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions,
- ASTReaderListener &Listener, bool ValidateDiagnosticOptions) {
+ ASTReaderListener &Listener, bool ValidateDiagnosticOptions,
+ unsigned ClientLoadCapabilities) {
// Open the AST file.
std::unique_ptr<llvm::MemoryBuffer> OwnedBuffer;
llvm::MemoryBuffer *Buffer = ModuleCache.lookupPCM(Filename);
@@ -5453,7 +5452,7 @@ bool ASTReader::readASTFileControlBlock(
switch (Entry.ID) {
case OPTIONS_BLOCK_ID: {
std::string IgnoredSuggestedPredefines;
- if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate,
+ if (ReadOptionsBlock(Stream, ClientLoadCapabilities,
/*AllowCompatibleConfigurationMismatch*/ false,
Listener, IgnoredSuggestedPredefines) != Success)
return true;
@@ -5679,7 +5678,7 @@ bool ASTReader::readASTFileControlBlock(
// Scan for the UNHASHED_CONTROL_BLOCK_ID block.
if (readUnhashedControlBlockImpl(
- nullptr, Bytes, ARR_ConfigurationMismatch | ARR_OutOfDate,
+ nullptr, Bytes, ClientLoadCapabilities,
/*AllowCompatibleConfigurationMismatch*/ false, &Listener,
ValidateDiagnosticOptions) != Success)
return true;
@@ -5997,9 +5996,9 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
case SUBMODULE_INITIALIZERS: {
if (!ContextObj)
break;
- SmallVector<uint32_t, 16> Inits;
- for (auto &ID : Record)
- Inits.push_back(getGlobalDeclID(F, ID));
+ SmallVector<GlobalDeclID, 16> Inits;
+ for (unsigned I = 0; I < Record.size(); /*in loop*/)
+ Inits.push_back(ReadDeclID(F, Record, I));
ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
break;
}
@@ -6242,8 +6241,8 @@ SourceRange ASTReader::ReadSkippedRange(unsigned GlobalIndex) {
unsigned LocalIndex = GlobalIndex - M->BasePreprocessedSkippedRangeID;
assert(LocalIndex < M->NumPreprocessedSkippedRanges);
PPSkippedRange RawRange = M->PreprocessedSkippedRangeOffsets[LocalIndex];
- SourceRange Range(TranslateSourceLocation(*M, RawRange.getBegin()),
- TranslateSourceLocation(*M, RawRange.getEnd()));
+ SourceRange Range(ReadSourceLocation(*M, RawRange.getBegin()),
+ ReadSourceLocation(*M, RawRange.getEnd()));
assert(Range.isValid());
return Range;
}
@@ -6262,7 +6261,7 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
if (llvm::Error Err = M.PreprocessorDetailCursor.JumpToBit(
- M.MacroOffsetsBase + PPOffs.BitOffset)) {
+ M.MacroOffsetsBase + PPOffs.getOffset())) {
Error(std::move(Err));
return nullptr;
}
@@ -6279,8 +6278,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
return nullptr;
// Read the record.
- SourceRange Range(TranslateSourceLocation(M, PPOffs.getBegin()),
- TranslateSourceLocation(M, PPOffs.getEnd()));
+ SourceRange Range(ReadSourceLocation(M, PPOffs.getBegin()),
+ ReadSourceLocation(M, PPOffs.getEnd()));
PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
StringRef Blob;
RecordData Record;
@@ -6392,7 +6391,7 @@ struct PPEntityComp {
}
SourceLocation getLoc(const PPEntityOffset &PPE) const {
- return Reader.TranslateSourceLocation(M, PPE.getBegin());
+ return Reader.ReadSourceLocation(M, PPE.getBegin());
}
};
@@ -6436,7 +6435,7 @@ PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
PPI = First;
std::advance(PPI, Half);
if (SourceMgr.isBeforeInTranslationUnit(
- TranslateSourceLocation(M, PPI->getEnd()), Loc)) {
+ ReadSourceLocation(M, PPI->getEnd()), Loc)) {
First = PPI;
++First;
Count = Count - Half - 1;
@@ -6477,7 +6476,7 @@ std::optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,
unsigned LocalIndex = PPInfo.second;
const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
- SourceLocation Loc = TranslateSourceLocation(M, PPOffs.getBegin());
+ SourceLocation Loc = ReadSourceLocation(M, PPOffs.getBegin());
if (Loc.isInvalid())
return false;
@@ -6621,17 +6620,15 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
while (NumLocations--) {
assert(Idx < Record.size() &&
"Invalid data, missing pragma diagnostic states");
- SourceLocation Loc = ReadSourceLocation(F, Record[Idx++]);
- auto IDAndOffset = SourceMgr.getDecomposedLoc(Loc);
- assert(IDAndOffset.first.isValid() && "invalid FileID for transition");
- assert(IDAndOffset.second == 0 && "not a start location for a FileID");
+ FileID FID = ReadFileID(F, Record, Idx);
+ assert(FID.isValid() && "invalid FileID for transition");
unsigned Transitions = Record[Idx++];
// Note that we don't need to set up Parent/ParentOffset here, because
// we won't be changing the diagnostic state within imported FileIDs
// (other than perhaps appending to the main source file, which has no
// parent).
- auto &F = Diag.DiagStatesByLoc.Files[IDAndOffset.first];
+ auto &F = Diag.DiagStatesByLoc.Files[FID];
F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
for (unsigned I = 0; I != Transitions; ++I) {
unsigned Offset = Record[Idx++];
@@ -6666,13 +6663,10 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
}
/// Get the correct cursor and offset for loading a type.
-ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
- GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index);
- assert(I != GlobalTypeMap.end() && "Corrupted global type map");
- ModuleFile *M = I->second;
- return RecordLocation(
- M, M->TypeOffsets[Index - M->BaseTypeIndex].getBitOffset() +
- M->DeclsBlockStartOffset);
+ASTReader::RecordLocation ASTReader::TypeCursorForIndex(TypeID ID) {
+ auto [M, Index] = translateTypeIDToIndex(ID);
+ return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex].get() +
+ M->DeclsBlockStartOffset);
}
static std::optional<Type::TypeClass> getTypeClassForCode(TypeCode code) {
@@ -6691,10 +6685,10 @@ static std::optional<Type::TypeClass> getTypeClassForCode(TypeCode code) {
/// routine actually reads the record corresponding to the type at the given
/// location. It is a helper routine for GetType, which deals with reading type
/// IDs.
-QualType ASTReader::readTypeRecord(unsigned Index) {
+QualType ASTReader::readTypeRecord(TypeID ID) {
assert(ContextObj && "reading type with no AST context");
ASTContext &Context = *ContextObj;
- RecordLocation Loc = TypeCursorForIndex(Index);
+ RecordLocation Loc = TypeCursorForIndex(ID);
BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
// Keep track of where we are in the stream, then jump back there
@@ -6809,6 +6803,10 @@ void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
// nothing to do
}
+void TypeLocReader::VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) {
+ // nothing to do
+}
+
void TypeLocReader::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
TL.setExpansionLoc(readSourceLocation());
}
@@ -6946,6 +6944,10 @@ void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
TL.setRParenLoc(readSourceLocation());
}
+void TypeLocReader::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
+ TL.setEllipsisLoc(readSourceLocation());
+}
+
void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
TL.setKWLoc(readSourceLocation());
TL.setLParenLoc(readSourceLocation());
@@ -6990,6 +6992,10 @@ void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
TL.setAttr(ReadAttr());
}
+void TypeLocReader::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) {
+ // Nothing to do
+}
+
void TypeLocReader::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
// Nothing to do.
}
@@ -7123,15 +7129,44 @@ TypeSourceInfo *ASTRecordReader::readTypeSourceInfo() {
return TInfo;
}
+static unsigned getIndexForTypeID(serialization::TypeID ID) {
+ return (ID & llvm::maskTrailingOnes<TypeID>(32)) >> Qualifiers::FastWidth;
+}
+
+static unsigned getModuleFileIndexForTypeID(serialization::TypeID ID) {
+ return ID >> 32;
+}
+
+static bool isPredefinedType(serialization::TypeID ID) {
+ // We don't need to erase the higher bits since if these bits are not 0,
+ // it must be larger than NUM_PREDEF_TYPE_IDS.
+ return (ID >> Qualifiers::FastWidth) < NUM_PREDEF_TYPE_IDS;
+}
+
+std::pair<ModuleFile *, unsigned>
+ASTReader::translateTypeIDToIndex(serialization::TypeID ID) const {
+ assert(!isPredefinedType(ID) &&
+ "Predefined type shouldn't be in TypesLoaded");
+ unsigned ModuleFileIndex = getModuleFileIndexForTypeID(ID);
+ assert(ModuleFileIndex && "Untranslated Local Decl?");
+
+ ModuleFile *OwningModuleFile = &getModuleManager()[ModuleFileIndex - 1];
+ assert(OwningModuleFile &&
+ "untranslated type ID or local type ID shouldn't be in TypesLoaded");
+
+ return {OwningModuleFile,
+ OwningModuleFile->BaseTypeIndex + getIndexForTypeID(ID)};
+}
+
QualType ASTReader::GetType(TypeID ID) {
assert(ContextObj && "reading type with no AST context");
ASTContext &Context = *ContextObj;
unsigned FastQuals = ID & Qualifiers::FastMask;
- unsigned Index = ID >> Qualifiers::FastWidth;
- if (Index < NUM_PREDEF_TYPE_IDS) {
+ if (isPredefinedType(ID)) {
QualType T;
+ unsigned Index = getIndexForTypeID(ID);
switch ((PredefinedTypeIDs)Index) {
case PREDEF_TYPE_LAST_ID:
// We should never use this one.
@@ -7288,6 +7323,9 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_OVERLOAD_ID:
T = Context.OverloadTy;
break;
+ case PREDEF_TYPE_UNRESOLVED_TEMPLATE:
+ T = Context.UnresolvedTemplateTy;
+ break;
case PREDEF_TYPE_BOUND_MEMBER:
T = Context.BoundMemberTy;
break;
@@ -7361,11 +7399,11 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_INCOMPLETE_MATRIX_IDX:
T = Context.IncompleteMatrixIdxTy;
break;
- case PREDEF_TYPE_OMP_ARRAY_SECTION:
- T = Context.OMPArraySectionTy;
+ case PREDEF_TYPE_ARRAY_SECTION:
+ T = Context.ArraySectionTy;
break;
case PREDEF_TYPE_OMP_ARRAY_SHAPING:
- T = Context.OMPArraySectionTy;
+ T = Context.OMPArrayShapingTy;
break;
case PREDEF_TYPE_OMP_ITERATOR:
T = Context.OMPIteratorTy;
@@ -7390,16 +7428,22 @@ QualType ASTReader::GetType(TypeID ID) {
T = Context.SingletonId; \
break;
#include "clang/Basic/WebAssemblyReferenceTypes.def"
+#define AMDGPU_TYPE(Name, Id, SingletonId) \
+ case PREDEF_TYPE_##Id##_ID: \
+ T = Context.SingletonId; \
+ break;
+#include "clang/Basic/AMDGPUTypes.def"
}
assert(!T.isNull() && "Unknown predefined type");
return T.withFastQualifiers(FastQuals);
}
- Index -= NUM_PREDEF_TYPE_IDS;
+ unsigned Index = translateTypeIDToIndex(ID).second;
+
assert(Index < TypesLoaded.size() && "Type index out-of-range");
if (TypesLoaded[Index].isNull()) {
- TypesLoaded[Index] = readTypeRecord(Index);
+ TypesLoaded[Index] = readTypeRecord(ID);
if (TypesLoaded[Index].isNull())
return QualType();
@@ -7412,27 +7456,28 @@ QualType ASTReader::GetType(TypeID ID) {
return TypesLoaded[Index].withFastQualifiers(FastQuals);
}
-QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) {
+QualType ASTReader::getLocalType(ModuleFile &F, LocalTypeID LocalID) {
return GetType(getGlobalTypeID(F, LocalID));
}
-serialization::TypeID
-ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const {
- unsigned FastQuals = LocalID & Qualifiers::FastMask;
- unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;
-
- if (LocalIndex < NUM_PREDEF_TYPE_IDS)
+serialization::TypeID ASTReader::getGlobalTypeID(ModuleFile &F,
+ LocalTypeID LocalID) const {
+ if (isPredefinedType(LocalID))
return LocalID;
if (!F.ModuleOffsetMap.empty())
ReadModuleOffsetMap(F);
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);
- assert(I != F.TypeRemap.end() && "Invalid index into type index remap");
+ unsigned ModuleFileIndex = getModuleFileIndexForTypeID(LocalID);
+ LocalID &= llvm::maskTrailingOnes<TypeID>(32);
- unsigned GlobalIndex = LocalIndex + I->second;
- return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;
+ if (ModuleFileIndex == 0)
+ LocalID -= NUM_PREDEF_TYPE_IDS << Qualifiers::FastWidth;
+
+ ModuleFile &MF =
+ ModuleFileIndex ? *F.TransitiveImports[ModuleFileIndex - 1] : F;
+ ModuleFileIndex = MF.Index + 1;
+ return ((uint64_t)ModuleFileIndex << 32) | LocalID;
}
TemplateArgumentLocInfo
@@ -7494,9 +7539,7 @@ ASTRecordReader::readASTTemplateArgumentListInfo() {
return ASTTemplateArgumentListInfo::Create(getContext(), Result);
}
-Decl *ASTReader::GetExternalDecl(uint32_t ID) {
- return GetDecl(ID);
-}
+Decl *ASTReader::GetExternalDecl(GlobalDeclID ID) { return GetDecl(ID); }
void ASTReader::CompleteRedeclChain(const Decl *D) {
if (NumCurrentElementsDeserializing) {
@@ -7629,51 +7672,61 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
return Bases;
}
-serialization::DeclID
-ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
+GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F,
+ LocalDeclID LocalID) const {
if (LocalID < NUM_PREDEF_DECL_IDS)
- return LocalID;
+ return GlobalDeclID(LocalID.getRawValue());
+
+ unsigned OwningModuleFileIndex = LocalID.getModuleFileIndex();
+ DeclID ID = LocalID.getLocalDeclIndex();
if (!F.ModuleOffsetMap.empty())
ReadModuleOffsetMap(F);
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);
- assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");
+ ModuleFile *OwningModuleFile =
+ OwningModuleFileIndex == 0
+ ? &F
+ : F.TransitiveImports[OwningModuleFileIndex - 1];
- return LocalID + I->second;
+ if (OwningModuleFileIndex == 0)
+ ID -= NUM_PREDEF_DECL_IDS;
+
+ uint64_t NewModuleFileIndex = OwningModuleFile->Index + 1;
+ return GlobalDeclID(NewModuleFileIndex, ID);
}
-bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
- ModuleFile &M) const {
+bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const {
// Predefined decls aren't from any module.
if (ID < NUM_PREDEF_DECL_IDS)
return false;
- return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID &&
- ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls;
+ unsigned ModuleFileIndex = ID.getModuleFileIndex();
+ return M.Index == ModuleFileIndex - 1;
}
-ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
+ModuleFile *ASTReader::getOwningModuleFile(GlobalDeclID ID) const {
+ // Predefined decls aren't from any module.
+ if (ID < NUM_PREDEF_DECL_IDS)
+ return nullptr;
+
+ uint64_t ModuleFileIndex = ID.getModuleFileIndex();
+ assert(ModuleFileIndex && "Untranslated Local Decl?");
+
+ return &getModuleManager()[ModuleFileIndex - 1];
+}
+
+ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) const {
if (!D->isFromASTFile())
return nullptr;
- GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- return I->second;
+
+ return getOwningModuleFile(D->getGlobalID());
}
SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
if (ID < NUM_PREDEF_DECL_IDS)
return SourceLocation();
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
-
- if (Index > DeclsLoaded.size()) {
- Error("declaration ID out-of-range for AST file");
- return SourceLocation();
- }
-
- if (Decl *D = DeclsLoaded[Index])
+ if (Decl *D = GetExistingDecl(ID))
return D->getLocation();
SourceLocation Loc;
@@ -7740,8 +7793,19 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) {
llvm_unreachable("PredefinedDeclIDs unknown enum value");
}
-Decl *ASTReader::GetExistingDecl(DeclID ID) {
+unsigned ASTReader::translateGlobalDeclIDToIndex(GlobalDeclID GlobalID) const {
+ ModuleFile *OwningModuleFile = getOwningModuleFile(GlobalID);
+ if (!OwningModuleFile) {
+ assert(GlobalID < NUM_PREDEF_DECL_IDS && "Untransalted Global ID?");
+ return GlobalID.getRawValue();
+ }
+
+ return OwningModuleFile->BaseDeclIndex + GlobalID.getLocalDeclIndex();
+}
+
+Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) {
assert(ContextObj && "reading decl with no AST context");
+
if (ID < NUM_PREDEF_DECL_IDS) {
Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID);
if (D) {
@@ -7754,7 +7818,7 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) {
return D;
}
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+ unsigned Index = translateGlobalDeclIDToIndex(ID);
if (Index >= DeclsLoaded.size()) {
assert(0 && "declaration ID out-of-range for AST file");
@@ -7765,11 +7829,11 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) {
return DeclsLoaded[Index];
}
-Decl *ASTReader::GetDecl(DeclID ID) {
+Decl *ASTReader::GetDecl(GlobalDeclID ID) {
if (ID < NUM_PREDEF_DECL_IDS)
return GetExistingDecl(ID);
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+ unsigned Index = translateGlobalDeclIDToIndex(ID);
if (Index >= DeclsLoaded.size()) {
assert(0 && "declaration ID out-of-range for AST file");
@@ -7786,32 +7850,43 @@ Decl *ASTReader::GetDecl(DeclID ID) {
return DeclsLoaded[Index];
}
-DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
- DeclID GlobalID) {
+LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
+ GlobalDeclID GlobalID) {
if (GlobalID < NUM_PREDEF_DECL_IDS)
- return GlobalID;
+ return LocalDeclID::get(*this, M, GlobalID.getRawValue());
- GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID);
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- ModuleFile *Owner = I->second;
+ if (!M.ModuleOffsetMap.empty())
+ ReadModuleOffsetMap(M);
- llvm::DenseMap<ModuleFile *, serialization::DeclID>::iterator Pos
- = M.GlobalToLocalDeclIDs.find(Owner);
- if (Pos == M.GlobalToLocalDeclIDs.end())
- return 0;
+ ModuleFile *Owner = getOwningModuleFile(GlobalID);
+ DeclID ID = GlobalID.getLocalDeclIndex();
+
+ if (Owner == &M) {
+ ID += NUM_PREDEF_DECL_IDS;
+ return LocalDeclID::get(*this, M, ID);
+ }
+
+ uint64_t OrignalModuleFileIndex = 0;
+ for (unsigned I = 0; I < M.TransitiveImports.size(); I++)
+ if (M.TransitiveImports[I] == Owner) {
+ OrignalModuleFileIndex = I + 1;
+ break;
+ }
+
+ if (!OrignalModuleFileIndex)
+ return LocalDeclID();
- return GlobalID - Owner->BaseDeclID + Pos->second;
+ return LocalDeclID::get(*this, M, OrignalModuleFileIndex, ID);
}
-serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx) {
+GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
+ unsigned &Idx) {
if (Idx >= Record.size()) {
Error("Corrupted AST file");
- return 0;
+ return GlobalDeclID(0);
}
- return getGlobalDeclID(F, Record[Idx++]);
+ return getGlobalDeclID(F, LocalDeclID::get(*this, F, Record[Idx++]));
}
/// Resolve the offset of a statement into a statement.
@@ -7847,7 +7922,7 @@ void ASTReader::FindExternalLexicalDecls(
if (!IsKindWeWant(K))
continue;
- auto ID = (serialization::DeclID)+LexicalDecls[I + 1];
+ auto ID = (DeclID) + LexicalDecls[I + 1];
// Don't add predefined declarations to the lexical context more
// than once.
@@ -7858,7 +7933,7 @@ void ASTReader::FindExternalLexicalDecls(
PredefsVisited[ID] = true;
}
- if (Decl *D = GetLocalDecl(*M, ID)) {
+ if (Decl *D = GetLocalDecl(*M, LocalDeclID::get(*this, *M, ID))) {
assert(D->getKind() == K && "wrong kind for lexical decl");
if (!DC->isDeclInLexicalTraversal(D))
Decls.push_back(D);
@@ -7880,32 +7955,34 @@ void ASTReader::FindExternalLexicalDecls(
namespace {
-class DeclIDComp {
+class UnalignedDeclIDComp {
ASTReader &Reader;
ModuleFile &Mod;
public:
- DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {}
+ UnalignedDeclIDComp(ASTReader &Reader, ModuleFile &M)
+ : Reader(Reader), Mod(M) {}
- bool operator()(LocalDeclID L, LocalDeclID R) const {
+ bool operator()(unaligned_decl_id_t L, unaligned_decl_id_t R) const {
SourceLocation LHS = getLocation(L);
SourceLocation RHS = getLocation(R);
return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
}
- bool operator()(SourceLocation LHS, LocalDeclID R) const {
+ bool operator()(SourceLocation LHS, unaligned_decl_id_t R) const {
SourceLocation RHS = getLocation(R);
return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
}
- bool operator()(LocalDeclID L, SourceLocation RHS) const {
+ bool operator()(unaligned_decl_id_t L, SourceLocation RHS) const {
SourceLocation LHS = getLocation(L);
return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
}
- SourceLocation getLocation(LocalDeclID ID) const {
+ SourceLocation getLocation(unaligned_decl_id_t ID) const {
return Reader.getSourceManager().getFileLoc(
- Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID)));
+ Reader.getSourceLocationForDeclID(
+ Reader.getGlobalDeclID(Mod, LocalDeclID::get(Reader, Mod, ID))));
}
};
@@ -7928,8 +8005,8 @@ void ASTReader::FindFileRegionDecls(FileID File,
BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset);
SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length);
- DeclIDComp DIDComp(*this, *DInfo.Mod);
- ArrayRef<serialization::LocalDeclID>::iterator BeginIt =
+ UnalignedDeclIDComp DIDComp(*this, *DInfo.Mod);
+ ArrayRef<unaligned_decl_id_t>::iterator BeginIt =
llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp);
if (BeginIt != DInfo.Decls.begin())
--BeginIt;
@@ -7938,18 +8015,20 @@ void ASTReader::FindFileRegionDecls(FileID File,
// to backtrack until we find it otherwise we will fail to report that the
// region overlaps with an objc container.
while (BeginIt != DInfo.Decls.begin() &&
- GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt))
+ GetDecl(getGlobalDeclID(*DInfo.Mod,
+ LocalDeclID::get(*this, *DInfo.Mod, *BeginIt)))
->isTopLevelDeclInObjCContainer())
--BeginIt;
- ArrayRef<serialization::LocalDeclID>::iterator EndIt =
+ ArrayRef<unaligned_decl_id_t>::iterator EndIt =
llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp);
if (EndIt != DInfo.Decls.end())
++EndIt;
- for (ArrayRef<serialization::LocalDeclID>::iterator
- DIt = BeginIt; DIt != EndIt; ++DIt)
- Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
+ for (ArrayRef<unaligned_decl_id_t>::iterator DIt = BeginIt; DIt != EndIt;
+ ++DIt)
+ Decls.push_back(GetDecl(getGlobalDeclID(
+ *DInfo.Mod, LocalDeclID::get(*this, *DInfo.Mod, *DIt))));
}
bool
@@ -7969,7 +8048,8 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
// Load the list of declarations.
SmallVector<NamedDecl *, 64> Decls;
llvm::SmallPtrSet<NamedDecl *, 8> Found;
- for (DeclID ID : It->second.Table.find(Name)) {
+
+ for (GlobalDeclID ID : It->second.Table.find(Name)) {
NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
if (ND->getDeclName() == Name && Found.insert(ND).second)
Decls.push_back(ND);
@@ -7990,7 +8070,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
DeclsMap Decls;
- for (DeclID ID : It->second.Table.findAll()) {
+ for (GlobalDeclID ID : It->second.Table.findAll()) {
NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
Decls[ND->getDeclName()].push_back(ND);
}
@@ -8140,19 +8220,15 @@ dumpModuleIDMap(StringRef Name,
llvm::errs() << Name << ":\n";
for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
- I != IEnd; ++I) {
- llvm::errs() << " " << I->first << " -> " << I->second->FileName
- << "\n";
- }
+ I != IEnd; ++I)
+ llvm::errs() << " " << (DeclID)I->first << " -> " << I->second->FileName
+ << "\n";
}
LLVM_DUMP_METHOD void ASTReader::dump() {
llvm::errs() << "*** PCH/ModuleFile Remappings:\n";
dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);
dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);
- dumpModuleIDMap("Global type map", GlobalTypeMap);
- dumpModuleIDMap("Global declaration map", GlobalDeclMap);
- dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
dumpModuleIDMap("Global macro map", GlobalMacroMap);
dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
dumpModuleIDMap("Global selector map", GlobalSelectorMap);
@@ -8188,7 +8264,7 @@ void ASTReader::InitializeSema(Sema &S) {
// Makes sure any declarations that were deserialized "too early"
// still get added to the identifier's declaration chains.
- for (uint64_t ID : PreloadedDeclIDs) {
+ for (GlobalDeclID ID : PreloadedDeclIDs) {
NamedDecl *D = cast<NamedDecl>(GetDecl(ID));
pushExternalDeclIntoScope(D, D->getDeclName());
}
@@ -8217,11 +8293,11 @@ void ASTReader::UpdateSema() {
assert(SemaDeclRefs.size() % 3 == 0);
for (unsigned I = 0; I != SemaDeclRefs.size(); I += 3) {
if (!SemaObj->StdNamespace)
- SemaObj->StdNamespace = SemaDeclRefs[I];
+ SemaObj->StdNamespace = SemaDeclRefs[I].getRawValue();
if (!SemaObj->StdBadAlloc)
- SemaObj->StdBadAlloc = SemaDeclRefs[I+1];
+ SemaObj->StdBadAlloc = SemaDeclRefs[I + 1].getRawValue();
if (!SemaObj->StdAlignValT)
- SemaObj->StdAlignValT = SemaDeclRefs[I+2];
+ SemaObj->StdAlignValT = SemaDeclRefs[I + 2].getRawValue();
}
SemaDeclRefs.clear();
}
@@ -8238,7 +8314,7 @@ void ASTReader::UpdateSema() {
PragmaMSPointersToMembersState,
PointersToMembersPragmaLocation);
}
- SemaObj->ForceCUDAHostDeviceDepth = ForceCUDAHostDeviceDepth;
+ SemaObj->CUDA().ForceHostDeviceDepth = ForceHostDeviceDepth;
if (PragmaAlignPackCurrentValue) {
// The bottom of the stack might have a default value. It must be adjusted
@@ -8534,7 +8610,7 @@ namespace serialization {
static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,
ObjCMethodList &List) {
for (ObjCMethodDecl *M : llvm::reverse(Methods))
- S.addMethodToGlobalList(&List, M);
+ S.ObjC().addMethodToGlobalList(&List, M);
}
void ASTReader::ReadMethodPool(Selector Sel) {
@@ -8559,8 +8635,10 @@ void ASTReader::ReadMethodPool(Selector Sel) {
return;
Sema &S = *getSema();
- Sema::GlobalMethodPool::iterator Pos =
- S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethodPool::Lists()))
+ SemaObjC::GlobalMethodPool::iterator Pos =
+ S.ObjC()
+ .MethodPool
+ .insert(std::make_pair(Sel, SemaObjC::GlobalMethodPool::Lists()))
.first;
Pos->second.first.setBits(Visitor.getInstanceBits());
@@ -8594,18 +8672,20 @@ void ASTReader::ReadKnownNamespaces(
void ASTReader::ReadUndefinedButUsed(
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
for (unsigned Idx = 0, N = UndefinedButUsed.size(); Idx != N;) {
- NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedButUsed[Idx++]));
- SourceLocation Loc =
- SourceLocation::getFromRawEncoding(UndefinedButUsed[Idx++]);
+ UndefinedButUsedDecl &U = UndefinedButUsed[Idx++];
+ NamedDecl *D = cast<NamedDecl>(GetDecl(U.ID));
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(U.RawLoc);
Undefined.insert(std::make_pair(D, Loc));
}
+ UndefinedButUsed.clear();
}
void ASTReader::ReadMismatchingDeleteExpressions(llvm::MapVector<
FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
Exprs) {
for (unsigned Idx = 0, N = DelayedDeleteExprs.size(); Idx != N;) {
- FieldDecl *FD = cast<FieldDecl>(GetDecl(DelayedDeleteExprs[Idx++]));
+ FieldDecl *FD =
+ cast<FieldDecl>(GetDecl(GlobalDeclID(DelayedDeleteExprs[Idx++])));
uint64_t Count = DelayedDeleteExprs[Idx++];
for (uint64_t C = 0; C < Count; ++C) {
SourceLocation DeleteLoc =
@@ -8719,9 +8799,10 @@ void ASTReader::ReadWeakUndeclaredIdentifiers(
void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) {
ExternalVTableUse VT;
- VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
- VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]);
- VT.DefinitionRequired = VTableUses[Idx++];
+ VTableUse &TableInfo = VTableUses[Idx++];
+ VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(TableInfo.ID));
+ VT.Location = SourceLocation::getFromRawEncoding(TableInfo.RawLoc);
+ VT.DefinitionRequired = TableInfo.Used;
VTables.push_back(VT);
}
@@ -8731,9 +8812,9 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
void ASTReader::ReadPendingInstantiations(
SmallVectorImpl<std::pair<ValueDecl *, SourceLocation>> &Pending) {
for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
- ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
- SourceLocation Loc
- = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
+ PendingInstantiation &Inst = PendingInstantiations[Idx++];
+ ValueDecl *D = cast<ValueDecl>(GetDecl(Inst.ID));
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(Inst.RawLoc);
Pending.push_back(std::make_pair(D, Loc));
}
@@ -8748,11 +8829,10 @@ void ASTReader::ReadLateParsedTemplates(
RecordDataImpl &LateParsed = LPT.second;
for (unsigned Idx = 0, N = LateParsed.size(); Idx < N;
/* In loop */) {
- FunctionDecl *FD =
- cast<FunctionDecl>(GetLocalDecl(*FMod, LateParsed[Idx++]));
+ FunctionDecl *FD = ReadDeclAs<FunctionDecl>(*FMod, LateParsed, Idx);
auto LT = std::make_unique<LateParsedTemplate>();
- LT->D = GetLocalDecl(*FMod, LateParsed[Idx++]);
+ LT->D = ReadDecl(*FMod, LateParsed, Idx);
LT->FPO = FPOptions::getFromOpaqueInt(LateParsed[Idx++]);
ModuleFile *F = getOwningModuleFile(LT->D);
@@ -8788,8 +8868,9 @@ void ASTReader::LoadSelector(Selector Sel) {
void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {
assert(ID && "Non-zero identifier ID required");
- assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
- IdentifiersLoaded[ID - 1] = II;
+ unsigned Index = translateIdentifierIDToIndex(ID).second;
+ assert(Index < IdentifiersLoaded.size() && "identifier ID out of range");
+ IdentifiersLoaded[Index] = II;
if (DeserializationListener)
DeserializationListener->IdentifierRead(ID, II);
}
@@ -8810,10 +8891,9 @@ void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {
/// \param Decls if non-null, this vector will be populated with the set of
/// deserialized declarations. These declarations will not be pushed into
/// scope.
-void
-ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
- const SmallVectorImpl<uint32_t> &DeclIDs,
- SmallVectorImpl<Decl *> *Decls) {
+void ASTReader::SetGloballyVisibleDecls(
+ IdentifierInfo *II, const SmallVectorImpl<GlobalDeclID> &DeclIDs,
+ SmallVectorImpl<Decl *> *Decls) {
if (NumCurrentElementsDeserializing && !Decls) {
PendingIdentifierInfos[II].append(DeclIDs.begin(), DeclIDs.end());
return;
@@ -8843,6 +8923,22 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
}
}
+std::pair<ModuleFile *, unsigned>
+ASTReader::translateIdentifierIDToIndex(IdentifierID ID) const {
+ if (ID == 0)
+ return {nullptr, 0};
+
+ unsigned ModuleFileIndex = ID >> 32;
+ unsigned LocalID = ID & llvm::maskTrailingOnes<IdentifierID>(32);
+
+ assert(ModuleFileIndex && "not translating loaded IdentifierID?");
+ assert(getModuleManager().size() > ModuleFileIndex - 1);
+
+ ModuleFile &MF = getModuleManager()[ModuleFileIndex - 1];
+ assert(LocalID < MF.LocalNumIdentifiers);
+ return {&MF, MF.BaseIdentifierID + LocalID};
+}
+
IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
if (ID == 0)
return nullptr;
@@ -8852,45 +8948,48 @@ IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
return nullptr;
}
- ID -= 1;
- if (!IdentifiersLoaded[ID]) {
- GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1);
- assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map");
- ModuleFile *M = I->second;
- unsigned Index = ID - M->BaseIdentifierID;
+ auto [M, Index] = translateIdentifierIDToIndex(ID);
+ if (!IdentifiersLoaded[Index]) {
+ assert(M != nullptr && "Untranslated Identifier ID?");
+ assert(Index >= M->BaseIdentifierID);
+ unsigned LocalIndex = Index - M->BaseIdentifierID;
const unsigned char *Data =
- M->IdentifierTableData + M->IdentifierOffsets[Index];
+ M->IdentifierTableData + M->IdentifierOffsets[LocalIndex];
ASTIdentifierLookupTrait Trait(*this, *M);
auto KeyDataLen = Trait.ReadKeyDataLength(Data);
auto Key = Trait.ReadKey(Data, KeyDataLen.first);
auto &II = PP.getIdentifierTable().get(Key);
- IdentifiersLoaded[ID] = &II;
+ IdentifiersLoaded[Index] = &II;
markIdentifierFromAST(*this, II);
if (DeserializationListener)
- DeserializationListener->IdentifierRead(ID + 1, &II);
+ DeserializationListener->IdentifierRead(ID, &II);
}
- return IdentifiersLoaded[ID];
+ return IdentifiersLoaded[Index];
}
-IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) {
+IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, uint64_t LocalID) {
return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID));
}
-IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
+IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, uint64_t LocalID) {
if (LocalID < NUM_PREDEF_IDENT_IDS)
return LocalID;
if (!M.ModuleOffsetMap.empty())
ReadModuleOffsetMap(M);
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);
- assert(I != M.IdentifierRemap.end()
- && "Invalid index into identifier index remap");
+ unsigned ModuleFileIndex = LocalID >> 32;
+ LocalID &= llvm::maskTrailingOnes<IdentifierID>(32);
+ ModuleFile *MF =
+ ModuleFileIndex ? M.TransitiveImports[ModuleFileIndex - 1] : &M;
+ assert(MF && "malformed identifier ID encoding?");
- return LocalID + I->second;
+ if (!ModuleFileIndex)
+ LocalID -= NUM_PREDEF_IDENT_IDS;
+
+ return ((IdentifierID)(MF->Index + 1) << 32) | LocalID;
}
MacroInfo *ASTReader::getMacro(MacroID ID) {
@@ -8935,7 +9034,7 @@ MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {
}
serialization::SubmoduleID
-ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
+ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) const {
if (LocalID < NUM_PREDEF_SUBMODULE_IDS)
return LocalID;
@@ -8968,7 +9067,7 @@ Module *ASTReader::getModule(unsigned ID) {
return getSubmodule(ID);
}
-ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) {
+ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &M, unsigned ID) const {
if (ID & 1) {
// It's a module, look it up by submodule ID.
auto I = GlobalSubmoduleMap.find(getGlobalSubmoduleID(M, ID >> 1));
@@ -9111,6 +9210,10 @@ DeclarationNameInfo ASTRecordReader::readDeclarationNameInfo() {
return NameInfo;
}
+TypeCoupledDeclRefInfo ASTRecordReader::readTypeCoupledDeclRefInfo() {
+ return TypeCoupledDeclRefInfo(readDeclAs<ValueDecl>(), readBool());
+}
+
void ASTRecordReader::readQualifierInfo(QualifierInfo &Info) {
Info.QualifierLoc = readNestedNameSpecifierLoc();
unsigned NumTPLists = readInt();
@@ -9157,7 +9260,7 @@ void ASTRecordReader::readUnresolvedSet(LazyASTUnresolvedSet &Set) {
unsigned NumDecls = readInt();
Set.reserve(getContext(), NumDecls);
while (NumDecls--) {
- DeclID ID = readDeclID();
+ GlobalDeclID ID = readDeclID();
AccessSpecifier AS = (AccessSpecifier) readInt();
Set.addLazyDecl(getContext(), ID, AS);
}
@@ -9312,6 +9415,18 @@ SourceRange ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record,
return SourceRange(beg, end);
}
+llvm::BitVector ASTReader::ReadBitVector(const RecordData &Record,
+ const StringRef Blob) {
+ unsigned Count = Record[0];
+ const char *Byte = Blob.data();
+ llvm::BitVector Ret = llvm::BitVector(Count, false);
+ for (unsigned I = 0; I < Count; ++Byte)
+ for (unsigned Bit = 0; Bit < 8 && I < Count; ++Bit, ++I)
+ if (*Byte & (1 << Bit))
+ Ret[I] = true;
+ return Ret;
+}
+
/// Read a floating-point value
llvm::APFloat ASTRecordReader::readAPFloat(const llvm::fltSemantics &Sem) {
return llvm::APFloat(Sem, readAPInt());
@@ -9367,6 +9482,20 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const {
return Diags.Report(Loc, DiagID);
}
+void ASTReader::warnStackExhausted(SourceLocation Loc) {
+ // When Sema is available, avoid duplicate errors.
+ if (SemaObj) {
+ SemaObj->warnStackExhausted(Loc);
+ return;
+ }
+
+ if (WarnedStackExhausted)
+ return;
+ WarnedStackExhausted = true;
+
+ Diag(Loc, diag::warn_stack_exhausted);
+}
+
/// Retrieve the identifier table associated with the
/// preprocessor.
IdentifierTable &ASTReader::getIdentifierTable() {
@@ -9521,7 +9650,7 @@ void ASTReader::finishPendingActions() {
while (!PendingIdentifierInfos.empty()) {
IdentifierInfo *II = PendingIdentifierInfos.back().first;
- SmallVector<uint32_t, 4> DeclIDs =
+ SmallVector<GlobalDeclID, 4> DeclIDs =
std::move(PendingIdentifierInfos.back().second);
PendingIdentifierInfos.pop_back();
@@ -9745,7 +9874,8 @@ void ASTReader::finishPendingActions() {
!NonConstDefn->isLateTemplateParsed() &&
// We only perform ODR checks for decls not in the explicit
// global module fragment.
- !FD->shouldSkipCheckingODR() &&
+ !shouldSkipCheckingODR(FD) &&
+ !shouldSkipCheckingODR(NonConstDefn) &&
FD->getODRHash() != NonConstDefn->getODRHash()) {
if (!isa<CXXMethodDecl>(FD)) {
PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn);
@@ -10139,7 +10269,7 @@ void ASTReader::FinishedDeserializing() {
}
void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
- if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
+ if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
// Remove any fake results before adding any real ones.
auto It = PendingFakeLookupResults.find(II);
if (It != PendingFakeLookupResults.end()) {
@@ -10335,6 +10465,9 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_relaxed:
C = new (Context) OMPRelaxedClause();
break;
+ case llvm::omp::OMPC_weak:
+ C = new (Context) OMPWeakClause();
+ break;
case llvm::omp::OMPC_threads:
C = new (Context) OMPThreadsClause();
break;
@@ -10733,6 +10866,8 @@ void OMPClauseReader::VisitOMPReleaseClause(OMPReleaseClause *) {}
void OMPClauseReader::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
+void OMPClauseReader::VisitOMPWeakClause(OMPWeakClause *) {}
+
void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
@@ -11717,3 +11852,209 @@ void ASTRecordReader::readOMPChildren(OMPChildren *Data) {
for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I)
Data->getChildren()[I] = readStmt();
}
+
+SmallVector<Expr *> ASTRecordReader::readOpenACCVarList() {
+ unsigned NumVars = readInt();
+ llvm::SmallVector<Expr *> VarList;
+ for (unsigned I = 0; I < NumVars; ++I)
+ VarList.push_back(readSubExpr());
+ return VarList;
+}
+
+SmallVector<Expr *> ASTRecordReader::readOpenACCIntExprList() {
+ unsigned NumExprs = readInt();
+ llvm::SmallVector<Expr *> ExprList;
+ for (unsigned I = 0; I < NumExprs; ++I)
+ ExprList.push_back(readSubExpr());
+ return ExprList;
+}
+
+OpenACCClause *ASTRecordReader::readOpenACCClause() {
+ OpenACCClauseKind ClauseKind = readEnum<OpenACCClauseKind>();
+ SourceLocation BeginLoc = readSourceLocation();
+ SourceLocation EndLoc = readSourceLocation();
+
+ switch (ClauseKind) {
+ case OpenACCClauseKind::Default: {
+ SourceLocation LParenLoc = readSourceLocation();
+ OpenACCDefaultClauseKind DCK = readEnum<OpenACCDefaultClauseKind>();
+ return OpenACCDefaultClause::Create(getContext(), DCK, BeginLoc, LParenLoc,
+ EndLoc);
+ }
+ case OpenACCClauseKind::If: {
+ SourceLocation LParenLoc = readSourceLocation();
+ Expr *CondExpr = readSubExpr();
+ return OpenACCIfClause::Create(getContext(), BeginLoc, LParenLoc, CondExpr,
+ EndLoc);
+ }
+ case OpenACCClauseKind::Self: {
+ SourceLocation LParenLoc = readSourceLocation();
+ Expr *CondExpr = readBool() ? readSubExpr() : nullptr;
+ return OpenACCSelfClause::Create(getContext(), BeginLoc, LParenLoc,
+ CondExpr, EndLoc);
+ }
+ case OpenACCClauseKind::NumGangs: {
+ SourceLocation LParenLoc = readSourceLocation();
+ unsigned NumClauses = readInt();
+ llvm::SmallVector<Expr *> IntExprs;
+ for (unsigned I = 0; I < NumClauses; ++I)
+ IntExprs.push_back(readSubExpr());
+ return OpenACCNumGangsClause::Create(getContext(), BeginLoc, LParenLoc,
+ IntExprs, EndLoc);
+ }
+ case OpenACCClauseKind::NumWorkers: {
+ SourceLocation LParenLoc = readSourceLocation();
+ Expr *IntExpr = readSubExpr();
+ return OpenACCNumWorkersClause::Create(getContext(), BeginLoc, LParenLoc,
+ IntExpr, EndLoc);
+ }
+ case OpenACCClauseKind::VectorLength: {
+ SourceLocation LParenLoc = readSourceLocation();
+ Expr *IntExpr = readSubExpr();
+ return OpenACCVectorLengthClause::Create(getContext(), BeginLoc, LParenLoc,
+ IntExpr, EndLoc);
+ }
+ case OpenACCClauseKind::Private: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::FirstPrivate: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCFirstPrivateClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::Attach: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCAttachClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::DevicePtr: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCDevicePtrClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::NoCreate: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCNoCreateClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::Present: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCPresentClause::Create(getContext(), BeginLoc, LParenLoc,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::PCopy:
+ case OpenACCClauseKind::PresentOrCopy:
+ case OpenACCClauseKind::Copy: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCCopyClause::Create(getContext(), ClauseKind, BeginLoc,
+ LParenLoc, VarList, EndLoc);
+ }
+ case OpenACCClauseKind::CopyIn:
+ case OpenACCClauseKind::PCopyIn:
+ case OpenACCClauseKind::PresentOrCopyIn: {
+ SourceLocation LParenLoc = readSourceLocation();
+ bool IsReadOnly = readBool();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCCopyInClause::Create(getContext(), ClauseKind, BeginLoc,
+ LParenLoc, IsReadOnly, VarList, EndLoc);
+ }
+ case OpenACCClauseKind::CopyOut:
+ case OpenACCClauseKind::PCopyOut:
+ case OpenACCClauseKind::PresentOrCopyOut: {
+ SourceLocation LParenLoc = readSourceLocation();
+ bool IsZero = readBool();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCCopyOutClause::Create(getContext(), ClauseKind, BeginLoc,
+ LParenLoc, IsZero, VarList, EndLoc);
+ }
+ case OpenACCClauseKind::Create:
+ case OpenACCClauseKind::PCreate:
+ case OpenACCClauseKind::PresentOrCreate: {
+ SourceLocation LParenLoc = readSourceLocation();
+ bool IsZero = readBool();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCCreateClause::Create(getContext(), ClauseKind, BeginLoc,
+ LParenLoc, IsZero, VarList, EndLoc);
+ }
+ case OpenACCClauseKind::Async: {
+ SourceLocation LParenLoc = readSourceLocation();
+ Expr *AsyncExpr = readBool() ? readSubExpr() : nullptr;
+ return OpenACCAsyncClause::Create(getContext(), BeginLoc, LParenLoc,
+ AsyncExpr, EndLoc);
+ }
+ case OpenACCClauseKind::Wait: {
+ SourceLocation LParenLoc = readSourceLocation();
+ Expr *DevNumExpr = readBool() ? readSubExpr() : nullptr;
+ SourceLocation QueuesLoc = readSourceLocation();
+ llvm::SmallVector<Expr *> QueueIdExprs = readOpenACCIntExprList();
+ return OpenACCWaitClause::Create(getContext(), BeginLoc, LParenLoc,
+ DevNumExpr, QueuesLoc, QueueIdExprs,
+ EndLoc);
+ }
+ case OpenACCClauseKind::DeviceType:
+ case OpenACCClauseKind::DType: {
+ SourceLocation LParenLoc = readSourceLocation();
+ llvm::SmallVector<DeviceTypeArgument> Archs;
+ unsigned NumArchs = readInt();
+
+ for (unsigned I = 0; I < NumArchs; ++I) {
+ IdentifierInfo *Ident = readBool() ? readIdentifier() : nullptr;
+ SourceLocation Loc = readSourceLocation();
+ Archs.emplace_back(Ident, Loc);
+ }
+
+ return OpenACCDeviceTypeClause::Create(getContext(), ClauseKind, BeginLoc,
+ LParenLoc, Archs, EndLoc);
+ }
+ case OpenACCClauseKind::Reduction: {
+ SourceLocation LParenLoc = readSourceLocation();
+ OpenACCReductionOperator Op = readEnum<OpenACCReductionOperator>();
+ llvm::SmallVector<Expr *> VarList = readOpenACCVarList();
+ return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op,
+ VarList, EndLoc);
+ }
+ case OpenACCClauseKind::Seq:
+ return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc);
+ case OpenACCClauseKind::Independent:
+ return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc);
+ case OpenACCClauseKind::Auto:
+ return OpenACCAutoClause::Create(getContext(), BeginLoc, EndLoc);
+
+ case OpenACCClauseKind::Finalize:
+ case OpenACCClauseKind::IfPresent:
+ case OpenACCClauseKind::Worker:
+ case OpenACCClauseKind::Vector:
+ case OpenACCClauseKind::NoHost:
+ case OpenACCClauseKind::UseDevice:
+ case OpenACCClauseKind::Delete:
+ case OpenACCClauseKind::Detach:
+ case OpenACCClauseKind::Device:
+ case OpenACCClauseKind::DeviceResident:
+ case OpenACCClauseKind::Host:
+ case OpenACCClauseKind::Link:
+ case OpenACCClauseKind::Collapse:
+ case OpenACCClauseKind::Bind:
+ case OpenACCClauseKind::DeviceNum:
+ case OpenACCClauseKind::DefaultAsync:
+ case OpenACCClauseKind::Tile:
+ case OpenACCClauseKind::Gang:
+ case OpenACCClauseKind::Invalid:
+ llvm_unreachable("Clause serialization not yet implemented");
+ }
+ llvm_unreachable("Invalid Clause Kind");
+}
+
+void ASTRecordReader::readOpenACCClauseList(
+ MutableArrayRef<const OpenACCClause *> Clauses) {
+ for (unsigned I = 0; I < Clauses.size(); ++I)
+ Clauses[I] = readOpenACCClause();
+}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
index 110f55f8c0f4..31ab6c651d59 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -49,6 +49,7 @@
#include "clang/Basic/PragmaKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/Stack.h"
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTRecordReader.h"
@@ -84,18 +85,16 @@ namespace clang {
ASTReader &Reader;
ASTRecordReader &Record;
ASTReader::RecordLocation Loc;
- const DeclID ThisDeclID;
+ const GlobalDeclID ThisDeclID;
const SourceLocation ThisDeclLoc;
using RecordData = ASTReader::RecordData;
TypeID DeferredTypeID = 0;
unsigned AnonymousDeclNumber = 0;
- GlobalDeclID NamedDeclForTagDecl = 0;
+ GlobalDeclID NamedDeclForTagDecl = GlobalDeclID();
IdentifierInfo *TypedefNameForLinkage = nullptr;
- bool HasPendingBody = false;
-
///A flag to carry the information for a decl from the entity is
/// used. We use it to delay the marking of the canonical decl as used until
/// the entire declaration is deserialized and merged.
@@ -126,15 +125,13 @@ namespace clang {
return Record.readTypeSourceInfo();
}
- serialization::DeclID readDeclID() {
- return Record.readDeclID();
- }
+ GlobalDeclID readDeclID() { return Record.readDeclID(); }
std::string readString() {
return Record.readString();
}
- void readDeclIDList(SmallVectorImpl<DeclID> &IDs) {
+ void readDeclIDList(SmallVectorImpl<GlobalDeclID> &IDs) {
for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I)
IDs.push_back(readDeclID());
}
@@ -260,14 +257,14 @@ namespace clang {
public:
ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record,
- ASTReader::RecordLocation Loc,
- DeclID thisDeclID, SourceLocation ThisDeclLoc)
+ ASTReader::RecordLocation Loc, GlobalDeclID thisDeclID,
+ SourceLocation ThisDeclLoc)
: Reader(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID),
ThisDeclLoc(ThisDeclLoc) {}
- template <typename T> static
- void AddLazySpecializations(T *D,
- SmallVectorImpl<serialization::DeclID>& IDs) {
+ template <typename T>
+ static void AddLazySpecializations(T *D,
+ SmallVectorImpl<GlobalDeclID> &IDs) {
if (IDs.empty())
return;
@@ -277,13 +274,14 @@ namespace clang {
auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations;
if (auto &Old = LazySpecializations) {
- IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
+ IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0].getRawValue());
llvm::sort(IDs);
IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
}
- auto *Result = new (C) serialization::DeclID[1 + IDs.size()];
- *Result = IDs.size();
+ auto *Result = new (C) GlobalDeclID[1 + IDs.size()];
+ *Result = GlobalDeclID(IDs.size());
+
std::copy(IDs.begin(), IDs.end(), Result + 1);
LazySpecializations = Result;
@@ -314,13 +312,10 @@ namespace clang {
static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
static void markIncompleteDeclChainImpl(...);
- /// Determine whether this declaration has a pending body.
- bool hasPendingBody() const { return HasPendingBody; }
-
void ReadFunctionDefinition(FunctionDecl *FD);
void Visit(Decl *D);
- void UpdateDecl(Decl *D, SmallVectorImpl<serialization::DeclID> &);
+ void UpdateDecl(Decl *D, SmallVectorImpl<GlobalDeclID> &);
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
ObjCCategoryDecl *Next) {
@@ -541,7 +536,6 @@ void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
}
// Store the offset of the body so we can lazily load it later.
Reader.PendingBodies[FD] = GetCurrentCursorOffset();
- HasPendingBody = true;
}
void ASTDeclReader::Visit(Decl *D) {
@@ -563,7 +557,7 @@ void ASTDeclReader::Visit(Decl *D) {
// If this is a tag declaration with a typedef name for linkage, it's safe
// to load that typedef now.
- if (NamedDeclForTagDecl)
+ if (NamedDeclForTagDecl.isValid())
cast<TagDecl>(D)->TypedefNameDeclOrQualifier =
cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl));
} else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
@@ -607,8 +601,8 @@ void ASTDeclReader::VisitDecl(Decl *D) {
// placeholder.
GlobalDeclID SemaDCIDForTemplateParmDecl = readDeclID();
GlobalDeclID LexicalDCIDForTemplateParmDecl =
- HasStandaloneLexicalDC ? readDeclID() : 0;
- if (!LexicalDCIDForTemplateParmDecl)
+ HasStandaloneLexicalDC ? readDeclID() : GlobalDeclID();
+ if (LexicalDCIDForTemplateParmDecl.isInvalid())
LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl;
Reader.addPendingDeclContextInfo(D,
SemaDCIDForTemplateParmDecl,
@@ -800,21 +794,16 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
BitsUnpacker EnumDeclBits(Record.readInt());
ED->setNumPositiveBits(EnumDeclBits.getNextBits(/*Width=*/8));
ED->setNumNegativeBits(EnumDeclBits.getNextBits(/*Width=*/8));
- bool ShouldSkipCheckingODR = EnumDeclBits.getNextBit();
ED->setScoped(EnumDeclBits.getNextBit());
ED->setScopedUsingClassTag(EnumDeclBits.getNextBit());
ED->setFixed(EnumDeclBits.getNextBit());
- if (!ShouldSkipCheckingODR) {
- ED->setHasODRHash(true);
- ED->ODRHash = Record.readInt();
- }
+ ED->setHasODRHash(true);
+ ED->ODRHash = Record.readInt();
// If this is a definition subject to the ODR, and we already have a
// definition, merge this one into it.
- if (ED->isCompleteDefinition() &&
- Reader.getContext().getLangOpts().Modules &&
- Reader.getContext().getLangOpts().CPlusPlus) {
+ if (ED->isCompleteDefinition() && Reader.getContext().getLangOpts().Modules) {
EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
if (!OldDef) {
// This is the first time we've seen an imported definition. Look for a
@@ -832,7 +821,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
Reader.mergeDefinitionVisibility(OldDef, ED);
// We don't want to check the ODR hash value for declarations from global
// module fragment.
- if (!ED->shouldSkipCheckingODR() &&
+ if (!shouldSkipCheckingODR(ED) && !shouldSkipCheckingODR(OldDef) &&
OldDef->getODRHash() != ED->getODRHash())
Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
} else {
@@ -872,9 +861,6 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
VisitRecordDeclImpl(RD);
- // We should only reach here if we're in C/Objective-C. There is no
- // global module fragment.
- assert(!RD->shouldSkipCheckingODR());
RD->setODRHash(Record.readInt());
// Maintain the invariant of a redeclaration chain containing only
@@ -1074,7 +1060,6 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setCachedLinkage((Linkage)FunctionDeclBits.getNextBits(/*Width=*/3));
FD->setStorageClass((StorageClass)FunctionDeclBits.getNextBits(/*Width=*/3));
- bool ShouldSkipCheckingODR = FunctionDeclBits.getNextBit();
FD->setInlineSpecified(FunctionDeclBits.getNextBit());
FD->setImplicitlyInline(FunctionDeclBits.getNextBit());
FD->setHasSkippedBody(FunctionDeclBits.getNextBit());
@@ -1104,21 +1089,29 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
if (FD->isExplicitlyDefaulted())
FD->setDefaultLoc(readSourceLocation());
- if (!ShouldSkipCheckingODR) {
- FD->ODRHash = Record.readInt();
- FD->setHasODRHash(true);
- }
+ FD->ODRHash = Record.readInt();
+ FD->setHasODRHash(true);
- if (FD->isDefaulted()) {
- if (unsigned NumLookups = Record.readInt()) {
+ if (FD->isDefaulted() || FD->isDeletedAsWritten()) {
+ // If 'Info' is nonzero, we need to read an DefaultedOrDeletedInfo; if,
+ // additionally, the second bit is also set, we also need to read
+ // a DeletedMessage for the DefaultedOrDeletedInfo.
+ if (auto Info = Record.readInt()) {
+ bool HasMessage = Info & 2;
+ StringLiteral *DeletedMessage =
+ HasMessage ? cast<StringLiteral>(Record.readExpr()) : nullptr;
+
+ 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));
+
+ FD->setDefaultedOrDeletedInfo(
+ FunctionDecl::DefaultedOrDeletedFunctionInfo::Create(
+ Reader.getContext(), Lookups, DeletedMessage));
}
}
@@ -1164,7 +1157,6 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
// Load the body on-demand. Most clients won't care, because method
// definitions rarely show up in headers.
Reader.PendingBodies[MD] = GetCurrentCursorOffset();
- HasPendingBody = true;
}
MD->setSelfDecl(readDeclAs<ImplicitParamDecl>());
MD->setCmdDecl(readDeclAs<ImplicitParamDecl>());
@@ -1845,18 +1837,13 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
// this namespace; loading it might load a later declaration of the
// same namespace, and we have an invariant that older declarations
// get merged before newer ones try to merge.
- GlobalDeclID AnonNamespace = 0;
- if (Redecl.getFirstID() == ThisDeclID) {
+ GlobalDeclID AnonNamespace;
+ if (Redecl.getFirstID() == ThisDeclID)
AnonNamespace = readDeclID();
- } else {
- // Link this namespace back to the first declaration, which has already
- // been deserialized.
- D->AnonOrFirstNamespaceAndFlags.setPointer(D->getFirstDecl());
- }
mergeRedeclarable(D, Redecl);
- if (AnonNamespace) {
+ if (AnonNamespace.isValid()) {
// Each module has its own anonymous namespace, which is disjoint from
// any other module's anonymous namespaces, so don't attach the anonymous
// namespace at all.
@@ -1975,8 +1962,6 @@ void ASTDeclReader::ReadCXXDefinitionData(
BitsUnpacker CXXRecordDeclBits = Record.readInt();
- bool ShouldSkipCheckingODR = CXXRecordDeclBits.getNextBit();
-
#define FIELD(Name, Width, Merge) \
if (!CXXRecordDeclBits.canGetNextNBits(Width)) \
CXXRecordDeclBits.updateValue(Record.readInt()); \
@@ -1985,12 +1970,9 @@ void ASTDeclReader::ReadCXXDefinitionData(
#include "clang/AST/CXXRecordDeclDefinitionBits.def"
#undef FIELD
- // We only perform ODR checks for decls not in GMF.
- if (!ShouldSkipCheckingODR) {
- // Note: the caller has deserialized the IsLambda bit already.
- Data.ODRHash = Record.readInt();
- Data.HasODRHash = true;
- }
+ // Note: the caller has deserialized the IsLambda bit already.
+ Data.ODRHash = Record.readInt();
+ Data.HasODRHash = true;
if (Record.readInt()) {
Reader.DefinitionSource[D] =
@@ -2016,7 +1998,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
if (Data.NumVBases)
Data.VBases = ReadGlobalOffset();
- Data.FirstFriend = readDeclID();
+ Data.FirstFriend = readDeclID().getRawValue();
} else {
using Capture = LambdaCapture;
@@ -2152,7 +2134,7 @@ void ASTDeclReader::MergeDefinitionData(
}
// We don't want to check ODR for decls in the global module fragment.
- if (MergeDD.Definition->shouldSkipCheckingODR())
+ if (shouldSkipCheckingODR(MergeDD.Definition) || shouldSkipCheckingODR(D))
return;
if (D->getODRHash() != MergeDD.ODRHash) {
@@ -2275,12 +2257,12 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
// Lazily load the key function to avoid deserializing every method so we can
// compute it.
if (WasDefinition) {
- DeclID KeyFn = readDeclID();
- if (KeyFn && D->isCompleteDefinition())
+ GlobalDeclID KeyFn = readDeclID();
+ if (KeyFn.isValid() && D->isCompleteDefinition())
// FIXME: This is wrong for the ARM ABI, where some other module may have
// made this function no longer be a key function. We need an update
// record or similar for that case.
- C.KeyFunctions[D] = KeyFn;
+ C.KeyFunctions[D] = KeyFn.getRawValue();
}
return Redecl;
@@ -2369,7 +2351,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
for (unsigned i = 0; i != D->NumTPLists; ++i)
D->getTrailingObjects<TemplateParameterList *>()[i] =
Record.readTemplateParameterList();
- D->NextFriend = readDeclID();
+ D->NextFriend = readDeclID().getRawValue();
D->UnsupportedFriend = (Record.readInt() != 0);
D->FriendLoc = readSourceLocation();
}
@@ -2454,7 +2436,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (ThisDeclID == Redecl.getFirstID()) {
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
// the specializations.
- SmallVector<serialization::DeclID, 32> SpecIDs;
+ SmallVector<GlobalDeclID, 32> SpecIDs;
readDeclIDList(SpecIDs);
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
}
@@ -2482,7 +2464,7 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
if (ThisDeclID == Redecl.getFirstID()) {
// This VarTemplateDecl owns a CommonPtr; read it to keep track of all of
// the specializations.
- SmallVector<serialization::DeclID, 32> SpecIDs;
+ SmallVector<GlobalDeclID, 32> SpecIDs;
readDeclIDList(SpecIDs);
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
}
@@ -2548,16 +2530,17 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
}
}
- // Explicit info.
- if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) {
- auto *ExplicitInfo =
- new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = TyInfo;
- ExplicitInfo->ExternLoc = readSourceLocation();
+ // extern/template keyword locations for explicit instantiations
+ if (Record.readBool()) {
+ auto *ExplicitInfo = new (C) ExplicitInstantiationInfo;
+ ExplicitInfo->ExternKeywordLoc = readSourceLocation();
ExplicitInfo->TemplateKeywordLoc = readSourceLocation();
D->ExplicitInfo = ExplicitInfo;
}
+ if (Record.readBool())
+ D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo());
+
return Redecl;
}
@@ -2567,7 +2550,6 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
// need them for profiling
TemplateParameterList *Params = Record.readTemplateParameterList();
D->TemplateParams = Params;
- D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
@@ -2584,7 +2566,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (ThisDeclID == Redecl.getFirstID()) {
// This FunctionTemplateDecl owns a CommonPtr; read it.
- SmallVector<serialization::DeclID, 32> SpecIDs;
+ SmallVector<GlobalDeclID, 32> SpecIDs;
readDeclIDList(SpecIDs);
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
}
@@ -2617,16 +2599,17 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
}
}
- // Explicit info.
- if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) {
- auto *ExplicitInfo =
- new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = TyInfo;
- ExplicitInfo->ExternLoc = readSourceLocation();
+ // extern/template keyword locations for explicit instantiations
+ if (Record.readBool()) {
+ auto *ExplicitInfo = new (C) ExplicitInstantiationInfo;
+ ExplicitInfo->ExternKeywordLoc = readSourceLocation();
ExplicitInfo->TemplateKeywordLoc = readSourceLocation();
D->ExplicitInfo = ExplicitInfo;
}
+ if (Record.readBool())
+ D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo());
+
SmallVector<TemplateArgument, 8> TemplArgs;
Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
@@ -2666,7 +2649,6 @@ void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl(
VarTemplatePartialSpecializationDecl *D) {
TemplateParameterList *Params = Record.readTemplateParameterList();
D->TemplateParams = Params;
- D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
@@ -2695,7 +2677,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
}
if (Record.readInt())
- D->setDefaultArgument(readTypeSourceInfo());
+ D->setDefaultArgument(Reader.getContext(),
+ Record.readTemplateArgumentLoc());
}
void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
@@ -2716,12 +2699,14 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
// Rest of NonTypeTemplateParmDecl.
D->ParameterPack = Record.readInt();
if (Record.readInt())
- D->setDefaultArgument(Record.readExpr());
+ D->setDefaultArgument(Reader.getContext(),
+ Record.readTemplateArgumentLoc());
}
}
void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
VisitTemplateDecl(D);
+ D->setDeclaredWithTypename(Record.readBool());
// TemplateParmPosition.
D->setDepth(Record.readInt());
D->setPosition(Record.readInt());
@@ -2779,7 +2764,7 @@ ASTDeclReader::VisitDeclContext(DeclContext *DC) {
template <typename T>
ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
- DeclID FirstDeclID = readDeclID();
+ GlobalDeclID FirstDeclID = readDeclID();
Decl *MergeWith = nullptr;
bool IsKeyDecl = ThisDeclID == FirstDeclID;
@@ -2787,9 +2772,9 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
uint64_t RedeclOffset = 0;
- // 0 indicates that this declaration was the only declaration of its entity,
- // and is used for space optimization.
- if (FirstDeclID == 0) {
+ // invalid FirstDeclID indicates that this declaration was the only
+ // declaration of its entity, and is used for space optimization.
+ if (FirstDeclID.isInvalid()) {
FirstDeclID = ThisDeclID;
IsKeyDecl = true;
IsFirstLocalDecl = true;
@@ -2918,9 +2903,9 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
bool IsKeyDecl) {
auto *DPattern = D->getTemplatedDecl();
auto *ExistingPattern = Existing->getTemplatedDecl();
- RedeclarableResult Result(/*MergeWith*/ ExistingPattern,
- DPattern->getCanonicalDecl()->getGlobalID(),
- IsKeyDecl);
+ RedeclarableResult Result(
+ /*MergeWith*/ ExistingPattern,
+ DPattern->getCanonicalDecl()->getGlobalID(), IsKeyDecl);
if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
// Merge with any existing definition.
@@ -2970,13 +2955,6 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
ExistingCanon->Used |= D->Used;
D->Used = false;
- // When we merge a namespace, update its pointer to the first namespace.
- // 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->AnonOrFirstNamespaceAndFlags.setPointer(
- assert_cast<NamespaceDecl *>(ExistingCanon));
-
// When we merge a template, merge its pattern.
if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
mergeTemplatePattern(
@@ -3075,14 +3053,14 @@ void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
Expr *Init = Record.readExpr();
auto IK = static_cast<OMPDeclareReductionInitKind>(Record.readInt());
D->setInitializer(Init, IK);
- D->PrevDeclInScope = readDeclID();
+ D->PrevDeclInScope = readDeclID().getRawValue();
}
void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
Record.readOMPChildren(D->Data);
VisitValueDecl(D);
D->VarName = Record.readDeclarationName();
- D->PrevDeclInScope = readDeclID();
+ D->PrevDeclInScope = readDeclID().getRawValue();
}
void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
@@ -3136,9 +3114,7 @@ public:
OMPTraitInfo *readOMPTraitInfo() { return Reader.readOMPTraitInfo(); }
- template <typename T> T *GetLocalDeclAs(uint32_t LocalID) {
- return Reader.GetLocalDeclAs<T>(LocalID);
- }
+ template <typename T> T *readDeclAs() { return Reader.readDeclAs<T>(); }
};
}
@@ -3205,7 +3181,7 @@ inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) {
/// This routine should return true for anything that might affect
/// code generation, e.g., inline function definitions, Objective-C
/// declarations with metadata, etc.
-static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
+bool ASTReader::isConsumerInterestedIn(Decl *D) {
// An ObjCMethodDecl is never considered as "interesting" because its
// implementation container always is.
@@ -3214,7 +3190,7 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
if (isPartOfPerModuleInitializer(D)) {
auto *M = D->getImportedOwningModule();
if (M && M->Kind == Module::ModuleMapModule &&
- Ctx.DeclMustBeEmitted(D))
+ getContext().DeclMustBeEmitted(D))
return false;
}
@@ -3229,7 +3205,7 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
(Var->isThisDeclarationADefinition() == VarDecl::Definition ||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var));
if (const auto *Func = dyn_cast<FunctionDecl>(D))
- return Func->doesThisDeclarationHaveABody() || HasBody;
+ return Func->doesThisDeclarationHaveABody() || PendingBodies.count(D);
if (auto *ES = D->getASTContext().getExternalSource())
if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
@@ -3239,14 +3215,13 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
}
/// Get the correct cursor and offset for loading a declaration.
-ASTReader::RecordLocation
-ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) {
- GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- ModuleFile *M = I->second;
- const DeclOffset &DOffs =
- M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS];
- Loc = TranslateSourceLocation(*M, DOffs.getLocation());
+ASTReader::RecordLocation ASTReader::DeclCursorForID(GlobalDeclID ID,
+ SourceLocation &Loc) {
+ ModuleFile *M = getOwningModuleFile(ID);
+ assert(M);
+ unsigned LocalDeclIndex = ID.getLocalDeclIndex();
+ const DeclOffset &DOffs = M->DeclOffsets[LocalDeclIndex];
+ Loc = ReadSourceLocation(*M, DOffs.getRawLoc());
return RecordLocation(M, DOffs.getBitOffset(M->DeclsBlockStartOffset));
}
@@ -3292,7 +3267,7 @@ ASTDeclReader::getOrFakePrimaryClassDefinition(ASTReader &Reader,
DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
DeclContext *DC) {
if (auto *ND = dyn_cast<NamespaceDecl>(DC))
- return ND->getOriginalNamespace();
+ return ND->getFirstDecl();
if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
return getOrFakePrimaryClassDefinition(Reader, RD);
@@ -3301,16 +3276,15 @@ DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
return RD->getDefinition();
if (auto *ED = dyn_cast<EnumDecl>(DC))
- return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
- : nullptr;
+ return ED->getDefinition();
if (auto *OID = dyn_cast<ObjCInterfaceDecl>(DC))
return OID->getDefinition();
- // We can see the TU here only if we have no Sema object. In that case,
- // there's no TU scope to look in, so using the DC alone is sufficient.
+ // We can see the TU here only if we have no Sema object. It is possible
+ // we're in clang-repl so we still need to get the primary context.
if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
- return TU;
+ return TU->getPrimaryContext();
return nullptr;
}
@@ -3526,7 +3500,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
// same template specialization into the same CXXRecordDecl.
auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext());
if (MergedDCIt != Reader.MergedDeclContexts.end() &&
- !D->shouldSkipCheckingODR() && MergedDCIt->second == D->getDeclContext())
+ !shouldSkipCheckingODR(D) && MergedDCIt->second == D->getDeclContext())
Reader.PendingOdrMergeChecks.push_back(D);
return FindExistingResult(Reader, D, /*Existing=*/nullptr,
@@ -3723,6 +3697,23 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
#include "clang/AST/DeclNodes.inc"
}
+ // [basic.link]/p10:
+ // If two declarations of an entity are attached to different modules,
+ // the program is ill-formed;
+ //
+ // FIXME: Get rid of the enumeration of decl types once we have an appropriate
+ // abstract for decls of an entity. e.g., the namespace decl and using decl
+ // doesn't introduce an entity.
+ if (Module *M = Previous->getOwningModule();
+ M && M->isNamedModule() &&
+ isa<VarDecl, FunctionDecl, TagDecl, RedeclarableTemplateDecl>(Previous) &&
+ !Reader.getContext().isInSameModule(M, D->getOwningModule())) {
+ Reader.Diag(Previous->getLocation(),
+ diag::err_multiple_decl_in_different_modules)
+ << cast<NamedDecl>(Previous) << M->Name;
+ Reader.Diag(D->getLocation(), diag::note_also_found);
+ }
+
// If the declaration was visible in one module, a redeclaration of it in
// another module remains visible even if it wouldn't be visible by itself.
//
@@ -3788,8 +3779,7 @@ void ASTReader::markIncompleteDeclChain(Decl *D) {
}
/// Read the declaration at the given offset from the AST file.
-Decl *ASTReader::ReadDeclRecord(DeclID ID) {
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
SourceLocation DeclLoc;
RecordLocation Loc = DeclCursorForID(ID, DeclLoc);
llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
@@ -3823,6 +3813,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
llvm::report_fatal_error(
Twine("ASTReader::readDeclRecord failed reading decl code: ") +
toString(MaybeDeclCode.takeError()));
+
switch ((DeclCode)MaybeDeclCode.get()) {
case DECL_CONTEXT_LEXICAL:
case DECL_CONTEXT_VISIBLE:
@@ -3949,9 +3940,8 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
}
case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: {
bool HasTypeConstraint = Record.readInt();
- D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID,
- Record.readInt(),
- HasTypeConstraint);
+ D = NonTypeTemplateParmDecl::CreateDeserialized(
+ Context, ID, Record.readInt(), HasTypeConstraint);
break;
}
case DECL_TEMPLATE_TEMPLATE_PARM:
@@ -4120,17 +4110,29 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
}
assert(D && "Unknown declaration reading AST file");
- LoadedDecl(Index, D);
+ LoadedDecl(translateGlobalDeclIDToIndex(ID), D);
// Set the DeclContext before doing any deserialization, to make sure internal
// calls to Decl::getASTContext() by Decl's methods will find the
// TranslationUnitDecl without crashing.
D->setDeclContext(Context.getTranslationUnitDecl());
- Reader.Visit(D);
+
+ // Reading some declarations can result in deep recursion.
+ clang::runWithSufficientStackSpace([&] { warnStackExhausted(DeclLoc); },
+ [&] { Reader.Visit(D); });
// If this declaration is also a declaration context, get the
// offsets for its tables of lexical and visible declarations.
if (auto *DC = dyn_cast<DeclContext>(D)) {
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
+
+ // Get the lexical and visible block for the delayed namespace.
+ // It is sufficient to judge if ID is in DelayedNamespaceOffsetMap.
+ // But it may be more efficient to filter the other cases.
+ if (!Offsets.first && !Offsets.second && isa<NamespaceDecl>(D))
+ if (auto Iter = DelayedNamespaceOffsetMap.find(ID);
+ Iter != DelayedNamespaceOffsetMap.end())
+ Offsets = Iter->second;
+
if (Offsets.first &&
ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC))
return nullptr;
@@ -4156,8 +4158,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// AST consumer might need to know about, queue it.
// We don't pass it to the consumer immediately because we may be in recursive
// loading, and some declarations may still be initializing.
- PotentiallyInterestingDecls.push_back(
- InterestingDecl(D, Reader.hasPendingBody()));
+ PotentiallyInterestingDecls.push_back(D);
return D;
}
@@ -4178,24 +4179,48 @@ void ASTReader::PassInterestingDeclsToConsumer() {
GetDecl(ID);
EagerlyDeserializedDecls.clear();
- while (!PotentiallyInterestingDecls.empty()) {
- InterestingDecl D = PotentiallyInterestingDecls.front();
- PotentiallyInterestingDecls.pop_front();
- if (isConsumerInterestedIn(getContext(), D.getDecl(), D.hasPendingBody()))
- PassInterestingDeclToConsumer(D.getDecl());
+ auto ConsumingPotentialInterestingDecls = [this]() {
+ while (!PotentiallyInterestingDecls.empty()) {
+ Decl *D = PotentiallyInterestingDecls.front();
+ PotentiallyInterestingDecls.pop_front();
+ if (isConsumerInterestedIn(D))
+ PassInterestingDeclToConsumer(D);
+ }
+ };
+ std::deque<Decl *> MaybeInterestingDecls =
+ std::move(PotentiallyInterestingDecls);
+ PotentiallyInterestingDecls.clear();
+ assert(PotentiallyInterestingDecls.empty());
+ while (!MaybeInterestingDecls.empty()) {
+ Decl *D = MaybeInterestingDecls.front();
+ MaybeInterestingDecls.pop_front();
+ // Since we load the variable's initializers lazily, it'd be problematic
+ // if the initializers dependent on each other. So here we try to load the
+ // initializers of static variables to make sure they are passed to code
+ // generator by order. If we read anything interesting, we would consume
+ // that before emitting the current declaration.
+ if (auto *VD = dyn_cast<VarDecl>(D);
+ VD && VD->isFileVarDecl() && !VD->isExternallyVisible())
+ VD->getInit();
+ ConsumingPotentialInterestingDecls();
+ if (isConsumerInterestedIn(D))
+ PassInterestingDeclToConsumer(D);
}
+
+ // If we add any new potential interesting decl in the last call, consume it.
+ ConsumingPotentialInterestingDecls();
}
void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
// The declaration may have been modified by files later in the chain.
// If this is the case, read the record containing the updates from each file
// and pass it to ASTDeclReader to make the modifications.
- serialization::GlobalDeclID ID = Record.ID;
+ GlobalDeclID ID = Record.ID;
Decl *D = Record.D;
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
- SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
+ SmallVector<GlobalDeclID, 8> PendingLazySpecializationIDs;
if (UpdI != DeclUpdateOffsets.end()) {
auto UpdateOffsets = std::move(UpdI->second);
@@ -4205,8 +4230,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
// the declaration, then we know it was interesting and we skip the call
// to isConsumerInterestedIn because it is unsafe to call in the
// current ASTReader state.
- bool WasInteresting =
- Record.JustLoaded || isConsumerInterestedIn(getContext(), D, false);
+ bool WasInteresting = Record.JustLoaded || isConsumerInterestedIn(D);
for (auto &FileAndOffset : UpdateOffsets) {
ModuleFile *F = FileAndOffset.first;
uint64_t Offset = FileAndOffset.second;
@@ -4238,10 +4262,8 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
// We might have made this declaration interesting. If so, remember that
// we need to hand it off to the consumer.
- if (!WasInteresting &&
- isConsumerInterestedIn(getContext(), D, Reader.hasPendingBody())) {
- PotentiallyInterestingDecls.push_back(
- InterestingDecl(D, Reader.hasPendingBody()));
+ if (!WasInteresting && isConsumerInterestedIn(D)) {
+ PotentiallyInterestingDecls.push_back(D);
WasInteresting = true;
}
}
@@ -4318,7 +4340,8 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
// we should instead generate one loop per kind and dispatch up-front?
Decl *MostRecent = FirstLocal;
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
- auto *D = GetLocalDecl(*M, Record[N - I - 1]);
+ unsigned Idx = N - I - 1;
+ auto *D = ReadDecl(*M, Record, Idx);
ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
MostRecent = D;
}
@@ -4335,7 +4358,7 @@ namespace {
llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized;
ObjCCategoryDecl *Tail = nullptr;
llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap;
- serialization::GlobalDeclID InterfaceID;
+ GlobalDeclID InterfaceID;
unsigned PreviousGeneration;
void add(ObjCCategoryDecl *Cat) {
@@ -4377,11 +4400,10 @@ namespace {
}
public:
- ObjCCategoriesVisitor(ASTReader &Reader,
- ObjCInterfaceDecl *Interface,
- llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized,
- serialization::GlobalDeclID InterfaceID,
- unsigned PreviousGeneration)
+ ObjCCategoriesVisitor(
+ ASTReader &Reader, ObjCInterfaceDecl *Interface,
+ llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized,
+ GlobalDeclID InterfaceID, unsigned PreviousGeneration)
: Reader(Reader), Interface(Interface), Deserialized(Deserialized),
InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) {
// Populate the name -> category map with the set of known categories.
@@ -4403,8 +4425,9 @@ namespace {
// Map global ID of the definition down to the local ID used in this
// module file. If there is no such mapping, we'll find nothing here
// (or in any module it imports).
- DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID);
- if (!LocalID)
+ LocalDeclID LocalID =
+ Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID);
+ if (LocalID.isInvalid())
return true;
// Perform a binary search to find the local redeclarations for this
@@ -4415,7 +4438,7 @@ namespace {
M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap,
Compare);
if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap ||
- Result->DefinitionID != LocalID) {
+ LocalID != Result->getDefinitionID()) {
// We didn't find anything. If the class definition is in this module
// file, then the module files it depends on cannot have any categories,
// so suppress further lookup.
@@ -4427,16 +4450,14 @@ namespace {
unsigned N = M.ObjCCategories[Offset];
M.ObjCCategories[Offset++] = 0; // Don't try to deserialize again
for (unsigned I = 0; I != N; ++I)
- add(cast_or_null<ObjCCategoryDecl>(
- Reader.GetLocalDecl(M, M.ObjCCategories[Offset++])));
+ add(Reader.ReadDeclAs<ObjCCategoryDecl>(M, M.ObjCCategories, Offset));
return true;
}
};
} // namespace
-void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,
- ObjCInterfaceDecl *D,
+void ASTReader::loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D,
unsigned PreviousGeneration) {
ObjCCategoriesVisitor Visitor(*this, D, CategoriesDeserialized, ID,
PreviousGeneration);
@@ -4464,8 +4485,9 @@ static void forAllLaterRedecls(DeclT *D, Fn F) {
}
}
-void ASTDeclReader::UpdateDecl(Decl *D,
- llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) {
+void ASTDeclReader::UpdateDecl(
+ Decl *D,
+ llvm::SmallVectorImpl<GlobalDeclID> &PendingLazySpecializationIDs) {
while (Record.getIdx() < Record.size()) {
switch ((DeclUpdateKind)Record.readInt()) {
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h b/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h
index 25a46ddabcb7..536b19f91691 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderInternals.h
@@ -49,15 +49,15 @@ public:
static const int MaxTables = 4;
/// The lookup result is a list of global declaration IDs.
- using data_type = SmallVector<DeclID, 4>;
+ using data_type = SmallVector<GlobalDeclID, 4>;
struct data_type_builder {
data_type &Data;
- llvm::DenseSet<DeclID> Found;
+ llvm::DenseSet<GlobalDeclID> Found;
data_type_builder(data_type &D) : Data(D) {}
- void insert(DeclID ID) {
+ void insert(GlobalDeclID ID) {
// Just use a linear scan unless we have more than a few IDs.
if (Found.empty() && !Data.empty()) {
if (Data.size() <= 4) {
@@ -108,7 +108,7 @@ public:
static void MergeDataInto(const data_type &From, data_type_builder &To) {
To.Data.reserve(To.Data.size() + From.size());
- for (DeclID ID : From)
+ for (GlobalDeclID ID : From)
To.insert(ID);
}
@@ -175,7 +175,7 @@ public:
const unsigned char* d,
unsigned DataLen);
- IdentID ReadIdentifierID(const unsigned char *d);
+ IdentifierID ReadIdentifierID(const unsigned char *d);
ASTReader &getReader() const { return Reader; }
};
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
index 85ecfa1a1a0b..c1361efd8c5f 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -790,19 +790,19 @@ readConstraintSatisfaction(ASTRecordReader &Record) {
ConstraintSatisfaction Satisfaction;
Satisfaction.IsSatisfied = Record.readInt();
Satisfaction.ContainsErrors = Record.readInt();
+ const ASTContext &C = Record.getContext();
if (!Satisfaction.IsSatisfied) {
unsigned NumDetailRecords = Record.readInt();
for (unsigned i = 0; i != NumDetailRecords; ++i) {
- Expr *ConstraintExpr = Record.readExpr();
if (/* IsDiagnostic */Record.readInt()) {
SourceLocation DiagLocation = Record.readSourceLocation();
- std::string DiagMessage = Record.readString();
+ StringRef DiagMessage = C.backupStr(Record.readString());
+
Satisfaction.Details.emplace_back(
- ConstraintExpr, new (Record.getContext())
- ConstraintSatisfaction::SubstitutionDiagnostic{
- DiagLocation, DiagMessage});
+ new (C) ConstraintSatisfaction::SubstitutionDiagnostic(
+ DiagLocation, DiagMessage));
} else
- Satisfaction.Details.emplace_back(ConstraintExpr, Record.readExpr());
+ Satisfaction.Details.emplace_back(Record.readExpr());
}
}
return Satisfaction;
@@ -821,9 +821,11 @@ void ASTStmtReader::VisitConceptSpecializationExpr(
static concepts::Requirement::SubstitutionDiagnostic *
readSubstitutionDiagnostic(ASTRecordReader &Record) {
- std::string SubstitutedEntity = Record.readString();
+ const ASTContext &C = Record.getContext();
+ StringRef SubstitutedEntity = C.backupStr(Record.readString());
SourceLocation DiagLoc = Record.readSourceLocation();
- std::string DiagMessage = Record.readString();
+ StringRef DiagMessage = C.backupStr(Record.readString());
+
return new (Record.getContext())
concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc,
DiagMessage};
@@ -908,26 +910,21 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
std::move(*Req));
} break;
case concepts::Requirement::RK_Nested: {
+ ASTContext &C = Record.getContext();
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(
- Record.getContext(),
- StringRef(InvalidConstraintBuf, InvalidConstraint.size()),
+ StringRef InvalidConstraint = C.backupStr(Record.readString());
+ R = new (C) concepts::NestedRequirement(
+ Record.getContext(), InvalidConstraint,
readConstraintSatisfaction(Record));
break;
}
Expr *E = Record.readExpr();
if (E->isInstantiationDependent())
- R = new (Record.getContext()) concepts::NestedRequirement(E);
+ R = new (C) concepts::NestedRequirement(E);
else
- R = new (Record.getContext())
- concepts::NestedRequirement(Record.getContext(), E,
- readConstraintSatisfaction(Record));
+ R = new (C) concepts::NestedRequirement(
+ C, E, readConstraintSatisfaction(Record));
} break;
}
if (!R)
@@ -956,14 +953,22 @@ void ASTStmtReader::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
E->setRBracketLoc(readSourceLocation());
}
-void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
+void ASTStmtReader::VisitArraySectionExpr(ArraySectionExpr *E) {
VisitExpr(E);
+ E->ASType = Record.readEnum<ArraySectionExpr::ArraySectionType>();
+
E->setBase(Record.readSubExpr());
E->setLowerBound(Record.readSubExpr());
E->setLength(Record.readSubExpr());
- E->setStride(Record.readSubExpr());
+
+ if (E->isOMPArraySection())
+ E->setStride(Record.readSubExpr());
+
E->setColonLocFirst(readSourceLocation());
- E->setColonLocSecond(readSourceLocation());
+
+ if (E->isOMPArraySection())
+ E->setColonLocSecond(readSourceLocation());
+
E->setRBracketLoc(readSourceLocation());
}
@@ -1047,30 +1052,22 @@ void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName());
E->MemberLoc = Record.readSourceLocation();
E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit();
- E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl;
+ E->MemberExprBits.HasQualifier = HasQualifier;
+ E->MemberExprBits.HasFoundDecl = HasFoundDecl;
E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo;
E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit();
E->MemberExprBits.NonOdrUseReason =
CurrentUnpackingBits->getNextBits(/*Width=*/2);
E->MemberExprBits.OperatorLoc = Record.readSourceLocation();
- if (HasQualifier || HasFoundDecl) {
- DeclAccessPair FoundDecl;
- if (HasFoundDecl) {
- auto *FoundD = Record.readDeclAs<NamedDecl>();
- auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2);
- FoundDecl = DeclAccessPair::make(FoundD, AS);
- } else {
- FoundDecl = DeclAccessPair::make(E->MemberDecl,
- E->MemberDecl->getAccess());
- }
- E->getTrailingObjects<MemberExprNameQualifier>()->FoundDecl = FoundDecl;
+ if (HasQualifier)
+ new (E->getTrailingObjects<NestedNameSpecifierLoc>())
+ NestedNameSpecifierLoc(Record.readNestedNameSpecifierLoc());
- NestedNameSpecifierLoc QualifierLoc;
- if (HasQualifier)
- QualifierLoc = Record.readNestedNameSpecifierLoc();
- E->getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc =
- QualifierLoc;
+ if (HasFoundDecl) {
+ auto *FoundD = Record.readDeclAs<NamedDecl>();
+ auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2);
+ *E->getTrailingObjects<DeclAccessPair>() = DeclAccessPair::make(FoundD, AS);
}
if (HasTemplateInfo)
@@ -1323,6 +1320,16 @@ void ASTStmtReader::VisitSourceLocExpr(SourceLocExpr *E) {
E->SourceLocExprBits.Kind = Record.readInt();
}
+void ASTStmtReader::VisitEmbedExpr(EmbedExpr *E) {
+ VisitExpr(E);
+ E->EmbedKeywordLoc = readSourceLocation();
+ EmbedDataStorage *Data = new (Record.getContext()) EmbedDataStorage;
+ Data->BinaryData = cast<StringLiteral>(Record.readSubStmt());
+ E->Data = Data;
+ E->Begin = Record.readInt();
+ E->NumOfElements = Record.readInt();
+}
+
void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
VisitExpr(E);
E->setAmpAmpLoc(readSourceLocation());
@@ -1849,6 +1856,7 @@ void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
VisitExpr(E);
E->setLocation(readSourceLocation());
E->setImplicit(Record.readInt());
+ E->setCapturedByCopyInLambdaWithExplicitObjectParameter(Record.readInt());
}
void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
@@ -2103,7 +2111,6 @@ void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E);
E->UnresolvedLookupExprBits.RequiresADL = CurrentUnpackingBits->getNextBit();
- E->UnresolvedLookupExprBits.Overloaded = CurrentUnpackingBits->getNextBit();
E->NamingClass = readDeclAs<CXXRecordDecl>();
}
@@ -2174,6 +2181,19 @@ void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
}
}
+void ASTStmtReader::VisitPackIndexingExpr(PackIndexingExpr *E) {
+ VisitExpr(E);
+ E->TransformedExpressions = Record.readInt();
+ E->ExpandedToEmptyPack = Record.readInt();
+ E->EllipsisLoc = readSourceLocation();
+ E->RSquareLoc = readSourceLocation();
+ E->SubExprs[0] = Record.readStmt();
+ E->SubExprs[1] = Record.readStmt();
+ auto **Exprs = E->getTrailingObjects<Expr *>();
+ for (unsigned I = 0; I < E->TransformedExpressions; ++I)
+ Exprs[I] = Record.readExpr();
+}
+
void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
@@ -2415,6 +2435,14 @@ void ASTStmtReader::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
VisitOMPLoopTransformationDirective(D);
}
+void ASTStmtReader::VisitOMPReverseDirective(OMPReverseDirective *D) {
+ VisitOMPLoopTransformationDirective(D);
+}
+
+void ASTStmtReader::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) {
+ VisitOMPLoopTransformationDirective(D);
+}
+
void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
VisitOMPLoopDirective(D);
D->setHasCancel(Record.readBool());
@@ -2764,6 +2792,7 @@ void ASTStmtReader::VisitOMPTeamsGenericLoopDirective(
void ASTStmtReader::VisitOMPTargetTeamsGenericLoopDirective(
OMPTargetTeamsGenericLoopDirective *D) {
VisitOMPLoopDirective(D);
+ D->setCanBeParallelFor(Record.readBool());
}
void ASTStmtReader::VisitOMPParallelGenericLoopDirective(
@@ -2777,6 +2806,34 @@ void ASTStmtReader::VisitOMPTargetParallelGenericLoopDirective(
}
//===----------------------------------------------------------------------===//
+// OpenACC Constructs/Directives.
+//===----------------------------------------------------------------------===//
+void ASTStmtReader::VisitOpenACCConstructStmt(OpenACCConstructStmt *S) {
+ (void)Record.readInt();
+ S->Kind = Record.readEnum<OpenACCDirectiveKind>();
+ S->Range = Record.readSourceRange();
+ S->DirectiveLoc = Record.readSourceLocation();
+ Record.readOpenACCClauseList(S->Clauses);
+}
+
+void ASTStmtReader::VisitOpenACCAssociatedStmtConstruct(
+ OpenACCAssociatedStmtConstruct *S) {
+ VisitOpenACCConstructStmt(S);
+ S->setAssociatedStmt(Record.readSubStmt());
+}
+
+void ASTStmtReader::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCAssociatedStmtConstruct(S);
+ S->findAndSetChildLoops();
+}
+
+void ASTStmtReader::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCAssociatedStmtConstruct(S);
+}
+
+//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
@@ -3064,8 +3121,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) MatrixSubscriptExpr(Empty);
break;
- case EXPR_OMP_ARRAY_SECTION:
- S = new (Context) OMPArraySectionExpr(Empty);
+ case EXPR_ARRAY_SECTION:
+ S = new (Context) ArraySectionExpr(Empty);
break;
case EXPR_OMP_ARRAY_SHAPING:
@@ -3191,6 +3248,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) SourceLocExpr(Empty);
break;
+ case EXPR_BUILTIN_PP_EMBED:
+ S = new (Context) EmbedExpr(Empty);
+ break;
+
case EXPR_ADDR_LABEL:
S = new (Context) AddrLabelExpr(Empty);
break;
@@ -3401,6 +3462,22 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
}
+ case STMT_OMP_REVERSE_DIRECTIVE: {
+ assert(Record[ASTStmtReader::NumStmtFields] == 1 &&
+ "Reverse directive accepts only a single loop");
+ assert(Record[ASTStmtReader::NumStmtFields + 1] == 0 &&
+ "Reverse directive has no clauses");
+ S = OMPReverseDirective::CreateEmpty(Context);
+ break;
+ }
+
+ case STMT_OMP_INTERCHANGE_DIRECTIVE: {
+ unsigned NumLoops = Record[ASTStmtReader::NumStmtFields];
+ unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1];
+ S = OMPInterchangeDirective::CreateEmpty(Context, NumClauses, NumLoops);
+ break;
+ }
+
case STMT_OMP_FOR_DIRECTIVE: {
unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields];
unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1];
@@ -4102,6 +4179,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
/*NumPartialArgs=*/Record[ASTStmtReader::NumExprFields]);
break;
+ case EXPR_PACK_INDEXING:
+ S = PackIndexingExpr::CreateDeserialized(
+ Context,
+ /*TransformedExprs=*/Record[ASTStmtReader::NumExprFields]);
+ break;
+
case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM:
S = new (Context) SubstNonTypeTemplateParmExpr(Empty);
break;
@@ -4188,7 +4271,16 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) ConceptSpecializationExpr(Empty);
break;
}
-
+ case STMT_OPENACC_COMPUTE_CONSTRUCT: {
+ unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+ S = OpenACCComputeConstruct::CreateEmpty(Context, NumClauses);
+ break;
+ }
+ case STMT_OPENACC_LOOP_CONSTRUCT: {
+ unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+ S = OpenACCLoopConstruct::CreateEmpty(Context, NumClauses);
+ break;
+ }
case EXPR_REQUIRES:
unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields];
unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1];
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
index 378a1f86bd53..c78d8943d6d9 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
@@ -29,6 +29,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenACCClause.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateName.h"
@@ -44,6 +45,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/OpenCLOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
@@ -63,6 +65,8 @@
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaCUDA.h"
+#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/Weak.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTReader.h"
@@ -161,79 +165,108 @@ static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) {
namespace {
-std::set<const FileEntry *> GetAffectingModuleMaps(const Preprocessor &PP,
- Module *RootModule) {
- SmallVector<const Module *> ModulesToProcess{RootModule};
+std::optional<std::set<const FileEntry *>>
+GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
+ if (!PP.getHeaderSearchInfo()
+ .getHeaderSearchOpts()
+ .ModulesPruneNonAffectingModuleMaps)
+ return std::nullopt;
const HeaderSearch &HS = PP.getHeaderSearchInfo();
-
- SmallVector<OptionalFileEntryRef, 16> FilesByUID;
- HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
-
- if (FilesByUID.size() > HS.header_file_size())
- FilesByUID.resize(HS.header_file_size());
-
- for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
- OptionalFileEntryRef File = FilesByUID[UID];
- if (!File)
- continue;
-
- const HeaderFileInfo *HFI =
- HS.getExistingFileInfo(*File, /*WantExternal*/ false);
- if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
- continue;
-
- for (const auto &KH : HS.findResolvedModulesForHeader(*File)) {
- if (!KH.getModule())
- continue;
- ModulesToProcess.push_back(KH.getModule());
- }
- }
-
const ModuleMap &MM = HS.getModuleMap();
- SourceManager &SourceMgr = PP.getSourceManager();
- std::set<const FileEntry *> ModuleMaps{};
- auto CollectIncludingModuleMaps = [&](FileEntryRef F) {
- if (!ModuleMaps.insert(F).second)
+ std::set<const FileEntry *> ModuleMaps;
+ std::set<const Module *> ProcessedModules;
+ auto CollectModuleMapsForHierarchy = [&](const Module *M) {
+ M = M->getTopLevelModule();
+
+ if (!ProcessedModules.insert(M).second)
return;
- FileID FID = SourceMgr.translateFile(F);
- SourceLocation Loc = SourceMgr.getIncludeLoc(FID);
- // The include location of inferred module maps can point into the header
- // file that triggered the inferring. Cut off the walk if that's the case.
- while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {
- FID = SourceMgr.getFileID(Loc);
- if (!ModuleMaps.insert(*SourceMgr.getFileEntryRefForID(FID)).second)
- break;
- Loc = SourceMgr.getIncludeLoc(FID);
- }
- };
- std::set<const Module *> ProcessedModules;
- auto CollectIncludingMapsFromAncestors = [&](const Module *M) {
- for (const Module *Mod = M; Mod; Mod = Mod->Parent) {
- if (!ProcessedModules.insert(Mod).second)
- break;
+ std::queue<const Module *> Q;
+ Q.push(M);
+ while (!Q.empty()) {
+ const Module *Mod = Q.front();
+ Q.pop();
+
// The containing module map is affecting, because it's being pointed
// into by Module::DefinitionLoc.
- if (auto ModuleMapFile = MM.getContainingModuleMapFile(Mod))
- CollectIncludingModuleMaps(*ModuleMapFile);
- // For inferred modules, the module map that allowed inferring is not in
- // the include chain of the virtual containing module map file. It did
- // affect the compilation, though.
- if (auto ModuleMapFile = MM.getModuleMapFileForUniquing(Mod))
- CollectIncludingModuleMaps(*ModuleMapFile);
+ if (auto FE = MM.getContainingModuleMapFile(Mod))
+ ModuleMaps.insert(*FE);
+ // For inferred modules, the module map that allowed inferring is not
+ // related to the virtual containing module map file. It did affect the
+ // compilation, though.
+ if (auto FE = MM.getModuleMapFileForUniquing(Mod))
+ ModuleMaps.insert(*FE);
+
+ for (auto *SubM : Mod->submodules())
+ Q.push(SubM);
}
};
- for (const Module *CurrentModule : ModulesToProcess) {
- CollectIncludingMapsFromAncestors(CurrentModule);
+ // Handle all the affecting modules referenced from the root module.
+
+ CollectModuleMapsForHierarchy(RootModule);
+
+ std::queue<const Module *> Q;
+ Q.push(RootModule);
+ while (!Q.empty()) {
+ const Module *CurrentModule = Q.front();
+ Q.pop();
+
for (const Module *ImportedModule : CurrentModule->Imports)
- CollectIncludingMapsFromAncestors(ImportedModule);
+ CollectModuleMapsForHierarchy(ImportedModule);
for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses)
- CollectIncludingMapsFromAncestors(UndeclaredModule);
+ CollectModuleMapsForHierarchy(UndeclaredModule);
+
+ for (auto *M : CurrentModule->submodules())
+ Q.push(M);
}
+ // Handle textually-included headers that belong to other modules.
+
+ SmallVector<OptionalFileEntryRef, 16> FilesByUID;
+ HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
+
+ if (FilesByUID.size() > HS.header_file_size())
+ FilesByUID.resize(HS.header_file_size());
+
+ for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
+ OptionalFileEntryRef File = FilesByUID[UID];
+ if (!File)
+ continue;
+
+ const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(*File);
+ if (!HFI)
+ continue; // We have no information on this being a header file.
+ if (!HFI->isCompilingModuleHeader && HFI->isModuleHeader)
+ continue; // Modular header, handled in the above module-based loop.
+ if (!HFI->isCompilingModuleHeader && !HFI->IsLocallyIncluded)
+ continue; // Non-modular header not included locally is not affecting.
+
+ for (const auto &KH : HS.findResolvedModulesForHeader(*File))
+ if (const Module *M = KH.getModule())
+ CollectModuleMapsForHierarchy(M);
+ }
+
+ // FIXME: This algorithm is not correct for module map hierarchies where
+ // module map file defining a (sub)module of a top-level module X includes
+ // a module map file that defines a (sub)module of another top-level module Y.
+ // Whenever X is affecting and Y is not, "replaying" this PCM file will fail
+ // when parsing module map files for X due to not knowing about the `extern`
+ // module map for Y.
+ //
+ // We don't have a good way to fix it here. We could mark all children of
+ // affecting module map files as being affecting as well, but that's
+ // expensive. SourceManager does not model the edge from parent to child
+ // SLocEntries, so instead, we would need to iterate over leaf module map
+ // files, walk up their include hierarchy and check whether we arrive at an
+ // affecting module map.
+ //
+ // Instead of complicating and slowing down this function, we should probably
+ // just ban module map hierarchies where module map defining a (sub)module X
+ // includes a module map defining a module that's not a submodule of X.
+
return ModuleMaps;
}
@@ -318,6 +351,10 @@ void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
// nothing to do
}
+void TypeLocWriter::VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) {
+ // nothing to do
+}
+
void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
addSourceLocation(TL.getCaretLoc());
}
@@ -482,6 +519,10 @@ void ASTRecordWriter::AddConceptReference(const ConceptReference *CR) {
AddASTTemplateArgumentListInfo(CR->getTemplateArgsAsWritten());
}
+void TypeLocWriter::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
+ addSourceLocation(TL.getEllipsisLoc());
+}
+
void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
addSourceLocation(TL.getNameLoc());
auto *CR = TL.getConceptReference();
@@ -510,6 +551,10 @@ void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
Record.AddAttr(TL.getAttr());
}
+void TypeLocWriter::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) {
+ // Nothing to do
+}
+
void TypeLocWriter::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
// Nothing to do.
}
@@ -784,6 +829,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
RECORD(EXPR_ARRAY_TYPE_TRAIT);
RECORD(EXPR_PACK_EXPANSION);
RECORD(EXPR_SIZEOF_PACK);
+ RECORD(EXPR_PACK_INDEXING);
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
RECORD(EXPR_FUNCTION_PARM_PACK);
@@ -850,6 +896,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(WEAK_UNDECLARED_IDENTIFIERS);
RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
RECORD(UPDATE_VISIBLE);
+ RECORD(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD);
RECORD(DECL_UPDATE_OFFSETS);
RECORD(DECL_UPDATES);
RECORD(CUDA_SPECIAL_DECL_REFS);
@@ -879,6 +926,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(PP_CONDITIONAL_STACK);
RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS);
RECORD(PP_ASSUME_NONNULL_LOC);
+ RECORD(PP_UNSAFE_BUFFER_USAGE);
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
@@ -1002,6 +1050,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DECL_UNRESOLVED_USING_VALUE);
RECORD(DECL_UNRESOLVED_USING_TYPENAME);
RECORD(DECL_LINKAGE_SPEC);
+ RECORD(DECL_EXPORT);
RECORD(DECL_CXX_RECORD);
RECORD(DECL_CXX_METHOD);
RECORD(DECL_CXX_CONSTRUCTOR);
@@ -1142,26 +1191,72 @@ ASTWriter::createSignature() const {
return std::make_pair(ASTBlockHash, Signature);
}
+ASTFileSignature ASTWriter::createSignatureForNamedModule() const {
+ llvm::SHA1 Hasher;
+ Hasher.update(StringRef(Buffer.data(), Buffer.size()));
+
+ assert(WritingModule);
+ assert(WritingModule->isNamedModule());
+
+ // We need to combine all the export imported modules no matter
+ // we used it or not.
+ for (auto [ExportImported, _] : WritingModule->Exports)
+ Hasher.update(ExportImported->Signature);
+
+ // We combine all the used modules to make sure the signature is precise.
+ // Consider the case like:
+ //
+ // // a.cppm
+ // export module a;
+ // export inline int a() { ... }
+ //
+ // // b.cppm
+ // export module b;
+ // import a;
+ // export inline int b() { return a(); }
+ //
+ // Since both `a()` and `b()` are inline, we need to make sure the BMI of
+ // `b.pcm` will change after the implementation of `a()` changes. We can't
+ // get that naturally since we won't record the body of `a()` during the
+ // writing process. We can't reuse ODRHash here since ODRHash won't calculate
+ // the called function recursively. So ODRHash will be problematic if `a()`
+ // calls other inline functions.
+ //
+ // Probably we can solve this by a new hash mechanism. But the safety and
+ // efficiency may a problem too. Here we just combine the hash value of the
+ // used modules conservatively.
+ for (Module *M : TouchedTopLevelModules)
+ Hasher.update(M->Signature);
+
+ return ASTFileSignature::create(Hasher.result());
+}
+
+static void BackpatchSignatureAt(llvm::BitstreamWriter &Stream,
+ const ASTFileSignature &S, uint64_t BitNo) {
+ for (uint8_t Byte : S) {
+ Stream.BackpatchByte(BitNo, Byte);
+ BitNo += 8;
+ }
+}
+
ASTFileSignature ASTWriter::backpatchSignature() {
+ if (isWritingStdCXXNamedModules()) {
+ ASTFileSignature Signature = createSignatureForNamedModule();
+ BackpatchSignatureAt(Stream, Signature, SignatureOffset);
+ return Signature;
+ }
+
if (!WritingModule ||
!PP->getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent)
return {};
// For implicit modules, write the hash of the PCM as its signature.
-
- auto BackpatchSignatureAt = [&](const ASTFileSignature &S, uint64_t BitNo) {
- for (uint8_t Byte : S) {
- Stream.BackpatchByte(BitNo, Byte);
- BitNo += 8;
- }
- };
-
ASTFileSignature ASTBlockHash;
ASTFileSignature Signature;
std::tie(ASTBlockHash, Signature) = createSignature();
- BackpatchSignatureAt(ASTBlockHash, ASTBlockHashOffset);
- BackpatchSignatureAt(Signature, SignatureOffset);
+ BackpatchSignatureAt(Stream, ASTBlockHash, ASTBlockHashOffset);
+ BackpatchSignatureAt(Stream, Signature, SignatureOffset);
return Signature;
}
@@ -1178,9 +1273,11 @@ void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
RecordData Record;
Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5);
- // For implicit modules, write the hash of the PCM as its signature.
- if (WritingModule &&
- PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) {
+ // For implicit modules and C++20 named modules, write the hash of the PCM as
+ // its signature.
+ if (isWritingStdCXXNamedModules() ||
+ (WritingModule &&
+ PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent)) {
// At this point, we don't know the actual signature of the file or the AST
// block - we're only able to compute those at the end of the serialization
// process. Let's store dummy signatures for now, and replace them with the
@@ -1191,21 +1288,24 @@ void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
auto Dummy = ASTFileSignature::createDummy();
SmallString<128> Blob{Dummy.begin(), Dummy.end()};
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(AST_BLOCK_HASH));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned ASTBlockHashAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
+ // We don't need AST Block hash in named modules.
+ if (!isWritingStdCXXNamedModules()) {
+ auto Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(AST_BLOCK_HASH));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned ASTBlockHashAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- Abbrev = std::make_shared<BitCodeAbbrev>();
+ Record.push_back(AST_BLOCK_HASH);
+ Stream.EmitRecordWithBlob(ASTBlockHashAbbrev, Record, Blob);
+ ASTBlockHashOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
+ Record.clear();
+ }
+
+ auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(SIGNATURE));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned SignatureAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- Record.push_back(AST_BLOCK_HASH);
- Stream.EmitRecordWithBlob(ASTBlockHashAbbrev, Record, Blob);
- ASTBlockHashOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
- Record.clear();
-
Record.push_back(SIGNATURE);
Stream.EmitRecordWithBlob(SignatureAbbrev, Record, Blob);
SignatureOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
@@ -1265,18 +1365,30 @@ void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
WritePragmaDiagnosticMappings(Diags, /* isModule = */ WritingModule);
// Header search entry usage.
- auto HSEntryUsage = PP.getHeaderSearchInfo().computeUserEntryUsage();
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_ENTRY_USAGE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of bits.
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Bit vector.
- unsigned HSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
{
+ auto HSEntryUsage = PP.getHeaderSearchInfo().computeUserEntryUsage();
+ auto Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_ENTRY_USAGE));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of bits.
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Bit vector.
+ unsigned HSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
RecordData::value_type Record[] = {HEADER_SEARCH_ENTRY_USAGE,
HSEntryUsage.size()};
Stream.EmitRecordWithBlob(HSUsageAbbrevCode, Record, bytes(HSEntryUsage));
}
+ // VFS usage.
+ {
+ auto VFSUsage = PP.getHeaderSearchInfo().collectVFSUsageAndClear();
+ auto Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(VFS_USAGE));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of bits.
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Bit vector.
+ unsigned VFSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+ RecordData::value_type Record[] = {VFS_USAGE, VFSUsage.size()};
+ Stream.EmitRecordWithBlob(VFSUsageAbbrevCode, Record, bytes(VFSUsage));
+ }
+
// Leave the options block.
Stream.ExitBlock();
UnhashedControlBlockRange.second = Stream.GetCurrentBitNo() >> 3;
@@ -1350,7 +1462,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
(!PP.getHeaderSearchInfo()
.getHeaderSearchOpts()
.ModuleMapFileHomeIsCwd ||
- WritingModule->Directory->getName() != StringRef("."))) {
+ WritingModule->Directory->getName() != ".")) {
// Module directory.
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY));
@@ -1595,6 +1707,18 @@ struct InputFileEntry {
} // namespace
+SourceLocation ASTWriter::getAffectingIncludeLoc(const SourceManager &SourceMgr,
+ const SrcMgr::FileInfo &File) {
+ SourceLocation IncludeLoc = File.getIncludeLoc();
+ if (IncludeLoc.isValid()) {
+ FileID IncludeFID = SourceMgr.getFileID(IncludeLoc);
+ assert(IncludeFID.isValid() && "IncludeLoc in invalid file");
+ if (!IsSLocAffecting[IncludeFID.ID])
+ IncludeLoc = SourceLocation();
+ }
+ return IncludeLoc;
+}
+
void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
HeaderSearchOptions &HSOpts) {
using namespace llvm;
@@ -1648,26 +1772,22 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
Entry.IsSystemFile = isSystem(File.getFileCharacteristic());
Entry.IsTransient = Cache->IsTransient;
Entry.BufferOverridden = Cache->BufferOverridden;
- Entry.IsTopLevel = File.getIncludeLoc().isInvalid();
+ Entry.IsTopLevel = getAffectingIncludeLoc(SourceMgr, File).isInvalid();
Entry.IsModuleMap = isModuleMap(File.getFileCharacteristic());
- auto ContentHash = hash_code(-1);
+ uint64_t ContentHash = 0;
if (PP->getHeaderSearchInfo()
.getHeaderSearchOpts()
.ValidateASTInputFilesContent) {
auto MemBuff = Cache->getBufferIfLoaded();
if (MemBuff)
- ContentHash = hash_value(MemBuff->getBuffer());
+ ContentHash = xxh3_64bits(MemBuff->getBuffer());
else
PP->Diag(SourceLocation(), diag::err_module_unable_to_hash_content)
<< Entry.File.getName();
}
- auto CH = llvm::APInt(64, ContentHash);
- Entry.ContentHash[0] =
- static_cast<uint32_t>(CH.getLoBits(32).getZExtValue());
- Entry.ContentHash[1] =
- static_cast<uint32_t>(CH.getHiBits(32).getZExtValue());
-
+ Entry.ContentHash[0] = uint32_t(ContentHash);
+ Entry.ContentHash[1] = uint32_t(ContentHash >> 32);
if (Entry.IsSystemFile)
SystemFiles.push_back(Entry);
else
@@ -1848,9 +1968,15 @@ namespace {
llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
struct data_type {
- const HeaderFileInfo &HFI;
+ data_type(const HeaderFileInfo &HFI, bool AlreadyIncluded,
+ ArrayRef<ModuleMap::KnownHeader> KnownHeaders,
+ UnresolvedModule Unresolved)
+ : HFI(HFI), AlreadyIncluded(AlreadyIncluded),
+ KnownHeaders(KnownHeaders), Unresolved(Unresolved) {}
+
+ HeaderFileInfo HFI;
bool AlreadyIncluded;
- ArrayRef<ModuleMap::KnownHeader> KnownHeaders;
+ SmallVector<ModuleMap::KnownHeader, 1> KnownHeaders;
UnresolvedModule Unresolved;
};
using data_type_ref = const data_type &;
@@ -1862,13 +1988,16 @@ namespace {
// The hash is based only on size/time of the file, so that the reader can
// match even when symlinking or excess path elements ("foo/../", "../")
// change the form of the name. However, complete path is still the key.
- return llvm::hash_combine(key.Size, key.ModTime);
+ uint8_t buf[sizeof(key.Size) + sizeof(key.ModTime)];
+ memcpy(buf, &key.Size, sizeof(key.Size));
+ memcpy(buf + sizeof(key.Size), &key.ModTime, sizeof(key.ModTime));
+ return llvm::xxh3_64bits(buf);
}
std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
- unsigned DataLen = 1 + 4 + 4;
+ unsigned DataLen = 1 + sizeof(IdentifierID) + 4;
for (auto ModInfo : Data.KnownHeaders)
if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
DataLen += 4;
@@ -1903,10 +2032,11 @@ namespace {
| Data.HFI.IndexHeaderMapHeader;
LE.write<uint8_t>(Flags);
- if (!Data.HFI.ControllingMacro)
- LE.write<uint32_t>(Data.HFI.ControllingMacroID);
+ if (Data.HFI.LazyControllingMacro.isID())
+ LE.write<IdentifierID>(Data.HFI.LazyControllingMacro.getID());
else
- LE.write<uint32_t>(Writer.getIdentifierRef(Data.HFI.ControllingMacro));
+ LE.write<IdentifierID>(
+ Writer.getIdentifierRef(Data.HFI.LazyControllingMacro.getPtr()));
unsigned Offset = 0;
if (!Data.HFI.Framework.empty()) {
@@ -2020,16 +2150,13 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
if (!File)
continue;
- // Get the file info. This will load info from the external source if
- // necessary. Skip emitting this file if we have no information on it
- // as a header file (in which case HFI will be null) or if it hasn't
- // changed since it was loaded. Also skip it if it's for a modular header
- // from a different module; in that case, we rely on the module(s)
- // containing the header to provide this information.
- const HeaderFileInfo *HFI =
- HS.getExistingFileInfo(*File, /*WantExternal*/!Chain);
- if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
- continue;
+ const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(*File);
+ if (!HFI)
+ continue; // We have no information on this being a header file.
+ if (!HFI->isCompilingModuleHeader && HFI->isModuleHeader)
+ continue; // Header file info is tracked by the owning module file.
+ if (!HFI->isCompilingModuleHeader && !PP->alreadyIncluded(*File))
+ continue; // Non-modular header not included is not needed.
// Massage the file path into an appropriate form.
StringRef Filename = File->getName();
@@ -2178,7 +2305,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
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);
+ AddSourceLocation(getAffectingIncludeLoc(SourceMgr, File), Record);
Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
Record.push_back(File.hasLineDirectives());
@@ -2398,6 +2525,12 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
Record.clear();
}
+ // Write the safe buffer opt-out region map in PP
+ for (SourceLocation &S : PP.serializeSafeBufferOptOutMap())
+ AddSourceLocation(S, Record);
+ Stream.EmitRecord(PP_UNSAFE_BUFFER_USAGE, Record);
+ Record.clear();
+
// Enter the preprocessor block.
Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3);
@@ -2636,8 +2769,10 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
assert((Offset >> 32) == 0 && "Preprocessed entity offset too large");
- PreprocessedEntityOffsets.push_back(
- PPEntityOffset(getAdjustedRange((*E)->getSourceRange()), Offset));
+ SourceRange R = getAdjustedRange((*E)->getSourceRange());
+ PreprocessedEntityOffsets.emplace_back(
+ getRawSourceLocationEncoding(R.getBegin()),
+ getRawSourceLocationEncoding(R.getEnd()), Offset);
if (auto *MD = dyn_cast<MacroDefinitionRecord>(*E)) {
// Record this macro definition's ID.
@@ -2704,7 +2839,9 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
std::vector<PPSkippedRange> SerializedSkippedRanges;
SerializedSkippedRanges.reserve(SkippedRanges.size());
for (auto const& Range : SkippedRanges)
- SerializedSkippedRanges.emplace_back(Range);
+ SerializedSkippedRanges.emplace_back(
+ getRawSourceLocationEncoding(Range.getBegin()),
+ getRawSourceLocationEncoding(Range.getEnd()));
using namespace llvm;
auto Abbrev = std::make_shared<BitCodeAbbrev>();
@@ -2870,8 +3007,8 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
ParentID = SubmoduleIDs[Mod->Parent];
}
- uint64_t DefinitionLoc =
- SourceLocationEncoding::encode(getAdjustedLocation(Mod->DefinitionLoc));
+ SourceLocationEncoding::RawLocEncoding DefinitionLoc =
+ getRawSourceLocationEncoding(getAdjustedLocation(Mod->DefinitionLoc));
// Emit the definition of the block.
{
@@ -2895,8 +3032,8 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
// Emit the requirements.
for (const auto &R : Mod->Requirements) {
- RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.second};
- Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.first);
+ RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.RequiredState};
+ Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.FeatureName);
}
// Emit the umbrella header, if there is one.
@@ -2997,10 +3134,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM);
}
- // Emit the initializers, if any.
+ // Emit the reachable initializers.
+ // The initializer may only be unreachable in reduced BMI.
RecordData Inits;
for (Decl *D : Context->getModuleInitializers(Mod))
- Inits.push_back(GetDeclRef(D));
+ if (wasDeclEmitted(D))
+ AddDeclRef(D, Inits);
if (!Inits.empty())
Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
@@ -3079,9 +3218,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
}
// Sort by diag::kind for deterministic output.
- llvm::sort(Mappings, [](const auto &LHS, const auto &RHS) {
- return LHS.first < RHS.first;
- });
+ llvm::sort(Mappings, llvm::less_first());
for (const auto &I : Mappings) {
Record.push_back(I.first);
@@ -3106,9 +3243,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
continue;
++NumLocations;
- SourceLocation Loc = Diag.SourceMgr->getComposedLoc(FileIDAndFile.first, 0);
- assert(!Loc.isInvalid() && "start loc for valid FileID is invalid");
- AddSourceLocation(Loc, Record);
+ AddFileID(FileIDAndFile.first, Record);
Record.push_back(FileIDAndFile.second.StateTransitions.size());
for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
@@ -3139,22 +3274,23 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
/// Write the representation of a type to the AST stream.
void ASTWriter::WriteType(QualType T) {
TypeIdx &IdxRef = TypeIdxs[T];
- if (IdxRef.getIndex() == 0) // we haven't seen this type before.
- IdxRef = TypeIdx(NextTypeID++);
+ if (IdxRef.getValue() == 0) // we haven't seen this type before.
+ IdxRef = TypeIdx(0, NextTypeID++);
TypeIdx Idx = IdxRef;
- assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST");
+ assert(Idx.getModuleFileIndex() == 0 && "Re-writing a type from a prior AST");
+ assert(Idx.getValue() >= FirstTypeID && "Writing predefined type");
// Emit the type's representation.
uint64_t Offset = ASTTypeWriter(*this).write(T) - DeclTypesBlockStartOffset;
// Record the offset for this type.
- unsigned Index = Idx.getIndex() - FirstTypeID;
+ uint64_t Index = Idx.getValue() - FirstTypeID;
if (TypeOffsets.size() == Index)
TypeOffsets.emplace_back(Offset);
else if (TypeOffsets.size() < Index) {
TypeOffsets.resize(Index + 1);
- TypeOffsets[Index].setBitOffset(Offset);
+ TypeOffsets[Index].set(Offset);
} else {
llvm_unreachable("Types emitted in wrong order");
}
@@ -3164,21 +3300,48 @@ void ASTWriter::WriteType(QualType T) {
// Declaration Serialization
//===----------------------------------------------------------------------===//
+static bool IsInternalDeclFromFileContext(const Decl *D) {
+ auto *ND = dyn_cast<NamedDecl>(D);
+ if (!ND)
+ return false;
+
+ if (!D->getDeclContext()->getRedeclContext()->isFileContext())
+ return false;
+
+ return ND->getFormalLinkage() == Linkage::Internal;
+}
+
/// Write the block containing all of the declaration IDs
/// lexically declared within the given DeclContext.
///
/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
/// bitstream, or 0 if no block was written.
uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
- DeclContext *DC) {
+ const DeclContext *DC) {
if (DC->decls_empty())
return 0;
+ // In reduced BMI, we don't care the declarations in functions.
+ if (GeneratingReducedBMI && DC->isFunctionOrMethod())
+ return 0;
+
uint64_t Offset = Stream.GetCurrentBitNo();
- SmallVector<uint32_t, 128> KindDeclPairs;
+ SmallVector<DeclID, 128> KindDeclPairs;
for (const auto *D : DC->decls()) {
+ if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D))
+ continue;
+
+ // We don't need to write decls with internal linkage into reduced BMI.
+ // If such decls gets emitted due to it get used from inline functions,
+ // the program illegal. However, there are too many use of static inline
+ // functions in the global module fragment and it will be breaking change
+ // to forbid that. So we have to allow to emit such declarations from GMF.
+ if (GeneratingReducedBMI && !D->isFromExplicitGlobalModule() &&
+ IsInternalDeclFromFileContext(D))
+ continue;
+
KindDeclPairs.push_back(D->getKind());
- KindDeclPairs.push_back(GetDeclRef(D));
+ KindDeclPairs.push_back(GetDeclRef(D).getRawValue());
}
++NumLexicalDeclContexts;
@@ -3195,12 +3358,10 @@ void ASTWriter::WriteTypeDeclOffsets() {
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base type index
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
{
- RecordData::value_type Record[] = {TYPE_OFFSET, TypeOffsets.size(),
- FirstTypeID - NUM_PREDEF_TYPE_IDS};
+ RecordData::value_type Record[] = {TYPE_OFFSET, TypeOffsets.size()};
Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, bytes(TypeOffsets));
}
@@ -3208,12 +3369,10 @@ void ASTWriter::WriteTypeDeclOffsets() {
Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
{
- RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(),
- FirstDeclID - NUM_PREDEF_DECL_IDS};
+ RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size()};
Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets));
}
}
@@ -3234,7 +3393,7 @@ void ASTWriter::WriteFileDeclIDsMap() {
Info.FirstDeclIndex = FileGroupedDeclIDs.size();
llvm::stable_sort(Info.DeclIDs);
for (auto &LocDeclEntry : Info.DeclIDs)
- FileGroupedDeclIDs.push_back(LocDeclEntry.second);
+ FileGroupedDeclIDs.push_back(LocDeclEntry.second.getRawValue());
}
auto Abbrev = std::make_shared<BitCodeAbbrev>();
@@ -3305,16 +3464,18 @@ public:
std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, Selector Sel,
data_type_ref Methods) {
- unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
+ unsigned KeyLen =
+ 2 + (Sel.getNumArgs() ? Sel.getNumArgs() * sizeof(IdentifierID)
+ : sizeof(IdentifierID));
unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
for (const ObjCMethodList *Method = &Methods.Instance; Method;
Method = Method->getNext())
if (ShouldWriteMethodListNode(Method))
- DataLen += 4;
+ DataLen += sizeof(DeclID);
for (const ObjCMethodList *Method = &Methods.Factory; Method;
Method = Method->getNext())
if (ShouldWriteMethodListNode(Method))
- DataLen += 4;
+ DataLen += sizeof(DeclID);
return emitULEBKeyDataLength(KeyLen, DataLen, Out);
}
@@ -3330,7 +3491,7 @@ public:
if (N == 0)
N = 1;
for (unsigned I = 0; I != N; ++I)
- LE.write<uint32_t>(
+ LE.write<IdentifierID>(
Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
}
@@ -3372,11 +3533,11 @@ public:
for (const ObjCMethodList *Method = &Methods.Instance; Method;
Method = Method->getNext())
if (ShouldWriteMethodListNode(Method))
- LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));
+ LE.write<DeclID>((DeclID)Writer.getDeclID(Method->getMethod()));
for (const ObjCMethodList *Method = &Methods.Factory; Method;
Method = Method->getNext())
if (ShouldWriteMethodListNode(Method))
- LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));
+ LE.write<DeclID>((DeclID)Writer.getDeclID(Method->getMethod()));
assert(Out.tell() - Start == DataLen && "Data length is wrong");
}
@@ -3398,7 +3559,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
using namespace llvm;
// Do we have to do anything at all?
- if (SemaRef.MethodPool.empty() && SelectorIDs.empty())
+ if (SemaRef.ObjC().MethodPool.empty() && SelectorIDs.empty())
return;
unsigned NumTableEntries = 0;
// Create and write out the blob that contains selectors and the method pool.
@@ -3412,13 +3573,14 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
for (auto &SelectorAndID : SelectorIDs) {
Selector S = SelectorAndID.first;
SelectorID ID = SelectorAndID.second;
- Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S);
+ SemaObjC::GlobalMethodPool::iterator F =
+ SemaRef.ObjC().MethodPool.find(S);
ASTMethodPoolTrait::data_type Data = {
ID,
ObjCMethodList(),
ObjCMethodList()
};
- if (F != SemaRef.MethodPool.end()) {
+ if (F != SemaRef.ObjC().MethodPool.end()) {
Data.Instance = F->second.first;
Data.Factory = F->second.second;
}
@@ -3503,7 +3665,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
using namespace llvm;
- if (SemaRef.ReferencedSelectors.empty())
+ if (SemaRef.ObjC().ReferencedSelectors.empty())
return;
RecordData Record;
@@ -3512,7 +3674,7 @@ void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
// Note: this writes out all references even for a dependent AST. But it is
// very tricky to fix, and given that @selector shouldn't really appear in
// headers, probably not worth it. It's not a correctness issue.
- for (auto &SelectorAndLocation : SemaRef.ReferencedSelectors) {
+ for (auto &SelectorAndLocation : SemaRef.ObjC().ReferencedSelectors) {
Selector Sel = SelectorAndLocation.first;
SourceLocation Loc = SelectorAndLocation.second;
Writer.AddSelectorRef(Sel);
@@ -3567,6 +3729,29 @@ static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts,
namespace {
+bool IsInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset,
+ bool IsModule, bool IsCPlusPlus) {
+ bool NeedDecls = !IsModule || !IsCPlusPlus;
+
+ bool IsInteresting =
+ II->getNotableIdentifierID() != tok::NotableIdentifierKind::not_notable ||
+ II->getBuiltinID() != Builtin::ID::NotBuiltin ||
+ II->getObjCKeywordID() != tok::ObjCKeywordKind::objc_not_keyword;
+ if (MacroOffset || II->isPoisoned() || (!IsModule && IsInteresting) ||
+ II->hasRevertedTokenIDToIdentifier() ||
+ (NeedDecls && II->getFETokenInfo()))
+ return true;
+
+ return false;
+}
+
+bool IsInterestingNonMacroIdentifier(const IdentifierInfo *II,
+ ASTWriter &Writer) {
+ bool IsModule = Writer.isWritingModule();
+ bool IsCPlusPlus = Writer.getLangOpts().CPlusPlus;
+ return IsInterestingIdentifier(II, /*MacroOffset=*/0, IsModule, IsCPlusPlus);
+}
+
class ASTIdentifierTableTrait {
ASTWriter &Writer;
Preprocessor &PP;
@@ -3580,20 +3765,15 @@ class ASTIdentifierTableTrait {
/// doesn't check whether the name has macros defined; use PublicMacroIterator
/// to check that.
bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) {
- if (MacroOffset || II->isPoisoned() ||
- (!IsModule && II->getObjCOrBuiltinID()) ||
- II->hasRevertedTokenIDToIdentifier() ||
- (NeedDecls && II->getFETokenInfo()))
- return true;
-
- return false;
+ return IsInterestingIdentifier(II, MacroOffset, IsModule,
+ Writer.getLangOpts().CPlusPlus);
}
public:
- using key_type = IdentifierInfo *;
+ using key_type = const IdentifierInfo *;
using key_type_ref = key_type;
- using data_type = IdentID;
+ using data_type = IdentifierID;
using data_type_ref = data_type;
using hash_value_type = unsigned;
@@ -3617,12 +3797,8 @@ public:
return isInterestingIdentifier(II, MacroOffset);
}
- bool isInterestingNonMacroIdentifier(const IdentifierInfo *II) {
- return isInterestingIdentifier(II, 0);
- }
-
std::pair<unsigned, unsigned>
- EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
+ EmitKeyDataLength(raw_ostream &Out, const IdentifierInfo *II, IdentifierID ID) {
// Record the location of the identifier data. This is used when generating
// the mapping from persistent IDs to strings.
Writer.SetIdentifierOffset(II, Out.tell());
@@ -3636,7 +3812,7 @@ public:
InterestingIdentifierOffsets->push_back(Out.tell());
unsigned KeyLen = II->getLength() + 1;
- unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
+ unsigned DataLen = sizeof(IdentifierID); // bytes for the persistent ID << 1
if (isInterestingIdentifier(II, MacroOffset)) {
DataLen += 2; // 2 bytes for builtin ID
DataLen += 2; // 2 bytes for flags
@@ -3644,29 +3820,29 @@ public:
DataLen += 4; // MacroDirectives offset.
if (NeedDecls)
- DataLen += std::distance(IdResolver.begin(II), IdResolver.end()) * 4;
+ DataLen += std::distance(IdResolver.begin(II), IdResolver.end()) *
+ sizeof(DeclID);
}
return emitULEBKeyDataLength(KeyLen, DataLen, Out);
}
- void EmitKey(raw_ostream& Out, const IdentifierInfo* II,
- unsigned KeyLen) {
+ void EmitKey(raw_ostream &Out, const IdentifierInfo *II, unsigned KeyLen) {
Out.write(II->getNameStart(), KeyLen);
}
- void EmitData(raw_ostream& Out, IdentifierInfo* II,
- IdentID ID, unsigned) {
+ void EmitData(raw_ostream &Out, const IdentifierInfo *II, IdentifierID ID,
+ unsigned) {
using namespace llvm::support;
endian::Writer LE(Out, llvm::endianness::little);
auto MacroOffset = Writer.getMacroDirectivesOffset(II);
if (!isInterestingIdentifier(II, MacroOffset)) {
- LE.write<uint32_t>(ID << 1);
+ LE.write<IdentifierID>(ID << 1);
return;
}
- LE.write<uint32_t>((ID << 1) | 0x01);
+ LE.write<IdentifierID>((ID << 1) | 0x01);
uint32_t Bits = (uint32_t)II->getObjCOrBuiltinID();
assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
LE.write<uint16_t>(Bits);
@@ -3691,14 +3867,18 @@ public:
// Only emit declarations that aren't from a chained PCH, though.
SmallVector<NamedDecl *, 16> Decls(IdResolver.decls(II));
for (NamedDecl *D : llvm::reverse(Decls))
- LE.write<uint32_t>(
- Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), D)));
+ LE.write<DeclID>((DeclID)Writer.getDeclID(
+ getDeclForLocalLookup(PP.getLangOpts(), D)));
}
}
};
} // namespace
+/// If the \param IdentifierID ID is a local Identifier ID. If the higher
+/// bits of ID is 0, it implies that the ID doesn't come from AST files.
+static bool isLocalIdentifierID(IdentifierID ID) { return !(ID >> 32); }
+
/// Write the identifier table into the AST file.
///
/// The identifier table consists of a blob containing string data
@@ -3718,32 +3898,17 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule,
IsModule ? &InterestingIdents : nullptr);
- // Look for any identifiers that were named while processing the
- // headers, but are otherwise not needed. We add these to the hash
- // table to enable checking of the predefines buffer in the case
- // where the user adds new macro definitions when building the AST
- // file.
- SmallVector<const IdentifierInfo *, 128> IIs;
- for (const auto &ID : PP.getIdentifierTable())
- if (Trait.isInterestingNonMacroIdentifier(ID.second))
- IIs.push_back(ID.second);
- // Sort the identifiers lexicographically before getting the references so
- // that their order is stable.
- llvm::sort(IIs, llvm::deref<std::less<>>());
- for (const IdentifierInfo *II : IIs)
- getIdentifierRef(II);
-
// Create the on-disk hash table representation. We only store offsets
// for identifiers that appear here for the first time.
IdentifierOffsets.resize(NextIdentID - FirstIdentID);
for (auto IdentIDPair : IdentifierIDs) {
- auto *II = const_cast<IdentifierInfo *>(IdentIDPair.first);
- IdentID ID = IdentIDPair.second;
+ const IdentifierInfo *II = IdentIDPair.first;
+ IdentifierID ID = IdentIDPair.second;
assert(II && "NULL identifier in identifier table");
+
// Write out identifiers if either the ID is local or the identifier has
// changed since it was loaded.
- if (ID >= FirstIdentID || !Chain || !II->isFromAST()
- || II->hasChangedSinceDeserialization() ||
+ if (isLocalIdentifierID(ID) || II->hasChangedSinceDeserialization() ||
(Trait.needDecls() &&
II->hasFETokenInfoChangedSinceDeserialization()))
Generator.insert(II, ID, Trait);
@@ -3777,7 +3942,6 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
@@ -3787,8 +3951,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
#endif
RecordData::value_type Record[] = {IDENTIFIER_OFFSET,
- IdentifierOffsets.size(),
- FirstIdentID - NUM_PREDEF_IDENT_IDS};
+ IdentifierOffsets.size()};
Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
bytes(IdentifierOffsets));
@@ -3807,7 +3970,7 @@ namespace {
// Trait used for the on-disk hash table used in the method pool.
class ASTDeclContextNameLookupTrait {
ASTWriter &Writer;
- llvm::SmallVector<DeclID, 64> DeclIDs;
+ llvm::SmallVector<LocalDeclID, 64> DeclIDs;
public:
using key_type = DeclarationNameKey;
@@ -3826,15 +3989,31 @@ public:
data_type getData(const Coll &Decls) {
unsigned Start = DeclIDs.size();
for (NamedDecl *D : Decls) {
- DeclIDs.push_back(
- Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), D)));
+ NamedDecl *DeclForLocalLookup =
+ getDeclForLocalLookup(Writer.getLangOpts(), D);
+
+ if (Writer.getDoneWritingDeclsAndTypes() &&
+ !Writer.wasDeclEmitted(DeclForLocalLookup))
+ continue;
+
+ // Try to avoid writing internal decls to reduced BMI.
+ // See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
+ if (Writer.isGeneratingReducedBMI() &&
+ !DeclForLocalLookup->isFromExplicitGlobalModule() &&
+ IsInternalDeclFromFileContext(DeclForLocalLookup))
+ continue;
+
+ DeclIDs.push_back(Writer.GetDeclRef(DeclForLocalLookup));
}
return std::make_pair(Start, DeclIDs.size());
}
data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) {
unsigned Start = DeclIDs.size();
- llvm::append_range(DeclIDs, FromReader);
+ DeclIDs.insert(
+ DeclIDs.end(),
+ DeclIDIterator<GlobalDeclID, LocalDeclID>(FromReader.begin()),
+ DeclIDIterator<GlobalDeclID, LocalDeclID>(FromReader.end()));
return std::make_pair(Start, DeclIDs.size());
}
@@ -3862,11 +4041,13 @@ public:
unsigned KeyLen = 1;
switch (Name.getKind()) {
case DeclarationName::Identifier:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXDeductionGuideName:
+ KeyLen += sizeof(IdentifierID);
+ break;
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXDeductionGuideName:
KeyLen += 4;
break;
case DeclarationName::CXXOperatorName:
@@ -3879,8 +4060,8 @@ public:
break;
}
- // 4 bytes for each DeclID.
- unsigned DataLen = 4 * (Lookup.second - Lookup.first);
+ // length of DeclIDs.
+ unsigned DataLen = sizeof(DeclID) * (Lookup.second - Lookup.first);
return emitULEBKeyDataLength(KeyLen, DataLen, Out);
}
@@ -3894,7 +4075,7 @@ public:
case DeclarationName::Identifier:
case DeclarationName::CXXLiteralOperatorName:
case DeclarationName::CXXDeductionGuideName:
- LE.write<uint32_t>(Writer.getIdentifierRef(Name.getIdentifier()));
+ LE.write<IdentifierID>(Writer.getIdentifierRef(Name.getIdentifier()));
return;
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
@@ -3923,7 +4104,7 @@ public:
endian::Writer LE(Out, llvm::endianness::little);
uint64_t Start = Out.tell(); (void)Start;
for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
- LE.write<uint32_t>(DeclIDs[I]);
+ LE.write<DeclID>((DeclID)DeclIDs[I]);
assert(Out.tell() - Start == DataLen && "Data length is wrong");
}
};
@@ -3936,11 +4117,28 @@ bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DC->hasNeedToReconcileExternalVisibleStorage();
}
-bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
- DeclContext *DC) {
- for (auto *D : Result.getLookupResult())
- if (!getDeclForLocalLookup(getLangOpts(), D)->isFromASTFile())
- return false;
+/// Returns ture if all of the lookup result are either external, not emitted or
+/// predefined. In such cases, the lookup result is not interesting and we don't
+/// need to record the result in the current being written module. Return false
+/// otherwise.
+static bool isLookupResultNotInteresting(ASTWriter &Writer,
+ StoredDeclsList &Result) {
+ for (auto *D : Result.getLookupResult()) {
+ auto *LocalD = getDeclForLocalLookup(Writer.getLangOpts(), D);
+ if (LocalD->isFromASTFile())
+ continue;
+
+ // We can only be sure whether the local declaration is reachable
+ // after we done writing the declarations and types.
+ if (Writer.getDoneWritingDeclsAndTypes() && !Writer.wasDeclEmitted(LocalD))
+ continue;
+
+ // We don't need to emit the predefined decls.
+ if (Writer.isDeclPredefined(LocalD))
+ continue;
+
+ return false;
+ }
return true;
}
@@ -3978,8 +4176,17 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
// don't need to write an entry for the name at all. If we can't
// write out a lookup set without performing more deserialization,
// just skip this entry.
- if (isLookupResultExternal(Result, DC) &&
- isLookupResultEntirelyExternal(Result, DC))
+ //
+ // Also in reduced BMI, we'd like to avoid writing unreachable
+ // declarations in GMF, so we need to avoid writing declarations
+ // that entirely external or unreachable.
+ //
+ // FIMXE: It looks sufficient to test
+ // isLookupResultNotInteresting here. But due to bug we have
+ // to test isLookupResultExternal here. See
+ // https://github.com/llvm/llvm-project/issues/61065 for details.
+ if ((GeneratingReducedBMI || isLookupResultExternal(Result, DC)) &&
+ isLookupResultNotInteresting(*this, Result))
continue;
// We also skip empty results. If any of the results could be external and
@@ -4170,9 +4377,21 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
continue;
}
- for (NamedDecl *ND : Result)
- if (!ND->isFromASTFile())
- GetDeclRef(ND);
+ for (NamedDecl *ND : Result) {
+ if (ND->isFromASTFile())
+ continue;
+
+ if (DoneWritingDeclsAndTypes && !wasDeclEmitted(ND))
+ continue;
+
+ // We don't need to force emitting internal decls into reduced BMI.
+ // See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
+ if (GeneratingReducedBMI && !ND->isFromExplicitGlobalModule() &&
+ IsInternalDeclFromFileContext(ND))
+ continue;
+
+ GetDeclRef(ND);
+ }
}
return 0;
@@ -4233,7 +4452,8 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
DC = cast<DeclContext>(Chain->getKeyDeclaration(cast<Decl>(DC)));
// Write the lookup table
- RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast<Decl>(DC))};
+ RecordData::value_type Record[] = {UPDATE_VISIBLE,
+ getDeclID(cast<Decl>(DC)).getRawValue()};
Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
}
@@ -4263,8 +4483,8 @@ void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) {
Stream.EmitRecord(OPENCL_EXTENSIONS, Record);
}
void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) {
- if (SemaRef.ForceCUDAHostDeviceDepth > 0) {
- RecordData::value_type Record[] = {SemaRef.ForceCUDAHostDeviceDepth};
+ if (SemaRef.CUDA().ForceHostDeviceDepth > 0) {
+ RecordData::value_type Record[] = {SemaRef.CUDA().ForceHostDeviceDepth};
Stream.EmitRecord(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH, Record);
}
}
@@ -4287,7 +4507,7 @@ void ASTWriter::WriteObjCCategories() {
Cat = Class->known_categories_begin(),
CatEnd = Class->known_categories_end();
Cat != CatEnd; ++Cat, ++Size) {
- assert(getDeclID(*Cat) != 0 && "Bogus category");
+ assert(getDeclID(*Cat).isValid() && "Bogus category");
AddDeclRef(*Cat, Categories);
}
@@ -4578,11 +4798,18 @@ void ASTWriter::AddVersionTuple(const VersionTuple &Version,
/// Note that the identifier II occurs at the given offset
/// within the identifier table.
void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
- IdentID ID = IdentifierIDs[II];
+ IdentifierID ID = IdentifierIDs[II];
// Only store offsets new to this AST file. Other identifier names are looked
// up earlier in the chain and thus don't need an offset.
- if (ID >= FirstIdentID)
- IdentifierOffsets[ID - FirstIdentID] = Offset;
+ if (!isLocalIdentifierID(ID))
+ return;
+
+ // For local identifiers, the module file index must be 0.
+
+ assert(ID != 0);
+ ID -= NUM_PREDEF_IDENT_IDS;
+ assert(ID < IdentifierOffsets.size());
+ IdentifierOffsets[ID] = Offset;
}
/// Note that the selector Sel occurs at the given offset
@@ -4601,10 +4828,12 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
SmallVectorImpl<char> &Buffer,
InMemoryModuleCache &ModuleCache,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool IncludeTimestamps, bool BuildingImplicitModule)
+ bool IncludeTimestamps, bool BuildingImplicitModule,
+ bool GeneratingReducedBMI)
: Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache),
IncludeTimestamps(IncludeTimestamps),
- BuildingImplicitModule(BuildingImplicitModule) {
+ BuildingImplicitModule(BuildingImplicitModule),
+ GeneratingReducedBMI(GeneratingReducedBMI) {
for (const auto &Ext : Extensions) {
if (auto Writer = Ext->createExtensionWriter(*this))
ModuleFileExtensionWriters.push_back(std::move(Writer));
@@ -4659,15 +4888,23 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
}
template<typename Vector>
-static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
- ASTWriter::RecordData &Record) {
+static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec) {
+ for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
+ I != E; ++I) {
+ Writer.GetDeclRef(*I);
+ }
+}
+
+template <typename Vector>
+static void AddLazyVectorEmiitedDecls(ASTWriter &Writer, Vector &Vec,
+ ASTWriter::RecordData &Record) {
for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
I != E; ++I) {
- Writer.AddDeclRef(*I, Record);
+ Writer.AddEmittedDeclRef(*I, Record);
}
}
-void ASTWriter::collectNonAffectingInputFiles() {
+void ASTWriter::computeNonAffectingInputFiles() {
SourceManager &SrcMgr = PP->getSourceManager();
unsigned N = SrcMgr.local_sloc_entry_size();
@@ -4699,9 +4936,16 @@ void ASTWriter::collectNonAffectingInputFiles() {
if (!Cache->OrigEntry)
continue;
- if (!isModuleMap(File.getFileCharacteristic()) ||
- AffectingModuleMaps.empty() ||
- llvm::is_contained(AffectingModuleMaps, *Cache->OrigEntry))
+ // Don't prune anything other than module maps.
+ if (!isModuleMap(File.getFileCharacteristic()))
+ continue;
+
+ // Don't prune module maps if all are guaranteed to be affecting.
+ if (!AffectingModuleMaps)
+ continue;
+
+ // Don't prune module maps that are affecting.
+ if (llvm::is_contained(*AffectingModuleMaps, *Cache->OrigEntry))
continue;
IsSLocAffecting[I] = false;
@@ -4727,32 +4971,43 @@ void ASTWriter::collectNonAffectingInputFiles() {
NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
}
-}
-
-ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
- Module *WritingModule) {
- using namespace llvm;
- bool isModule = WritingModule != nullptr;
+ if (!PP->getHeaderSearchInfo().getHeaderSearchOpts().ModulesIncludeVFSUsage)
+ return;
- // Make sure that the AST reader knows to finalize itself.
- if (Chain)
- Chain->finalizeForWriting();
+ FileManager &FileMgr = PP->getFileManager();
+ FileMgr.trackVFSUsage(true);
+ // Lookup the paths in the VFS to trigger `-ivfsoverlay` usage tracking.
+ for (StringRef Path :
+ PP->getHeaderSearchInfo().getHeaderSearchOpts().VFSOverlayFiles)
+ FileMgr.getVirtualFileSystem().exists(Path);
+ for (unsigned I = 1; I != N; ++I) {
+ if (IsSLocAffecting[I]) {
+ const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(I);
+ if (!SLoc->isFile())
+ continue;
+ const SrcMgr::FileInfo &File = SLoc->getFile();
+ const SrcMgr::ContentCache *Cache = &File.getContentCache();
+ if (!Cache->OrigEntry)
+ continue;
+ FileMgr.getVirtualFileSystem().exists(
+ Cache->OrigEntry->getNameAsRequested());
+ }
+ }
+ FileMgr.trackVFSUsage(false);
+}
+void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
ASTContext &Context = SemaRef.Context;
- Preprocessor &PP = SemaRef.PP;
-
- // This needs to be done very early, since everything that writes
- // SourceLocations or FileIDs depends on it.
- collectNonAffectingInputFiles();
- writeUnhashedControlBlock(PP, Context);
+ bool isModule = WritingModule != nullptr;
// Set up predefined declaration IDs.
auto RegisterPredefDecl = [&] (Decl *D, PredefinedDeclIDs ID) {
if (D) {
assert(D->isCanonicalDecl() && "predefined decl is not canonical");
DeclIDs[D] = ID;
+ PredefinedDecls.insert(D);
}
};
RegisterPredefDecl(Context.getTranslationUnitDecl(),
@@ -4782,103 +5037,276 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
RegisterPredefDecl(Context.TypePackElementDecl,
PREDEF_DECL_TYPE_PACK_ELEMENT_ID);
- // Build a record containing all of the tentative definitions in this file, in
+ const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+
+ // Force all top level declarations to be emitted.
+ //
+ // We start emitting top level declarations from the module purview to
+ // implement the eliding unreachable declaration feature.
+ for (const auto *D : TU->noload_decls()) {
+ if (D->isFromASTFile())
+ continue;
+
+ if (GeneratingReducedBMI) {
+ if (D->isFromExplicitGlobalModule())
+ continue;
+
+ // Don't force emitting static entities.
+ //
+ // Technically, all static entities shouldn't be in reduced BMI. The
+ // language also specifies that the program exposes TU-local entities
+ // is ill-formed. However, in practice, there are a lot of projects
+ // uses `static inline` in the headers. So we can't get rid of all
+ // static entities in reduced BMI now.
+ if (IsInternalDeclFromFileContext(D))
+ continue;
+ }
+
+ // If we're writing C++ named modules, don't emit declarations which are
+ // not from modules by default. They may be built in declarations (be
+ // handled above) or implcit declarations (see the implementation of
+ // `Sema::Initialize()` for example).
+ if (isWritingStdCXXNamedModules() && !D->getOwningModule() &&
+ D->isImplicit())
+ continue;
+
+ GetDeclRef(D);
+ }
+
+ if (GeneratingReducedBMI)
+ return;
+
+ // Writing all of the tentative definitions in this file, in
// TentativeDefinitions order. Generally, this record will be empty for
// headers.
RecordData TentativeDefinitions;
- AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions);
+ AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions);
- // Build a record containing all of the file scoped decls in this file.
- RecordData UnusedFileScopedDecls;
+ // Writing all of the file scoped decls in this file.
if (!isModule)
- AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls,
- UnusedFileScopedDecls);
+ AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls);
- // Build a record containing all of the delegating constructors we still need
+ // Writing all of the delegating constructors we still need
// to resolve.
- RecordData DelegatingCtorDecls;
if (!isModule)
- AddLazyVectorDecls(*this, SemaRef.DelegatingCtorDecls, DelegatingCtorDecls);
+ AddLazyVectorDecls(*this, SemaRef.DelegatingCtorDecls);
- // Write the set of weak, undeclared identifiers. We always write the
- // entire table, since later PCH files in a PCH chain are only interested in
- // the results at the end of the chain.
- RecordData WeakUndeclaredIdentifiers;
- for (const auto &WeakUndeclaredIdentifierList :
- SemaRef.WeakUndeclaredIdentifiers) {
- const IdentifierInfo *const II = WeakUndeclaredIdentifierList.first;
- for (const auto &WI : WeakUndeclaredIdentifierList.second) {
- AddIdentifierRef(II, WeakUndeclaredIdentifiers);
- AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers);
- AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers);
+ // Writing all of the ext_vector declarations.
+ AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls);
+
+ // Writing all of the VTable uses information.
+ if (!SemaRef.VTableUses.empty())
+ for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I)
+ GetDeclRef(SemaRef.VTableUses[I].first);
+
+ // Writing all of the UnusedLocalTypedefNameCandidates.
+ for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
+ GetDeclRef(TD);
+
+ // Writing all of pending implicit instantiations.
+ for (const auto &I : SemaRef.PendingInstantiations)
+ GetDeclRef(I.first);
+ assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
+ "There are local ones at end of translation unit!");
+
+ // Writing some declaration references.
+ if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
+ GetDeclRef(SemaRef.getStdNamespace());
+ GetDeclRef(SemaRef.getStdBadAlloc());
+ GetDeclRef(SemaRef.getStdAlignValT());
+ }
+
+ if (Context.getcudaConfigureCallDecl())
+ GetDeclRef(Context.getcudaConfigureCallDecl());
+
+ // Writing all of the known namespaces.
+ for (const auto &I : SemaRef.KnownNamespaces)
+ if (!I.second)
+ GetDeclRef(I.first);
+
+ // Writing all used, undefined objects that require definitions.
+ SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
+ SemaRef.getUndefinedButUsed(Undefined);
+ for (const auto &I : Undefined)
+ GetDeclRef(I.first);
+
+ // Writing all delete-expressions that we would like to
+ // analyze later in AST.
+ if (!isModule)
+ for (const auto &DeleteExprsInfo :
+ SemaRef.getMismatchingDeleteExpressions())
+ GetDeclRef(DeleteExprsInfo.first);
+
+ // Make sure visible decls, added to DeclContexts previously loaded from
+ // an AST file, are registered for serialization. Likewise for template
+ // specializations added to imported templates.
+ for (const auto *I : DeclsToEmitEvenIfUnreferenced)
+ GetDeclRef(I);
+ DeclsToEmitEvenIfUnreferenced.clear();
+
+ // Make sure all decls associated with an identifier are registered for
+ // serialization, if we're storing decls with identifiers.
+ if (!WritingModule || !getLangOpts().CPlusPlus) {
+ llvm::SmallVector<const IdentifierInfo*, 256> IIs;
+ for (const auto &ID : SemaRef.PP.getIdentifierTable()) {
+ const IdentifierInfo *II = ID.second;
+ if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization())
+ IIs.push_back(II);
}
+ // Sort the identifiers to visit based on their name.
+ llvm::sort(IIs, llvm::deref<std::less<>>());
+ for (const IdentifierInfo *II : IIs)
+ for (const Decl *D : SemaRef.IdResolver.decls(II))
+ GetDeclRef(D);
}
- // Build a record containing all of the ext_vector declarations.
+ // Write all of the DeclsToCheckForDeferredDiags.
+ for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
+ GetDeclRef(D);
+}
+
+void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
+ ASTContext &Context = SemaRef.Context;
+
+ bool isModule = WritingModule != nullptr;
+
+ // Write the record containing external, unnamed definitions.
+ if (!EagerlyDeserializedDecls.empty())
+ Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
+
+ if (!ModularCodegenDecls.empty())
+ Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls);
+
+ // Write the record containing tentative definitions.
+ RecordData TentativeDefinitions;
+ AddLazyVectorEmiitedDecls(*this, SemaRef.TentativeDefinitions,
+ TentativeDefinitions);
+ if (!TentativeDefinitions.empty())
+ Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
+
+ // Write the record containing unused file scoped decls.
+ RecordData UnusedFileScopedDecls;
+ if (!isModule)
+ AddLazyVectorEmiitedDecls(*this, SemaRef.UnusedFileScopedDecls,
+ UnusedFileScopedDecls);
+ if (!UnusedFileScopedDecls.empty())
+ Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
+
+ // Write the record containing ext_vector type names.
RecordData ExtVectorDecls;
- AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
+ AddLazyVectorEmiitedDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
+ if (!ExtVectorDecls.empty())
+ Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
- // Build a record containing all of the VTable uses information.
+ // Write the record containing VTable uses information.
RecordData VTableUses;
if (!SemaRef.VTableUses.empty()) {
for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
- AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
+ CXXRecordDecl *D = SemaRef.VTableUses[I].first;
+ if (!wasDeclEmitted(D))
+ continue;
+
+ AddDeclRef(D, VTableUses);
AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
- VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]);
+ VTableUses.push_back(SemaRef.VTablesUsed[D]);
}
+ Stream.EmitRecord(VTABLE_USES, VTableUses);
}
- // Build a record containing all of the UnusedLocalTypedefNameCandidates.
+ // Write the record containing potentially unused local typedefs.
RecordData UnusedLocalTypedefNameCandidates;
for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
- AddDeclRef(TD, UnusedLocalTypedefNameCandidates);
+ AddEmittedDeclRef(TD, UnusedLocalTypedefNameCandidates);
+ if (!UnusedLocalTypedefNameCandidates.empty())
+ Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
+ UnusedLocalTypedefNameCandidates);
- // Build a record containing all of pending implicit instantiations.
+ // Write the record containing pending implicit instantiations.
RecordData PendingInstantiations;
for (const auto &I : SemaRef.PendingInstantiations) {
+ if (!wasDeclEmitted(I.first))
+ continue;
+
AddDeclRef(I.first, PendingInstantiations);
AddSourceLocation(I.second, PendingInstantiations);
}
- assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
- "There are local ones at end of translation unit!");
+ if (!PendingInstantiations.empty())
+ Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
- // Build a record containing some declaration references.
+ // Write the record containing declaration references of Sema.
RecordData SemaDeclRefs;
if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
- AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs);
- AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
- AddDeclRef(SemaRef.getStdAlignValT(), SemaDeclRefs);
+ auto AddEmittedDeclRefOrZero = [this, &SemaDeclRefs](Decl *D) {
+ if (!D || !wasDeclEmitted(D))
+ SemaDeclRefs.push_back(0);
+ else
+ AddDeclRef(D, SemaDeclRefs);
+ };
+
+ AddEmittedDeclRefOrZero(SemaRef.getStdNamespace());
+ AddEmittedDeclRefOrZero(SemaRef.getStdBadAlloc());
+ AddEmittedDeclRefOrZero(SemaRef.getStdAlignValT());
}
+ if (!SemaDeclRefs.empty())
+ Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
+ // Write the record containing decls to be checked for deferred diags.
+ RecordData DeclsToCheckForDeferredDiags;
+ for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
+ if (wasDeclEmitted(D))
+ AddDeclRef(D, DeclsToCheckForDeferredDiags);
+ if (!DeclsToCheckForDeferredDiags.empty())
+ Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS,
+ DeclsToCheckForDeferredDiags);
+
+ // Write the record containing CUDA-specific declaration references.
RecordData CUDASpecialDeclRefs;
- if (Context.getcudaConfigureCallDecl()) {
- AddDeclRef(Context.getcudaConfigureCallDecl(), CUDASpecialDeclRefs);
+ if (auto *CudaCallDecl = Context.getcudaConfigureCallDecl();
+ CudaCallDecl && wasDeclEmitted(CudaCallDecl)) {
+ AddDeclRef(CudaCallDecl, CUDASpecialDeclRefs);
+ Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs);
}
- // Build a record containing all of the known namespaces.
+ // Write the delegating constructors.
+ RecordData DelegatingCtorDecls;
+ if (!isModule)
+ AddLazyVectorEmiitedDecls(*this, SemaRef.DelegatingCtorDecls,
+ DelegatingCtorDecls);
+ if (!DelegatingCtorDecls.empty())
+ Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
+
+ // Write the known namespaces.
RecordData KnownNamespaces;
for (const auto &I : SemaRef.KnownNamespaces) {
- if (!I.second)
+ if (!I.second && wasDeclEmitted(I.first))
AddDeclRef(I.first, KnownNamespaces);
}
+ if (!KnownNamespaces.empty())
+ Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
- // Build a record of all used, undefined objects that require definitions.
+ // Write the undefined internal functions and variables, and inline functions.
RecordData UndefinedButUsed;
-
SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
SemaRef.getUndefinedButUsed(Undefined);
for (const auto &I : Undefined) {
+ if (!wasDeclEmitted(I.first))
+ continue;
+
AddDeclRef(I.first, UndefinedButUsed);
AddSourceLocation(I.second, UndefinedButUsed);
}
+ if (!UndefinedButUsed.empty())
+ Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
- // Build a record containing all delete-expressions that we would like to
+ // Write all delete-expressions that we would like to
// analyze later in AST.
RecordData DeleteExprsToAnalyze;
-
if (!isModule) {
for (const auto &DeleteExprsInfo :
SemaRef.getMismatchingDeleteExpressions()) {
+ if (!wasDeclEmitted(DeleteExprsInfo.first))
+ continue;
+
AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze);
DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size());
for (const auto &DeleteLoc : DeleteExprsInfo.second) {
@@ -4887,6 +5315,87 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
}
}
}
+ if (!DeleteExprsToAnalyze.empty())
+ Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
+}
+
+ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
+ Module *WritingModule) {
+ using namespace llvm;
+
+ bool isModule = WritingModule != nullptr;
+
+ // Make sure that the AST reader knows to finalize itself.
+ if (Chain)
+ Chain->finalizeForWriting();
+
+ ASTContext &Context = SemaRef.Context;
+ Preprocessor &PP = SemaRef.PP;
+
+ // This needs to be done very early, since everything that writes
+ // SourceLocations or FileIDs depends on it.
+ computeNonAffectingInputFiles();
+
+ writeUnhashedControlBlock(PP, Context);
+
+ // Don't reuse type ID and Identifier ID from readers for C++ standard named
+ // modules since we want to support no-transitive-change model for named
+ // modules. The theory for no-transitive-change model is,
+ // for a user of a named module, the user can only access the indirectly
+ // imported decls via the directly imported module. So that it is possible to
+ // control what matters to the users when writing the module. It would be
+ // problematic if the users can reuse the type IDs and identifier IDs from
+ // indirectly imported modules arbitrarily. So we choose to clear these ID
+ // here.
+ if (isWritingStdCXXNamedModules()) {
+ TypeIdxs.clear();
+ IdentifierIDs.clear();
+ }
+
+ // Look for any identifiers that were named while processing the
+ // headers, but are otherwise not needed. We add these to the hash
+ // table to enable checking of the predefines buffer in the case
+ // where the user adds new macro definitions when building the AST
+ // file.
+ //
+ // We do this before emitting any Decl and Types to make sure the
+ // Identifier ID is stable.
+ SmallVector<const IdentifierInfo *, 128> IIs;
+ for (const auto &ID : PP.getIdentifierTable())
+ if (IsInterestingNonMacroIdentifier(ID.second, *this))
+ IIs.push_back(ID.second);
+ // Sort the identifiers lexicographically before getting the references so
+ // that their order is stable.
+ llvm::sort(IIs, llvm::deref<std::less<>>());
+ for (const IdentifierInfo *II : IIs)
+ getIdentifierRef(II);
+
+ // Write the set of weak, undeclared identifiers. We always write the
+ // entire table, since later PCH files in a PCH chain are only interested in
+ // the results at the end of the chain.
+ RecordData WeakUndeclaredIdentifiers;
+ for (const auto &WeakUndeclaredIdentifierList :
+ SemaRef.WeakUndeclaredIdentifiers) {
+ const IdentifierInfo *const II = WeakUndeclaredIdentifierList.first;
+ for (const auto &WI : WeakUndeclaredIdentifierList.second) {
+ AddIdentifierRef(II, WeakUndeclaredIdentifiers);
+ AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers);
+ AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers);
+ }
+ }
+
+ // Form the record of special types.
+ RecordData SpecialTypes;
+ AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
+ AddTypeRef(Context.getFILEType(), SpecialTypes);
+ AddTypeRef(Context.getjmp_bufType(), SpecialTypes);
+ AddTypeRef(Context.getsigjmp_bufType(), SpecialTypes);
+ AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes);
+ AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes);
+ AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
+ AddTypeRef(Context.getucontext_tType(), SpecialTypes);
+
+ PrepareWritingSpecialDecls(SemaRef);
// Write the control block
WriteControlBlock(PP, Context, isysroot);
@@ -4904,83 +5413,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
Stream.EmitRecord(METADATA_OLD_FORMAT, Record);
}
- // Create a lexical update block containing all of the declarations in the
- // translation unit that do not come from other AST files.
- const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
- SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
- for (const auto *D : TU->noload_decls()) {
- if (!D->isFromASTFile()) {
- NewGlobalKindDeclPairs.push_back(D->getKind());
- NewGlobalKindDeclPairs.push_back(GetDeclRef(D));
- }
- }
-
- auto Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
- unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
- {
- RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
- Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
- bytes(NewGlobalKindDeclPairs));
- }
-
- // And a visible updates block for the translation unit.
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
- UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
- WriteDeclContextVisibleUpdate(TU);
-
- // If we have any extern "C" names, write out a visible update for them.
- if (Context.ExternCContext)
- WriteDeclContextVisibleUpdate(Context.ExternCContext);
-
- // If the translation unit has an anonymous namespace, and we don't already
- // have an update block for it, write it as an update block.
- // FIXME: Why do we not do this if there's already an update block?
- if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
- ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
- if (Record.empty())
- Record.push_back(DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS));
- }
-
- // Add update records for all mangling numbers and static local numbers.
- // These aren't really update records, but this is a convenient way of
- // tagging this rare extra data onto the declarations.
- for (const auto &Number : Context.MangleNumbers)
- if (!Number.first->isFromASTFile())
- DeclUpdates[Number.first].push_back(DeclUpdate(UPD_MANGLING_NUMBER,
- Number.second));
- for (const auto &Number : Context.StaticLocalNumbers)
- if (!Number.first->isFromASTFile())
- DeclUpdates[Number.first].push_back(DeclUpdate(UPD_STATIC_LOCAL_NUMBER,
- Number.second));
-
- // Make sure visible decls, added to DeclContexts previously loaded from
- // an AST file, are registered for serialization. Likewise for template
- // specializations added to imported templates.
- for (const auto *I : DeclsToEmitEvenIfUnreferenced) {
- GetDeclRef(I);
- }
-
- // Make sure all decls associated with an identifier are registered for
- // serialization, if we're storing decls with identifiers.
- if (!WritingModule || !getLangOpts().CPlusPlus) {
- llvm::SmallVector<const IdentifierInfo*, 256> IIs;
- for (const auto &ID : PP.getIdentifierTable()) {
- const IdentifierInfo *II = ID.second;
- if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization())
- IIs.push_back(II);
- }
- // Sort the identifiers to visit based on their name.
- llvm::sort(IIs, llvm::deref<std::less<>>());
- for (const IdentifierInfo *II : IIs)
- for (const Decl *D : SemaRef.IdResolver.decls(II))
- GetDeclRef(D);
- }
-
// For method pool in the module, if it contains an entry for a selector,
// the entry should be complete, containing everything introduced by that
// module and all modules it imports. It's possible that the entry is out of
@@ -4992,18 +5424,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
for (auto &SelectorAndID : SelectorIDs)
AllSelectors.push_back(SelectorAndID.first);
for (auto &Selector : AllSelectors)
- SemaRef.updateOutOfDateSelector(Selector);
-
- // Form the record of special types.
- RecordData SpecialTypes;
- AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
- AddTypeRef(Context.getFILEType(), SpecialTypes);
- AddTypeRef(Context.getjmp_bufType(), SpecialTypes);
- AddTypeRef(Context.getsigjmp_bufType(), SpecialTypes);
- AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes);
- AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes);
- AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
- AddTypeRef(Context.getucontext_tType(), SpecialTypes);
+ SemaRef.ObjC().updateOutOfDateSelector(Selector);
if (Chain) {
// Write the mapping information describing our module dependencies and how
@@ -5055,15 +5476,11 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// These values should be unique within a chain, since they will be read
// as keys into ContinuousRangeMaps.
- writeBaseIDOrNone(M.SLocEntryBaseOffset, M.LocalNumSLocEntries);
- writeBaseIDOrNone(M.BaseIdentifierID, M.LocalNumIdentifiers);
writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros);
writeBaseIDOrNone(M.BasePreprocessedEntityID,
M.NumPreprocessedEntities);
writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
- writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls);
- writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes);
}
}
RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
@@ -5071,38 +5488,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
Buffer.data(), Buffer.size());
}
- // Build a record containing all of the DeclsToCheckForDeferredDiags.
- SmallVector<serialization::DeclID, 64> DeclsToCheckForDeferredDiags;
- for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
- DeclsToCheckForDeferredDiags.push_back(GetDeclRef(D));
+ WriteDeclAndTypes(Context);
- RecordData DeclUpdatesOffsetsRecord;
-
- // Keep writing types, declarations, and declaration update records
- // until we've emitted all of them.
- Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5);
- DeclTypesBlockStartOffset = Stream.GetCurrentBitNo();
- WriteTypeAbbrevs();
- WriteDeclAbbrevs();
- do {
- WriteDeclUpdatesBlocks(DeclUpdatesOffsetsRecord);
- while (!DeclTypesToEmit.empty()) {
- DeclOrType DOT = DeclTypesToEmit.front();
- DeclTypesToEmit.pop();
- if (DOT.isType())
- WriteType(DOT.getType());
- else
- WriteDecl(Context, DOT.getDecl());
- }
- } while (!DeclUpdates.empty());
- Stream.ExitBlock();
-
- DoneWritingDeclsAndTypes = true;
-
- // These things can only be done once we've written out decls and types.
- WriteTypeDeclOffsets();
- if (!DeclUpdatesOffsetsRecord.empty())
- Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
WriteFileDeclIDsMap();
WriteSourceManagerBlock(Context.getSourceManager(), PP);
WriteComments();
@@ -5122,75 +5509,13 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
- // Write the record containing external, unnamed definitions.
- if (!EagerlyDeserializedDecls.empty())
- Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
-
- if (!ModularCodegenDecls.empty())
- Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls);
-
- // Write the record containing tentative definitions.
- if (!TentativeDefinitions.empty())
- Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
-
- // Write the record containing unused file scoped decls.
- if (!UnusedFileScopedDecls.empty())
- Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
+ WriteSpecialDeclRecords(SemaRef);
// Write the record containing weak undeclared identifiers.
if (!WeakUndeclaredIdentifiers.empty())
Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
WeakUndeclaredIdentifiers);
- // Write the record containing ext_vector type names.
- if (!ExtVectorDecls.empty())
- Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
-
- // Write the record containing VTable uses information.
- if (!VTableUses.empty())
- Stream.EmitRecord(VTABLE_USES, VTableUses);
-
- // Write the record containing potentially unused local typedefs.
- if (!UnusedLocalTypedefNameCandidates.empty())
- Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
- UnusedLocalTypedefNameCandidates);
-
- // Write the record containing pending implicit instantiations.
- if (!PendingInstantiations.empty())
- Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
-
- // Write the record containing declaration references of Sema.
- if (!SemaDeclRefs.empty())
- Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
-
- // Write the record containing decls to be checked for deferred diags.
- if (!DeclsToCheckForDeferredDiags.empty())
- Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS,
- DeclsToCheckForDeferredDiags);
-
- // Write the record containing CUDA-specific declaration references.
- if (!CUDASpecialDeclRefs.empty())
- Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs);
-
- // Write the delegating constructors.
- if (!DelegatingCtorDecls.empty())
- Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
-
- // Write the known namespaces.
- if (!KnownNamespaces.empty())
- Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
-
- // Write the undefined internal functions and variables, and inline functions.
- if (!UndefinedButUsed.empty())
- Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
-
- if (!DeleteExprsToAnalyze.empty())
- Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
-
- // Write the visible updates to DeclContexts.
- for (auto *DC : UpdatedDeclContexts)
- WriteDeclContextVisibleUpdate(DC);
-
if (!WritingModule) {
// Write the submodules that were imported, if any.
struct ModuleInfo {
@@ -5255,6 +5580,142 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
return backpatchSignature();
}
+void ASTWriter::EnteringModulePurview() {
+ // In C++20 named modules, all entities before entering the module purview
+ // lives in the GMF.
+ if (GeneratingReducedBMI)
+ DeclUpdatesFromGMF.swap(DeclUpdates);
+}
+
+// Add update records for all mangling numbers and static local numbers.
+// These aren't really update records, but this is a convenient way of
+// tagging this rare extra data onto the declarations.
+void ASTWriter::AddedManglingNumber(const Decl *D, unsigned Number) {
+ if (D->isFromASTFile())
+ return;
+
+ DeclUpdates[D].push_back(DeclUpdate(UPD_MANGLING_NUMBER, Number));
+}
+void ASTWriter::AddedStaticLocalNumbers(const Decl *D, unsigned Number) {
+ if (D->isFromASTFile())
+ return;
+
+ DeclUpdates[D].push_back(DeclUpdate(UPD_STATIC_LOCAL_NUMBER, Number));
+}
+
+void ASTWriter::AddedAnonymousNamespace(const TranslationUnitDecl *TU,
+ NamespaceDecl *AnonNamespace) {
+ // If the translation unit has an anonymous namespace, and we don't already
+ // have an update block for it, write it as an update block.
+ // FIXME: Why do we not do this if there's already an update block?
+ if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
+ ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
+ if (Record.empty())
+ Record.push_back(DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS));
+ }
+}
+
+void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
+ // Keep writing types, declarations, and declaration update records
+ // until we've emitted all of them.
+ RecordData DeclUpdatesOffsetsRecord;
+ Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5);
+ DeclTypesBlockStartOffset = Stream.GetCurrentBitNo();
+ WriteTypeAbbrevs();
+ WriteDeclAbbrevs();
+ do {
+ WriteDeclUpdatesBlocks(DeclUpdatesOffsetsRecord);
+ while (!DeclTypesToEmit.empty()) {
+ DeclOrType DOT = DeclTypesToEmit.front();
+ DeclTypesToEmit.pop();
+ if (DOT.isType())
+ WriteType(DOT.getType());
+ else
+ WriteDecl(Context, DOT.getDecl());
+ }
+ } while (!DeclUpdates.empty());
+
+ DoneWritingDeclsAndTypes = true;
+
+ // DelayedNamespace is only meaningful in reduced BMI.
+ // See the comments of DelayedNamespace for details.
+ assert(DelayedNamespace.empty() || GeneratingReducedBMI);
+ RecordData DelayedNamespaceRecord;
+ for (NamespaceDecl *NS : DelayedNamespace) {
+ uint64_t LexicalOffset = WriteDeclContextLexicalBlock(Context, NS);
+ uint64_t VisibleOffset = WriteDeclContextVisibleBlock(Context, NS);
+
+ // Write the offset relative to current block.
+ if (LexicalOffset)
+ LexicalOffset -= DeclTypesBlockStartOffset;
+
+ if (VisibleOffset)
+ VisibleOffset -= DeclTypesBlockStartOffset;
+
+ AddDeclRef(NS, DelayedNamespaceRecord);
+ DelayedNamespaceRecord.push_back(LexicalOffset);
+ DelayedNamespaceRecord.push_back(VisibleOffset);
+ }
+
+ // The process of writing lexical and visible block for delayed namespace
+ // shouldn't introduce any new decls, types or update to emit.
+ assert(DeclTypesToEmit.empty());
+ assert(DeclUpdates.empty());
+
+ Stream.ExitBlock();
+
+ // These things can only be done once we've written out decls and types.
+ WriteTypeDeclOffsets();
+ if (!DeclUpdatesOffsetsRecord.empty())
+ Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
+
+ if (!DelayedNamespaceRecord.empty())
+ Stream.EmitRecord(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD,
+ DelayedNamespaceRecord);
+
+ const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+ // Create a lexical update block containing all of the declarations in the
+ // translation unit that do not come from other AST files.
+ SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
+ for (const auto *D : TU->noload_decls()) {
+ if (D->isFromASTFile())
+ continue;
+
+ // In reduced BMI, skip unreached declarations.
+ if (!wasDeclEmitted(D))
+ continue;
+
+ NewGlobalKindDeclPairs.push_back(D->getKind());
+ NewGlobalKindDeclPairs.push_back(GetDeclRef(D).getRawValue());
+ }
+
+ auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
+ Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
+ Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+ unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
+ Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
+ bytes(NewGlobalKindDeclPairs));
+
+ Abv = std::make_shared<llvm::BitCodeAbbrev>();
+ Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
+ Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
+ Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
+ UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
+
+ // And a visible updates block for the translation unit.
+ WriteDeclContextVisibleUpdate(TU);
+
+ // If we have any extern "C" names, write out a visible update for them.
+ if (Context.ExternCContext)
+ WriteDeclContextVisibleUpdate(Context.ExternCContext);
+
+ // Write the visible updates to DeclContexts.
+ for (auto *DC : UpdatedDeclContexts)
+ WriteDeclContextVisibleUpdate(DC);
+}
+
void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
if (DeclUpdates.empty())
return;
@@ -5286,7 +5747,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
assert(Update.getDecl() && "no decl to add?");
- Record.push_back(GetDeclRef(Update.getDecl()));
+ Record.AddDeclRef(Update.getDecl());
break;
case UPD_CXX_ADDED_FUNCTION_DEFINITION:
@@ -5299,8 +5760,8 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
break;
case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT:
- Record.AddStmt(const_cast<Expr *>(
- cast<ParmVarDecl>(Update.getDecl())->getDefaultArg()));
+ Record.writeStmtRef(
+ cast<ParmVarDecl>(Update.getDecl())->getDefaultArg());
break;
case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER:
@@ -5314,8 +5775,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
Record.push_back(RD->isParamDestroyedInCallee());
Record.push_back(llvm::to_underlying(RD->getArgPassingRestrictions()));
Record.AddCXXDefinitionData(RD);
- Record.AddOffset(WriteDeclContextLexicalBlock(
- *Context, const_cast<CXXRecordDecl *>(RD)));
+ Record.AddOffset(WriteDeclContextLexicalBlock(*Context, RD));
// This state is sometimes updated by template instantiation, when we
// switch from the specialization referring to the template declaration
@@ -5411,21 +5871,23 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
// Add a trailing update record, if any. These must go last because we
// lazily load their attached statement.
- if (HasUpdatedBody) {
- const auto *Def = cast<FunctionDecl>(D);
- Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
- Record.push_back(Def->isInlined());
- Record.AddSourceLocation(Def->getInnerLocStart());
- Record.AddFunctionDefinition(Def);
- } else if (HasAddedVarDefinition) {
- const auto *VD = cast<VarDecl>(D);
- Record.push_back(UPD_CXX_ADDED_VAR_DEFINITION);
- Record.push_back(VD->isInline());
- Record.push_back(VD->isInlineSpecified());
- Record.AddVarDeclInit(VD);
+ if (!GeneratingReducedBMI || !CanElideDeclDef(D)) {
+ if (HasUpdatedBody) {
+ const auto *Def = cast<FunctionDecl>(D);
+ Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
+ Record.push_back(Def->isInlined());
+ Record.AddSourceLocation(Def->getInnerLocStart());
+ Record.AddFunctionDefinition(Def);
+ } else if (HasAddedVarDefinition) {
+ const auto *VD = cast<VarDecl>(D);
+ Record.push_back(UPD_CXX_ADDED_VAR_DEFINITION);
+ Record.push_back(VD->isInline());
+ Record.push_back(VD->isInlineSpecified());
+ Record.AddVarDeclInit(VD);
+ }
}
- OffsetsRecord.push_back(GetDeclRef(D));
+ AddDeclRef(D, OffsetsRecord);
OffsetsRecord.push_back(Record.Emit(DECL_UPDATES));
}
}
@@ -5502,10 +5964,34 @@ void ASTWriter::AddFileID(FileID FID, RecordDataImpl &Record) {
Record.push_back(getAdjustedFileID(FID).getOpaqueValue());
}
+SourceLocationEncoding::RawLocEncoding
+ASTWriter::getRawSourceLocationEncoding(SourceLocation Loc, LocSeq *Seq) {
+ unsigned BaseOffset = 0;
+ unsigned ModuleFileIndex = 0;
+
+ // See SourceLocationEncoding.h for the encoding details.
+ if (Context->getSourceManager().isLoadedSourceLocation(Loc) &&
+ Loc.isValid()) {
+ assert(getChain());
+ auto SLocMapI = getChain()->GlobalSLocOffsetMap.find(
+ SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
+ assert(SLocMapI != getChain()->GlobalSLocOffsetMap.end() &&
+ "Corrupted global sloc offset map");
+ ModuleFile *F = SLocMapI->second;
+ BaseOffset = F->SLocEntryBaseOffset - 2;
+ // 0 means the location is not loaded. So we need to add 1 to the index to
+ // make it clear.
+ ModuleFileIndex = F->Index + 1;
+ assert(&getChain()->getModuleManager()[F->Index] == F);
+ }
+
+ return SourceLocationEncoding::encode(Loc, BaseOffset, ModuleFileIndex, Seq);
+}
+
void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record,
SourceLocationSequence *Seq) {
Loc = getAdjustedLocation(Loc);
- Record.push_back(SourceLocationEncoding::encode(Loc, Seq));
+ Record.push_back(getRawSourceLocationEncoding(Loc, Seq));
}
void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record,
@@ -5522,11 +6008,11 @@ void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Recor
Record.push_back(getIdentifierRef(II));
}
-IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
+IdentifierID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
if (!II)
return 0;
- IdentID &ID = IdentifierIDs[II];
+ IdentifierID &ID = IdentifierIDs[II];
if (ID == 0)
ID = NextIdentID++;
return ID;
@@ -5650,6 +6136,31 @@ void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) {
Record.push_back(GetOrCreateTypeID(T));
}
+template <typename IdxForTypeTy>
+static TypeID MakeTypeID(ASTContext &Context, QualType T,
+ IdxForTypeTy IdxForType) {
+ if (T.isNull())
+ return PREDEF_TYPE_NULL_ID;
+
+ unsigned FastQuals = T.getLocalFastQualifiers();
+ T.removeLocalFastQualifiers();
+
+ if (T.hasLocalNonFastQualifiers())
+ return IdxForType(T).asTypeID(FastQuals);
+
+ assert(!T.hasLocalQualifiers());
+
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
+ return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
+
+ if (T == Context.AutoDeductTy)
+ return TypeIdx(0, PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
+ if (T == Context.AutoRRefDeductTy)
+ return TypeIdx(0, PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
+
+ return IdxForType(T).asTypeID(FastQuals);
+}
+
TypeID ASTWriter::GetOrCreateTypeID(QualType T) {
assert(Context);
return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx {
@@ -5658,7 +6169,7 @@ TypeID ASTWriter::GetOrCreateTypeID(QualType T) {
assert(!T.getLocalFastQualifiers());
TypeIdx &Idx = TypeIdxs[T];
- if (Idx.getIndex() == 0) {
+ if (Idx.getValue() == 0) {
if (DoneWritingDeclsAndTypes) {
assert(0 && "New type seen after serializing all the types to emit!");
return TypeIdx();
@@ -5666,48 +6177,54 @@ TypeID ASTWriter::GetOrCreateTypeID(QualType T) {
// We haven't seen this type before. Assign it a new ID and put it
// into the queue of types to emit.
- Idx = TypeIdx(NextTypeID++);
+ Idx = TypeIdx(0, NextTypeID++);
DeclTypesToEmit.push(T);
}
return Idx;
});
}
-TypeID ASTWriter::getTypeID(QualType T) const {
- assert(Context);
- return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx {
- if (T.isNull())
- return TypeIdx();
- assert(!T.getLocalFastQualifiers());
+void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
+ if (!wasDeclEmitted(D))
+ return;
- TypeIdxMap::const_iterator I = TypeIdxs.find(T);
- assert(I != TypeIdxs.end() && "Type not emitted!");
- return I->second;
- });
+ AddDeclRef(D, Record);
}
void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
- Record.push_back(GetDeclRef(D));
+ Record.push_back(GetDeclRef(D).getRawValue());
}
-DeclID ASTWriter::GetDeclRef(const Decl *D) {
+LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
assert(WritingAST && "Cannot request a declaration ID before AST writing");
if (!D) {
- return 0;
+ return LocalDeclID();
+ }
+
+ // If the DeclUpdate from the GMF gets touched, emit it.
+ if (auto *Iter = DeclUpdatesFromGMF.find(D);
+ Iter != DeclUpdatesFromGMF.end()) {
+ for (DeclUpdate &Update : Iter->second)
+ DeclUpdates[D].push_back(Update);
+ DeclUpdatesFromGMF.erase(Iter);
}
// If D comes from an AST file, its declaration ID is already known and
// fixed.
- if (D->isFromASTFile())
- return D->getGlobalID();
+ if (D->isFromASTFile()) {
+ if (isWritingStdCXXNamedModules() && D->getOwningModule())
+ TouchedTopLevelModules.insert(D->getOwningModule()->getTopLevelModule());
+
+ return LocalDeclID(D->getGlobalID());
+ }
assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
- DeclID &ID = DeclIDs[D];
- if (ID == 0) {
+ LocalDeclID &ID = DeclIDs[D];
+ if (ID.isInvalid()) {
if (DoneWritingDeclsAndTypes) {
assert(0 && "New decl seen after serializing all the decls to emit!");
- return 0;
+ return LocalDeclID();
}
// We haven't seen this declaration before. Give it a new ID and
@@ -5719,21 +6236,37 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) {
return ID;
}
-DeclID ASTWriter::getDeclID(const Decl *D) {
+LocalDeclID ASTWriter::getDeclID(const Decl *D) {
if (!D)
- return 0;
+ return LocalDeclID();
// If D comes from an AST file, its declaration ID is already known and
// fixed.
if (D->isFromASTFile())
- return D->getGlobalID();
+ return LocalDeclID(D->getGlobalID());
assert(DeclIDs.contains(D) && "Declaration not emitted!");
return DeclIDs[D];
}
-void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) {
- assert(ID);
+bool ASTWriter::wasDeclEmitted(const Decl *D) const {
+ assert(D);
+
+ assert(DoneWritingDeclsAndTypes &&
+ "wasDeclEmitted should only be called after writing declarations");
+
+ if (D->isFromASTFile())
+ return true;
+
+ bool Emitted = DeclIDs.contains(D);
+ assert((Emitted || (!D->getOwningModule() && isWritingStdCXXNamedModules()) ||
+ GeneratingReducedBMI) &&
+ "The declaration within modules can only be omitted in reduced BMI.");
+ return Emitted;
+}
+
+void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) {
+ assert(ID.isValid());
assert(D);
SourceLocation Loc = D->getLocation();
@@ -5765,7 +6298,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) {
if (!Info)
Info = std::make_unique<DeclIDInFileInfo>();
- std::pair<unsigned, serialization::DeclID> LocDecl(Offset, ID);
+ std::pair<unsigned, LocalDeclID> LocDecl(Offset, ID);
LocDeclIDsTy &Decls = Info->DeclIDs;
Decls.push_back(LocDecl);
}
@@ -5898,7 +6431,7 @@ void ASTRecordWriter::AddTemplateParameterList(
AddDeclRef(P);
if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) {
Record->push_back(true);
- AddStmt(const_cast<Expr*>(RequiresClause));
+ writeStmtRef(RequiresClause);
} else {
Record->push_back(false);
}
@@ -6010,9 +6543,6 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
BitsPacker DefinitionBits;
- bool ShouldSkipCheckingODR = D->shouldSkipCheckingODR();
- DefinitionBits.addBit(ShouldSkipCheckingODR);
-
#define FIELD(Name, Width, Merge) \
if (!DefinitionBits.canWriteNextNBits(Width)) { \
Record->push_back(DefinitionBits); \
@@ -6025,17 +6555,15 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
Record->push_back(DefinitionBits);
- // We only perform ODR checks for decls not in GMF.
- if (!ShouldSkipCheckingODR)
- // getODRHash will compute the ODRHash if it has not been previously
- // computed.
- Record->push_back(D->getODRHash());
+ // getODRHash will compute the ODRHash if it has not been previously
+ // computed.
+ Record->push_back(D->getODRHash());
bool ModulesDebugInfo =
Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType();
Record->push_back(ModulesDebugInfo);
if (ModulesDebugInfo)
- Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D));
+ Writer->AddDeclRef(D, Writer->ModularCodegenDecls);
// IsLambda bit is already saved.
@@ -6139,23 +6667,30 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) {
// Note, this will get called multiple times, once one the reader starts up
// and again each time it's done reading a PCH or module.
- FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();
- FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();
- FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();
FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros();
FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
- NextDeclID = FirstDeclID;
- NextTypeID = FirstTypeID;
- NextIdentID = FirstIdentID;
NextMacroID = FirstMacroID;
NextSelectorID = FirstSelectorID;
NextSubmoduleID = FirstSubmoduleID;
}
-void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
- // Always keep the highest ID. See \p TypeRead() for more information.
- IdentID &StoredID = IdentifierIDs[II];
+void ASTWriter::IdentifierRead(IdentifierID ID, IdentifierInfo *II) {
+ // Don't reuse Type ID from external modules for named modules. See the
+ // comments in WriteASTCore for details.
+ if (isWritingStdCXXNamedModules())
+ return;
+
+ IdentifierID &StoredID = IdentifierIDs[II];
+ unsigned OriginalModuleFileIndex = StoredID >> 32;
+
+ // Always keep the local identifier ID. See \p TypeRead() for more
+ // information.
+ if (OriginalModuleFileIndex == 0 && StoredID)
+ return;
+
+ // Otherwise, keep the highest ID since the module file comes later has
+ // higher module file indexes.
if (ID > StoredID)
StoredID = ID;
}
@@ -6168,13 +6703,29 @@ void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
}
void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
- // Always take the highest-numbered type index. This copes with an interesting
+ // Don't reuse Type ID from external modules for named modules. See the
+ // comments in WriteASTCore for details.
+ if (isWritingStdCXXNamedModules())
+ return;
+
+ // Always take the type index that comes in later module files.
+ // This copes with an interesting
// case for chained AST writing where we schedule writing the type and then,
// later, deserialize the type from another AST. In this case, we want to
- // keep the higher-numbered entry so that we can properly write it out to
+ // keep the entry from a later module so that we can properly write it out to
// the AST file.
TypeIdx &StoredIdx = TypeIdxs[T];
- if (Idx.getIndex() >= StoredIdx.getIndex())
+
+ // Ignore it if the type comes from the current being written module file.
+ // Since the current module file being written logically has the highest
+ // index.
+ unsigned ModuleFileIndex = StoredIdx.getModuleFileIndex();
+ if (ModuleFileIndex == 0 && StoredIdx.getValue())
+ return;
+
+ // Otherwise, keep the highest ID since the module file comes later has
+ // higher module file indexes.
+ if (Idx.getModuleFileIndex() >= StoredIdx.getModuleFileIndex())
StoredIdx = Idx;
}
@@ -6659,6 +7210,8 @@ void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {}
void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
+void OMPClauseWriter::VisitOMPWeakClause(OMPWeakClause *) {}
+
void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
@@ -7325,3 +7878,208 @@ void ASTRecordWriter::writeOMPChildren(OMPChildren *Data) {
for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I)
AddStmt(Data->getChildren()[I]);
}
+
+void ASTRecordWriter::writeOpenACCVarList(const OpenACCClauseWithVarList *C) {
+ writeUInt32(C->getVarList().size());
+ for (Expr *E : C->getVarList())
+ AddStmt(E);
+}
+
+void ASTRecordWriter::writeOpenACCIntExprList(ArrayRef<Expr *> Exprs) {
+ writeUInt32(Exprs.size());
+ for (Expr *E : Exprs)
+ AddStmt(E);
+}
+
+void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
+ writeEnum(C->getClauseKind());
+ writeSourceLocation(C->getBeginLoc());
+ writeSourceLocation(C->getEndLoc());
+
+ switch (C->getClauseKind()) {
+ case OpenACCClauseKind::Default: {
+ const auto *DC = cast<OpenACCDefaultClause>(C);
+ writeSourceLocation(DC->getLParenLoc());
+ writeEnum(DC->getDefaultClauseKind());
+ return;
+ }
+ case OpenACCClauseKind::If: {
+ const auto *IC = cast<OpenACCIfClause>(C);
+ writeSourceLocation(IC->getLParenLoc());
+ AddStmt(const_cast<Expr*>(IC->getConditionExpr()));
+ return;
+ }
+ case OpenACCClauseKind::Self: {
+ const auto *SC = cast<OpenACCSelfClause>(C);
+ writeSourceLocation(SC->getLParenLoc());
+ writeBool(SC->hasConditionExpr());
+ if (SC->hasConditionExpr())
+ AddStmt(const_cast<Expr*>(SC->getConditionExpr()));
+ return;
+ }
+ case OpenACCClauseKind::NumGangs: {
+ const auto *NGC = cast<OpenACCNumGangsClause>(C);
+ writeSourceLocation(NGC->getLParenLoc());
+ writeUInt32(NGC->getIntExprs().size());
+ for (Expr *E : NGC->getIntExprs())
+ AddStmt(E);
+ return;
+ }
+ case OpenACCClauseKind::NumWorkers: {
+ const auto *NWC = cast<OpenACCNumWorkersClause>(C);
+ writeSourceLocation(NWC->getLParenLoc());
+ AddStmt(const_cast<Expr*>(NWC->getIntExpr()));
+ return;
+ }
+ case OpenACCClauseKind::VectorLength: {
+ const auto *NWC = cast<OpenACCVectorLengthClause>(C);
+ writeSourceLocation(NWC->getLParenLoc());
+ AddStmt(const_cast<Expr*>(NWC->getIntExpr()));
+ return;
+ }
+ case OpenACCClauseKind::Private: {
+ const auto *PC = cast<OpenACCPrivateClause>(C);
+ writeSourceLocation(PC->getLParenLoc());
+ writeOpenACCVarList(PC);
+ return;
+ }
+ case OpenACCClauseKind::FirstPrivate: {
+ const auto *FPC = cast<OpenACCFirstPrivateClause>(C);
+ writeSourceLocation(FPC->getLParenLoc());
+ writeOpenACCVarList(FPC);
+ return;
+ }
+ case OpenACCClauseKind::Attach: {
+ const auto *AC = cast<OpenACCAttachClause>(C);
+ writeSourceLocation(AC->getLParenLoc());
+ writeOpenACCVarList(AC);
+ return;
+ }
+ case OpenACCClauseKind::DevicePtr: {
+ const auto *DPC = cast<OpenACCDevicePtrClause>(C);
+ writeSourceLocation(DPC->getLParenLoc());
+ writeOpenACCVarList(DPC);
+ return;
+ }
+ case OpenACCClauseKind::NoCreate: {
+ const auto *NCC = cast<OpenACCNoCreateClause>(C);
+ writeSourceLocation(NCC->getLParenLoc());
+ writeOpenACCVarList(NCC);
+ return;
+ }
+ case OpenACCClauseKind::Present: {
+ const auto *PC = cast<OpenACCPresentClause>(C);
+ writeSourceLocation(PC->getLParenLoc());
+ writeOpenACCVarList(PC);
+ return;
+ }
+ case OpenACCClauseKind::Copy:
+ case OpenACCClauseKind::PCopy:
+ case OpenACCClauseKind::PresentOrCopy: {
+ const auto *CC = cast<OpenACCCopyClause>(C);
+ writeSourceLocation(CC->getLParenLoc());
+ writeOpenACCVarList(CC);
+ return;
+ }
+ case OpenACCClauseKind::CopyIn:
+ case OpenACCClauseKind::PCopyIn:
+ case OpenACCClauseKind::PresentOrCopyIn: {
+ const auto *CIC = cast<OpenACCCopyInClause>(C);
+ writeSourceLocation(CIC->getLParenLoc());
+ writeBool(CIC->isReadOnly());
+ writeOpenACCVarList(CIC);
+ return;
+ }
+ case OpenACCClauseKind::CopyOut:
+ case OpenACCClauseKind::PCopyOut:
+ case OpenACCClauseKind::PresentOrCopyOut: {
+ const auto *COC = cast<OpenACCCopyOutClause>(C);
+ writeSourceLocation(COC->getLParenLoc());
+ writeBool(COC->isZero());
+ writeOpenACCVarList(COC);
+ return;
+ }
+ case OpenACCClauseKind::Create:
+ case OpenACCClauseKind::PCreate:
+ case OpenACCClauseKind::PresentOrCreate: {
+ const auto *CC = cast<OpenACCCreateClause>(C);
+ writeSourceLocation(CC->getLParenLoc());
+ writeBool(CC->isZero());
+ writeOpenACCVarList(CC);
+ return;
+ }
+ case OpenACCClauseKind::Async: {
+ const auto *AC = cast<OpenACCAsyncClause>(C);
+ writeSourceLocation(AC->getLParenLoc());
+ writeBool(AC->hasIntExpr());
+ if (AC->hasIntExpr())
+ AddStmt(const_cast<Expr*>(AC->getIntExpr()));
+ return;
+ }
+ case OpenACCClauseKind::Wait: {
+ const auto *WC = cast<OpenACCWaitClause>(C);
+ writeSourceLocation(WC->getLParenLoc());
+ writeBool(WC->getDevNumExpr());
+ if (Expr *DNE = WC->getDevNumExpr())
+ AddStmt(DNE);
+ writeSourceLocation(WC->getQueuesLoc());
+
+ writeOpenACCIntExprList(WC->getQueueIdExprs());
+ return;
+ }
+ case OpenACCClauseKind::DeviceType:
+ case OpenACCClauseKind::DType: {
+ const auto *DTC = cast<OpenACCDeviceTypeClause>(C);
+ writeSourceLocation(DTC->getLParenLoc());
+ writeUInt32(DTC->getArchitectures().size());
+ for (const DeviceTypeArgument &Arg : DTC->getArchitectures()) {
+ writeBool(Arg.first);
+ if (Arg.first)
+ AddIdentifierRef(Arg.first);
+ writeSourceLocation(Arg.second);
+ }
+ return;
+ }
+ case OpenACCClauseKind::Reduction: {
+ const auto *RC = cast<OpenACCReductionClause>(C);
+ writeSourceLocation(RC->getLParenLoc());
+ writeEnum(RC->getReductionOp());
+ writeOpenACCVarList(RC);
+ return;
+ }
+ case OpenACCClauseKind::Seq:
+ case OpenACCClauseKind::Independent:
+ case OpenACCClauseKind::Auto:
+ // Nothing to do here, there is no additional information beyond the
+ // begin/end loc and clause kind.
+ return;
+
+ case OpenACCClauseKind::Finalize:
+ case OpenACCClauseKind::IfPresent:
+ case OpenACCClauseKind::Worker:
+ case OpenACCClauseKind::Vector:
+ case OpenACCClauseKind::NoHost:
+ case OpenACCClauseKind::UseDevice:
+ case OpenACCClauseKind::Delete:
+ case OpenACCClauseKind::Detach:
+ case OpenACCClauseKind::Device:
+ case OpenACCClauseKind::DeviceResident:
+ case OpenACCClauseKind::Host:
+ case OpenACCClauseKind::Link:
+ case OpenACCClauseKind::Collapse:
+ case OpenACCClauseKind::Bind:
+ case OpenACCClauseKind::DeviceNum:
+ case OpenACCClauseKind::DefaultAsync:
+ case OpenACCClauseKind::Tile:
+ case OpenACCClauseKind::Gang:
+ case OpenACCClauseKind::Invalid:
+ llvm_unreachable("Clause serialization not yet implemented");
+ }
+ llvm_unreachable("Invalid Clause Kind");
+}
+
+void ASTRecordWriter::writeOpenACCClauseList(
+ ArrayRef<const OpenACCClause *> Clauses) {
+ for (const OpenACCClause *Clause : Clauses)
+ writeOpenACCClause(Clause);
+}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
index 42583c09f009..17c774038571 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -40,11 +40,14 @@ namespace clang {
serialization::DeclCode Code;
unsigned AbbrevToUse;
+ bool GeneratingReducedBMI = false;
+
public:
ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
- ASTWriter::RecordDataImpl &Record)
+ ASTWriter::RecordDataImpl &Record, bool GeneratingReducedBMI)
: Writer(Writer), Context(Context), Record(Writer, Record),
- Code((serialization::DeclCode)0), AbbrevToUse(0) {}
+ Code((serialization::DeclCode)0), AbbrevToUse(0),
+ GeneratingReducedBMI(GeneratingReducedBMI) {}
uint64_t Emit(Decl *D) {
if (!Code)
@@ -220,9 +223,9 @@ namespace clang {
assert(!Common->LazySpecializations);
}
- ArrayRef<DeclID> LazySpecializations;
+ ArrayRef<GlobalDeclID> LazySpecializations;
if (auto *LS = Common->LazySpecializations)
- LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]);
+ LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].getRawValue());
// Add a slot to the record for the number of specializations.
unsigned I = Record.size();
@@ -240,7 +243,9 @@ namespace clang {
assert(D->isCanonicalDecl() && "non-canonical decl in set");
AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
}
- Record.append(LazySpecializations.begin(), LazySpecializations.end());
+ Record.append(
+ DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.begin()),
+ DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.end()));
// Update the size entry we added earlier.
Record[I] = Record.size() - I - 1;
@@ -270,6 +275,34 @@ namespace clang {
};
}
+bool clang::CanElideDeclDef(const Decl *D) {
+ if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->isInlined() || FD->isConstexpr())
+ return false;
+
+ if (FD->isDependentContext())
+ return false;
+
+ if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return false;
+ }
+
+ if (auto *VD = dyn_cast<VarDecl>(D)) {
+ if (!VD->getDeclContext()->getRedeclContext()->isFileContext() ||
+ VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(VD) ||
+ // Constant initialized variable may not affect the ABI, but they
+ // may be used in constant evaluation in the frontend, so we have
+ // to remain them.
+ VD->hasConstantInitialization())
+ return false;
+
+ if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return false;
+ }
+
+ return true;
+}
+
void ASTDeclWriter::Visit(Decl *D) {
DeclVisitor<ASTDeclWriter>::Visit(D);
@@ -285,9 +318,12 @@ void ASTDeclWriter::Visit(Decl *D) {
// have been written. We want it last because we will not read it back when
// retrieving it from the AST, we'll just lazily set the offset.
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
- Record.push_back(FD->doesThisDeclarationHaveABody());
- if (FD->doesThisDeclarationHaveABody())
- Record.AddFunctionDefinition(FD);
+ if (!GeneratingReducedBMI || !CanElideDeclDef(FD)) {
+ Record.push_back(FD->doesThisDeclarationHaveABody());
+ if (FD->doesThisDeclarationHaveABody())
+ Record.AddFunctionDefinition(FD);
+ } else
+ Record.push_back(0);
}
// Similar to FunctionDecls, handle VarDecl's initializer here and write it
@@ -295,7 +331,10 @@ void ASTDeclWriter::Visit(Decl *D) {
// we have finished recursive deserialization, because it can recursively
// refer back to the variable.
if (auto *VD = dyn_cast<VarDecl>(D)) {
- Record.AddVarDeclInit(VD);
+ if (!GeneratingReducedBMI || !CanElideDeclDef(VD))
+ Record.AddVarDeclInit(VD);
+ else
+ Record.push_back(0);
}
// And similarly for FieldDecls. We already serialized whether there is a
@@ -488,16 +527,12 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
BitsPacker EnumDeclBits;
EnumDeclBits.addBits(D->getNumPositiveBits(), /*BitWidth=*/8);
EnumDeclBits.addBits(D->getNumNegativeBits(), /*BitWidth=*/8);
- bool ShouldSkipCheckingODR = D->shouldSkipCheckingODR();
- EnumDeclBits.addBit(ShouldSkipCheckingODR);
EnumDeclBits.addBit(D->isScoped());
EnumDeclBits.addBit(D->isScopedUsingClassTag());
EnumDeclBits.addBit(D->isFixed());
Record.push_back(EnumDeclBits);
- // We only perform ODR checks for decls not in GMF.
- if (!ShouldSkipCheckingODR)
- Record.push_back(D->getODRHash());
+ Record.push_back(D->getODRHash());
if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
@@ -514,7 +549,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
!D->isTopLevelDeclInObjCContainer() &&
!CXXRecordDecl::classofKind(D->getKind()) &&
!D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() &&
- !needsAnonymousDeclarationNumber(D) && !D->shouldSkipCheckingODR() &&
+ !needsAnonymousDeclarationNumber(D) &&
D->getDeclName().getNameKind() == DeclarationName::Identifier)
AbbrevToUse = Writer.getDeclEnumAbbrev();
@@ -680,8 +715,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
// FIXME: stable encoding
FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3);
FunctionDeclBits.addBits((uint32_t)D->getStorageClass(), /*BitWidth=*/3);
- bool ShouldSkipCheckingODR = D->shouldSkipCheckingODR();
- FunctionDeclBits.addBit(ShouldSkipCheckingODR);
FunctionDeclBits.addBit(D->isInlineSpecified());
FunctionDeclBits.addBit(D->isInlined());
FunctionDeclBits.addBit(D->hasSkippedBody());
@@ -707,12 +740,17 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
if (D->isExplicitlyDefaulted())
Record.AddSourceLocation(D->getDefaultLoc());
- // We only perform ODR checks for decls not in GMF.
- if (!ShouldSkipCheckingODR)
- Record.push_back(D->getODRHash());
+ Record.push_back(D->getODRHash());
+
+ if (D->isDefaulted() || D->isDeletedAsWritten()) {
+ if (auto *FDI = D->getDefalutedOrDeletedInfo()) {
+ // Store both that there is an DefaultedOrDeletedInfo and whether it
+ // contains a DeletedMessage.
+ StringLiteral *DeletedMessage = FDI->getDeletedMessage();
+ Record.push_back(1 | (DeletedMessage ? 2 : 0));
+ if (DeletedMessage)
+ Record.AddStmt(DeletedMessage);
- if (D->isDefaulted()) {
- if (auto *FDI = D->getDefaultedFunctionInfo()) {
Record.push_back(FDI->getUnqualifiedLookups().size());
for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
Record.AddDeclRef(P.getDecl());
@@ -1122,7 +1160,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
Record.push_back(VarDeclBits);
if (ModulesCodegen)
- Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
+ Writer.AddDeclRef(D, Writer.ModularCodegenDecls);
if (D->hasAttr<BlocksAttr>()) {
BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
@@ -1337,7 +1375,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
Record.AddSourceLocation(D->getBeginLoc());
Record.AddSourceLocation(D->getRBraceLoc());
- if (D->isOriginalNamespace())
+ if (D->isFirstDecl())
Record.AddDeclRef(D->getAnonymousNamespace());
Code = serialization::DECL_NAMESPACE;
@@ -1514,8 +1552,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
!D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->shouldSkipCheckingODR() && !D->hasExtInfo() &&
- !D->isExplicitlyDefaulted()) {
+ !D->hasExtInfo() && !D->isExplicitlyDefaulted()) {
if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate ||
D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate ||
D->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
@@ -1681,6 +1718,15 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (D->isFirstDecl())
AddTemplateSpecializations(D);
+
+ // Force emitting the corresponding deduction guide in reduced BMI mode.
+ // Otherwise, the deduction guide may be optimized out incorrectly.
+ if (Writer.isGeneratingReducedBMI()) {
+ auto Name = Context.DeclarationNames.getCXXDeductionGuideName(D);
+ for (auto *DG : D->getDeclContext()->noload_lookup(Name))
+ Writer.GetDeclRef(DG->getCanonicalDecl());
+ }
+
Code = serialization::DECL_CLASS_TEMPLATE;
}
@@ -1710,20 +1756,28 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
}
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
+ bool ExplicitInstantiation =
+ D->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration ||
+ D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
+ Record.push_back(ExplicitInstantiation);
+ if (ExplicitInstantiation) {
+ Record.AddSourceLocation(D->getExternKeywordLoc());
Record.AddSourceLocation(D->getTemplateKeywordLoc());
}
+ const ASTTemplateArgumentListInfo *ArgsWritten =
+ D->getTemplateArgsAsWritten();
+ Record.push_back(!!ArgsWritten);
+ if (ArgsWritten)
+ Record.AddASTTemplateArgumentListInfo(ArgsWritten);
+
Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
}
void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
Record.AddTemplateParameterList(D->getTemplateParameters());
- Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
VisitClassTemplateSpecializationDecl(D);
@@ -1757,13 +1811,22 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
}
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
+ bool ExplicitInstantiation =
+ D->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration ||
+ D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
+ Record.push_back(ExplicitInstantiation);
+ if (ExplicitInstantiation) {
+ Record.AddSourceLocation(D->getExternKeywordLoc());
Record.AddSourceLocation(D->getTemplateKeywordLoc());
}
+ const ASTTemplateArgumentListInfo *ArgsWritten =
+ D->getTemplateArgsAsWritten();
+ Record.push_back(!!ArgsWritten);
+ if (ArgsWritten)
+ Record.AddASTTemplateArgumentListInfo(ArgsWritten);
+
Record.AddTemplateArgumentList(&D->getTemplateArgs());
Record.AddSourceLocation(D->getPointOfInstantiation());
Record.push_back(D->getSpecializationKind());
@@ -1784,7 +1847,6 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
VarTemplatePartialSpecializationDecl *D) {
Record.AddTemplateParameterList(D->getTemplateParameters());
- Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
VisitVarTemplateSpecializationDecl(D);
@@ -1828,7 +1890,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
!D->defaultArgumentWasInherited();
Record.push_back(OwnsDefaultArg);
if (OwnsDefaultArg)
- Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
+ Record.AddTemplateArgumentLoc(D->getDefaultArgument());
if (!TC && !OwnsDefaultArg &&
D->getDeclContext() == D->getLexicalDeclContext() &&
@@ -1870,7 +1932,7 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
!D->defaultArgumentWasInherited();
Record.push_back(OwnsDefaultArg);
if (OwnsDefaultArg)
- Record.AddStmt(D->getDefaultArgument());
+ Record.AddTemplateArgumentLoc(D->getDefaultArgument());
Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
}
}
@@ -1883,6 +1945,7 @@ void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
Record.push_back(D->getNumExpansionTemplateParameters());
VisitTemplateDecl(D);
+ Record.push_back(D->wasDeclaredWithTypename());
// TemplateParmPosition.
Record.push_back(D->getDepth());
Record.push_back(D->getPosition());
@@ -1924,8 +1987,22 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
"You need to update the serializer after you change the "
"DeclContextBits");
- Record.AddOffset(Writer.WriteDeclContextLexicalBlock(Context, DC));
- Record.AddOffset(Writer.WriteDeclContextVisibleBlock(Context, DC));
+ uint64_t LexicalOffset = 0;
+ uint64_t VisibleOffset = 0;
+
+ if (Writer.isGeneratingReducedBMI() && isa<NamespaceDecl>(DC) &&
+ cast<NamespaceDecl>(DC)->isFromExplicitGlobalModule()) {
+ // In reduced BMI, delay writing lexical and visible block for namespace
+ // in the global module fragment. See the comments of DelayedNamespace for
+ // details.
+ Writer.DelayedNamespace.push_back(cast<NamespaceDecl>(DC));
+ } else {
+ LexicalOffset = Writer.WriteDeclContextLexicalBlock(Context, DC);
+ VisibleOffset = Writer.WriteDeclContextVisibleBlock(Context, DC);
+ }
+
+ Record.AddOffset(LexicalOffset);
+ Record.AddOffset(VisibleOffset);
}
const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
@@ -2718,10 +2795,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
"serializing");
// Determine the ID for this declaration.
- serialization::DeclID ID;
+ LocalDeclID ID;
assert(!D->isFromASTFile() && "should not be emitting imported decl");
- serialization::DeclID &IDR = DeclIDs[D];
- if (IDR == 0)
+ LocalDeclID &IDR = DeclIDs[D];
+ if (IDR.isInvalid())
IDR = NextDeclID++;
ID = IDR;
@@ -2729,7 +2806,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
assert(ID >= FirstDeclID && "invalid decl ID");
RecordData Record;
- ASTDeclWriter W(*this, Context, Record);
+ ASTDeclWriter W(*this, Context, Record, GeneratingReducedBMI);
// Build a record for this declaration
W.Visit(D);
@@ -2739,14 +2816,16 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Record the offset for this declaration
SourceLocation Loc = D->getLocation();
- unsigned Index = ID - FirstDeclID;
+ SourceLocationEncoding::RawLocEncoding RawLoc =
+ getRawSourceLocationEncoding(getAdjustedLocation(Loc));
+
+ unsigned Index = ID.getRawValue() - FirstDeclID.getRawValue();
if (DeclOffsets.size() == Index)
- DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset,
- DeclTypesBlockStartOffset);
+ DeclOffsets.emplace_back(RawLoc, Offset, DeclTypesBlockStartOffset);
else if (DeclOffsets.size() < Index) {
// FIXME: Can/should this happen?
DeclOffsets.resize(Index+1);
- DeclOffsets[Index].setLocation(getAdjustedLocation(Loc));
+ DeclOffsets[Index].setRawLoc(RawLoc);
DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset);
} else {
llvm_unreachable("declarations should be emitted in ID order");
@@ -2759,7 +2838,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Note declarations that should be deserialized eagerly so that we can add
// them to a record in the AST file later.
if (isRequiredDecl(D, Context, WritingModule))
- EagerlyDeserializedDecls.push_back(ID);
+ AddDeclRef(D, EagerlyDeserializedDecls);
}
void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
@@ -2795,7 +2874,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
}
Record->push_back(ModulesCodegen);
if (ModulesCodegen)
- Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD));
+ Writer->AddDeclRef(FD, Writer->ModularCodegenDecls);
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
Record->push_back(CD->getNumCtorInitializers());
if (CD->getNumCtorInitializers())
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
index e5836f5dcbe9..caa222277f06 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -19,7 +19,7 @@
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Lex/Token.h"
-#include "clang/Sema/DeclSpec.h"
+#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
using namespace clang;
@@ -38,7 +38,7 @@ namespace clang {
unsigned AbbrevToUse;
/// A helper that can help us to write a packed bit across function
- /// calls. For example, we may write seperate bits in seperate functions:
+ /// calls. For example, we may write separate bits in separate functions:
///
/// void VisitA(A* a) {
/// Record.push_back(a->isSomething());
@@ -474,14 +474,12 @@ addConstraintSatisfaction(ASTRecordWriter &Record,
if (!Satisfaction.IsSatisfied) {
Record.push_back(Satisfaction.NumRecords);
for (const auto &DetailRecord : Satisfaction) {
- Record.AddStmt(const_cast<Expr *>(DetailRecord.first));
- auto *E = DetailRecord.second.dyn_cast<Expr *>();
- Record.push_back(E == nullptr);
+ auto *E = DetailRecord.dyn_cast<Expr *>();
+ Record.push_back(/* IsDiagnostic */ E == nullptr);
if (E)
Record.AddStmt(E);
else {
- auto *Diag = DetailRecord.second.get<std::pair<SourceLocation,
- StringRef> *>();
+ auto *Diag = DetailRecord.get<std::pair<SourceLocation, StringRef> *>();
Record.AddSourceLocation(Diag->first);
Record.AddString(Diag->second);
}
@@ -881,16 +879,21 @@ void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
}
-void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
+void ASTStmtWriter::VisitArraySectionExpr(ArraySectionExpr *E) {
VisitExpr(E);
+ Record.writeEnum(E->ASType);
Record.AddStmt(E->getBase());
Record.AddStmt(E->getLowerBound());
Record.AddStmt(E->getLength());
- Record.AddStmt(E->getStride());
+ if (E->isOMPArraySection())
+ Record.AddStmt(E->getStride());
Record.AddSourceLocation(E->getColonLocFirst());
- Record.AddSourceLocation(E->getColonLocSecond());
+
+ if (E->isOMPArraySection())
+ Record.AddSourceLocation(E->getColonLocSecond());
+
Record.AddSourceLocation(E->getRBracketLoc());
- Code = serialization::EXPR_OMP_ARRAY_SECTION;
+ Code = serialization::EXPR_ARRAY_SECTION;
}
void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
@@ -970,10 +973,7 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
VisitExpr(E);
bool HasQualifier = E->hasQualifier();
- bool HasFoundDecl =
- E->hasQualifierOrFoundDecl() &&
- (E->getFoundDecl().getDecl() != E->getMemberDecl() ||
- E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess());
+ bool HasFoundDecl = E->hasFoundDecl();
bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
unsigned NumTemplateArgs = E->getNumTemplateArgs();
@@ -995,15 +995,15 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
Record.AddSourceLocation(E->getOperatorLoc());
+ if (HasQualifier)
+ Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
+
if (HasFoundDecl) {
DeclAccessPair FoundDecl = E->getFoundDecl();
Record.AddDeclRef(FoundDecl.getDecl());
CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
}
- if (HasQualifier)
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
-
if (HasTemplateInfo)
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
E->getTrailingObjects<TemplateArgumentLoc>());
@@ -1261,6 +1261,16 @@ void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
Code = serialization::EXPR_SOURCE_LOC;
}
+void ASTStmtWriter::VisitEmbedExpr(EmbedExpr *E) {
+ VisitExpr(E);
+ Record.AddSourceLocation(E->getBeginLoc());
+ Record.AddSourceLocation(E->getEndLoc());
+ Record.AddStmt(E->getDataStringLiteral());
+ Record.writeUInt32(E->getStartingElementPos());
+ Record.writeUInt32(E->getDataElementCount());
+ Code = serialization::EXPR_BUILTIN_PP_EMBED;
+}
+
void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
VisitExpr(E);
Record.AddSourceLocation(E->getAmpAmpLoc());
@@ -1842,6 +1852,7 @@ void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
VisitExpr(E);
Record.AddSourceLocation(E->getLocation());
Record.push_back(E->isImplicit());
+ Record.push_back(E->isCapturedByCopyInLambdaWithExplicitObjectParameter());
Code = serialization::EXPR_CXX_THIS;
}
@@ -2085,9 +2096,24 @@ void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E);
CurrentPackingBits.addBit(E->requiresADL());
- CurrentPackingBits.addBit(E->isOverloaded());
Record.AddDeclRef(E->getNamingClass());
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
+
+ if (Writer.isWritingStdCXXNamedModules() && Writer.getChain()) {
+ // Referencing all the possible declarations to make sure the change get
+ // propagted.
+ DeclarationName Name = E->getName();
+ for (auto *Found :
+ Writer.getASTContext().getTranslationUnitDecl()->lookup(Name))
+ if (Found->isFromASTFile())
+ Writer.GetDeclRef(Found);
+
+ llvm::SmallVector<NamespaceDecl *> ExternalNSs;
+ Writer.getChain()->ReadKnownNamespaces(ExternalNSs);
+ for (auto *NS : ExternalNSs)
+ for (auto *Found : NS->lookup(Name))
+ Writer.GetDeclRef(Found);
+ }
}
void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
@@ -2153,6 +2179,19 @@ void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
Code = serialization::EXPR_SIZEOF_PACK;
}
+void ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) {
+ VisitExpr(E);
+ Record.push_back(E->TransformedExpressions);
+ Record.push_back(E->ExpandedToEmptyPack);
+ Record.AddSourceLocation(E->getEllipsisLoc());
+ Record.AddSourceLocation(E->getRSquareLoc());
+ Record.AddStmt(E->getPackIdExpression());
+ Record.AddStmt(E->getIndexExpr());
+ for (Expr *Sub : E->getExpressions())
+ Record.AddStmt(Sub);
+ Code = serialization::EXPR_PACK_INDEXING;
+}
+
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
@@ -2398,6 +2437,16 @@ void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
Code = serialization::STMT_OMP_UNROLL_DIRECTIVE;
}
+void ASTStmtWriter::VisitOMPReverseDirective(OMPReverseDirective *D) {
+ VisitOMPLoopTransformationDirective(D);
+ Code = serialization::STMT_OMP_REVERSE_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) {
+ VisitOMPLoopTransformationDirective(D);
+ Code = serialization::STMT_OMP_INTERCHANGE_DIRECTIVE;
+}
+
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
VisitOMPLoopDirective(D);
Record.writeBool(D->hasCancel());
@@ -2810,6 +2859,7 @@ void ASTStmtWriter::VisitOMPTeamsGenericLoopDirective(
void ASTStmtWriter::VisitOMPTargetTeamsGenericLoopDirective(
OMPTargetTeamsGenericLoopDirective *D) {
VisitOMPLoopDirective(D);
+ Record.writeBool(D->canBeParallelFor());
Code = serialization::STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE;
}
@@ -2826,6 +2876,35 @@ void ASTStmtWriter::VisitOMPTargetParallelGenericLoopDirective(
}
//===----------------------------------------------------------------------===//
+// OpenACC Constructs/Directives.
+//===----------------------------------------------------------------------===//
+void ASTStmtWriter::VisitOpenACCConstructStmt(OpenACCConstructStmt *S) {
+ Record.push_back(S->clauses().size());
+ Record.writeEnum(S->Kind);
+ Record.AddSourceRange(S->Range);
+ Record.AddSourceLocation(S->DirectiveLoc);
+ Record.writeOpenACCClauseList(S->clauses());
+}
+
+void ASTStmtWriter::VisitOpenACCAssociatedStmtConstruct(
+ OpenACCAssociatedStmtConstruct *S) {
+ VisitOpenACCConstructStmt(S);
+ Record.AddStmt(S->getAssociatedStmt());
+}
+
+void ASTStmtWriter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCAssociatedStmtConstruct(S);
+ Code = serialization::STMT_OPENACC_COMPUTE_CONSTRUCT;
+}
+
+void ASTStmtWriter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCAssociatedStmtConstruct(S);
+ Code = serialization::STMT_OPENACC_LOOP_CONSTRUCT;
+}
+
+//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/clang/lib/Serialization/GeneratePCH.cpp b/contrib/llvm-project/clang/lib/Serialization/GeneratePCH.cpp
index cf8084333811..cc06106a4770 100644
--- a/contrib/llvm-project/clang/lib/Serialization/GeneratePCH.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/GeneratePCH.cpp
@@ -12,7 +12,9 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTWriter.h"
@@ -21,15 +23,16 @@
using namespace clang;
PCHGenerator::PCHGenerator(
- const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
- StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
+ Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef OutputFile,
+ StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors, bool IncludeTimestamps,
- bool BuildingImplicitModule, bool ShouldCacheASTInMemory)
+ bool BuildingImplicitModule, bool ShouldCacheASTInMemory,
+ bool GeneratingReducedBMI)
: PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,
- IncludeTimestamps, BuildingImplicitModule),
+ IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),
AllowASTWithErrors(AllowASTWithErrors),
ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
this->Buffer->IsComplete = false;
@@ -38,6 +41,21 @@ PCHGenerator::PCHGenerator(
PCHGenerator::~PCHGenerator() {
}
+Module *PCHGenerator::getEmittingModule(ASTContext &) {
+ Module *M = nullptr;
+
+ if (PP.getLangOpts().isCompilingModule()) {
+ M = PP.getHeaderSearchInfo().lookupModule(PP.getLangOpts().CurrentModule,
+ SourceLocation(),
+ /*AllowSearch*/ false);
+ if (!M)
+ assert(PP.getDiagnostics().hasErrorOccurred() &&
+ "emitting module but current module doesn't exist");
+ }
+
+ return M;
+}
+
void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
// Don't create a PCH if there were fatal failures during module loading.
if (PP.getModuleLoader().HadFatalFailure)
@@ -47,16 +65,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
if (hasErrors && !AllowASTWithErrors)
return;
- Module *Module = nullptr;
- if (PP.getLangOpts().isCompilingModule()) {
- Module = PP.getHeaderSearchInfo().lookupModule(
- PP.getLangOpts().CurrentModule, SourceLocation(),
- /*AllowSearch*/ false);
- if (!Module) {
- assert(hasErrors && "emitting module but current module doesn't exist");
- return;
- }
- }
+ Module *Module = getEmittingModule(Ctx);
// Errors that do not prevent the PCH from being written should not cause the
// overall compilation to fail either.
@@ -78,3 +87,53 @@ ASTMutationListener *PCHGenerator::GetASTMutationListener() {
ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
return &Writer;
}
+
+void PCHGenerator::anchor() {}
+
+CXX20ModulesGenerator::CXX20ModulesGenerator(Preprocessor &PP,
+ InMemoryModuleCache &ModuleCache,
+ StringRef OutputFile,
+ bool GeneratingReducedBMI)
+ : PCHGenerator(
+ PP, ModuleCache, OutputFile, llvm::StringRef(),
+ std::make_shared<PCHBuffer>(),
+ /*Extensions=*/ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
+ /*AllowASTWithErrors*/ false, /*IncludeTimestamps=*/false,
+ /*BuildingImplicitModule=*/false, /*ShouldCacheASTInMemory=*/false,
+ GeneratingReducedBMI) {}
+
+Module *CXX20ModulesGenerator::getEmittingModule(ASTContext &Ctx) {
+ Module *M = Ctx.getCurrentNamedModule();
+ assert(M && M->isNamedModuleUnit() &&
+ "CXX20ModulesGenerator should only be used with C++20 Named modules.");
+ return M;
+}
+
+void CXX20ModulesGenerator::HandleTranslationUnit(ASTContext &Ctx) {
+ // FIMXE: We'd better to wrap such options to a new class ASTWriterOptions
+ // since this is not about searching header really.
+ HeaderSearchOptions &HSOpts =
+ getPreprocessor().getHeaderSearchInfo().getHeaderSearchOpts();
+ HSOpts.ModulesSkipDiagnosticOptions = true;
+ HSOpts.ModulesSkipHeaderSearchPaths = true;
+
+ PCHGenerator::HandleTranslationUnit(Ctx);
+
+ if (!isComplete())
+ return;
+
+ std::error_code EC;
+ auto OS = std::make_unique<llvm::raw_fd_ostream>(getOutputFile(), EC);
+ if (EC) {
+ getDiagnostics().Report(diag::err_fe_unable_to_open_output)
+ << getOutputFile() << EC.message() << "\n";
+ return;
+ }
+
+ *OS << getBufferPtr()->Data;
+ OS->flush();
+}
+
+void CXX20ModulesGenerator::anchor() {}
+
+void ReducedBMIGenerator::anchor() {}
diff --git a/contrib/llvm-project/clang/lib/Serialization/GlobalModuleIndex.cpp b/contrib/llvm-project/clang/lib/Serialization/GlobalModuleIndex.cpp
index dd4fc3e00905..1163943c5dff 100644
--- a/contrib/llvm-project/clang/lib/Serialization/GlobalModuleIndex.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/GlobalModuleIndex.cpp
@@ -13,7 +13,6 @@
#include "clang/Serialization/GlobalModuleIndex.h"
#include "ASTReaderInternals.h"
#include "clang/Basic/FileManager.h"
-#include "clang/Lex/HeaderSearch.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ModuleFile.h"
#include "clang/Serialization/PCHContainerOperations.h"
@@ -89,10 +88,8 @@ public:
static std::pair<unsigned, unsigned>
ReadKeyDataLength(const unsigned char*& d) {
using namespace llvm::support;
- unsigned KeyLen =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
- unsigned DataLen =
- endian::readNext<uint16_t, llvm::endianness::little, unaligned>(d);
+ unsigned KeyLen = endian::readNext<uint16_t, llvm::endianness::little>(d);
+ unsigned DataLen = endian::readNext<uint16_t, llvm::endianness::little>(d);
return std::make_pair(KeyLen, DataLen);
}
@@ -113,8 +110,7 @@ public:
data_type Result;
while (DataLen > 0) {
- unsigned ID =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
+ unsigned ID = endian::readNext<uint32_t, llvm::endianness::little>(d);
Result.push_back(ID);
DataLen -= 4;
}
@@ -514,8 +510,8 @@ namespace {
// The first bit indicates whether this identifier is interesting.
// That's all we care about.
using namespace llvm::support;
- unsigned RawID =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(d);
+ IdentifierID RawID =
+ endian::readNext<IdentifierID, llvm::endianness::little>(d);
bool IsInteresting = RawID & 0x01;
return std::make_pair(k, IsInteresting);
}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ModuleFile.cpp b/contrib/llvm-project/clang/lib/Serialization/ModuleFile.cpp
index db896fd36115..4858cdbda554 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ModuleFile.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ModuleFile.cpp
@@ -59,11 +59,9 @@ LLVM_DUMP_METHOD void ModuleFile::dump() {
// Remapping tables.
llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset
<< '\n';
- dumpLocalRemap("Source location offset local -> global map", SLocRemap);
llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n'
<< " Number of identifiers: " << LocalNumIdentifiers << '\n';
- dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap);
llvm::errs() << " Base macro ID: " << BaseMacroID << '\n'
<< " Number of macros: " << LocalNumMacros << '\n';
@@ -86,9 +84,7 @@ LLVM_DUMP_METHOD void ModuleFile::dump() {
llvm::errs() << " Base type index: " << BaseTypeIndex << '\n'
<< " Number of types: " << LocalNumTypes << '\n';
- dumpLocalRemap("Type index local -> global map", TypeRemap);
- llvm::errs() << " Base decl ID: " << BaseDeclID << '\n'
+ llvm::errs() << " Base decl index: " << BaseDeclIndex << '\n'
<< " Number of decls: " << LocalNumDecls << '\n';
- dumpLocalRemap("Decl ID local -> global map", DeclRemap);
}
diff --git a/contrib/llvm-project/clang/lib/Serialization/ModuleFileExtension.cpp b/contrib/llvm-project/clang/lib/Serialization/ModuleFileExtension.cpp
index 95fff41e0d7a..729529b5fca1 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ModuleFileExtension.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ModuleFileExtension.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Serialization/ModuleFileExtension.h"
-#include "llvm/ADT/Hashing.h"
+
using namespace clang;
char ModuleFileExtension::ID = 0;
diff --git a/contrib/llvm-project/clang/lib/Serialization/MultiOnDiskHashTable.h b/contrib/llvm-project/clang/lib/Serialization/MultiOnDiskHashTable.h
index 2402a628b512..a0d75ec3a9e7 100644
--- a/contrib/llvm-project/clang/lib/Serialization/MultiOnDiskHashTable.h
+++ b/contrib/llvm-project/clang/lib/Serialization/MultiOnDiskHashTable.h
@@ -200,11 +200,11 @@ public:
storage_type Ptr = Data;
uint32_t BucketOffset =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Ptr);
+ endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
// Read the list of overridden files.
uint32_t NumFiles =
- endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Ptr);
+ endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
// FIXME: Add a reserve() to TinyPtrVector so that we don't need to make
// an additional copy.
llvm::SmallVector<file_type, 16> OverriddenFiles;
diff --git a/contrib/llvm-project/clang/lib/Serialization/PCHContainerOperations.cpp b/contrib/llvm-project/clang/lib/Serialization/PCHContainerOperations.cpp
index 56ca3394385b..4aedb7debcff 100644
--- a/contrib/llvm-project/clang/lib/Serialization/PCHContainerOperations.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/PCHContainerOperations.cpp
@@ -12,8 +12,6 @@
#include "clang/Serialization/PCHContainerOperations.h"
#include "clang/AST/ASTConsumer.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>