diff options
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Serialization')
13 files changed, 706 insertions, 212 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h index 027a981df22c..fdd64f2abbe9 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h @@ -41,7 +41,7 @@ namespace serialization { /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 15; +const unsigned VERSION_MAJOR = 29; /// AST file minor version number supported by this version of /// Clang. @@ -51,7 +51,7 @@ const unsigned VERSION_MAJOR = 15; /// for the previous version could still support reading the new /// version by ignoring new kinds of subblocks), this number /// should be increased. -const unsigned VERSION_MINOR = 0; +const unsigned VERSION_MINOR = 1; /// An ID number that refers to an identifier in an AST file. /// @@ -343,9 +343,6 @@ enum ControlRecordTypes { /// name. ORIGINAL_FILE, - /// The directory that the PCH was originally created in. - ORIGINAL_PCH_DIR, - /// Record code for file ID of the file or buffer that was used to /// generate the AST file. ORIGINAL_FILE_ID, @@ -400,8 +397,14 @@ enum UnhashedControlBlockRecordTypes { /// Record code for the diagnostic options table. DIAGNOSTIC_OPTIONS, + /// Record code for the headers search paths. + HEADER_SEARCH_PATHS, + /// Record code for \#pragma diagnostic mappings. DIAG_PRAGMA_MAPPINGS, + + /// Record code for the indices of used header search entries. + HEADER_SEARCH_ENTRY_USAGE, }; /// Record code for extension blocks. @@ -521,13 +524,7 @@ enum ASTRecordTypes { /// of source-location information. SOURCE_LOCATION_OFFSETS = 14, - /// Record code for the set of source location entries - /// that need to be preloaded by the AST reader. - /// - /// This set contains the source location entry for the - /// predefines buffer and for any file entries that need to be - /// preloaded. - SOURCE_LOCATION_PRELOADS = 15, + // ID 15 used to be for source location entry preloads. /// Record code for the set of ext_vector type names. EXT_VECTOR_DECLS = 16, @@ -692,6 +689,12 @@ enum ASTRecordTypes { /// Record code for \#pragma float_control options. FLOAT_CONTROL_PRAGMA_OPTIONS = 65, + + /// ID 66 used to be the list of included files. + + /// Record code for an unterminated \#pragma clang assume_nonnull begin + /// recorded in a preamble. + PP_ASSUME_NONNULL_LOC = 67, }; /// Record types used within a source manager block. @@ -822,6 +825,9 @@ enum SubmoduleRecordTypes { /// Specifies the name of the module that will eventually /// re-export the entities in this module. SUBMODULE_EXPORT_AS = 17, + + /// Specifies affecting modules that were not imported. + SUBMODULE_AFFECTING_MODULES = 18, }; /// Record types used within a comments block. @@ -1064,6 +1070,9 @@ enum PredefinedTypeIDs { /// \brief The '__bf16' type PREDEF_TYPE_BFLOAT16_ID = 73, + /// \brief The '__ibm128' type + PREDEF_TYPE_IBM128_ID = 74, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1080,6 +1089,11 @@ enum PredefinedTypeIDs { // \brief RISC-V V types with auto numeration #define RVV_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID, #include "clang/Basic/RISCVVTypes.def" +// \brief WebAssembly reference types with auto numeration +#define WASM_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID, +#include "clang/Basic/WebAssemblyReferenceTypes.def" + // Sentinel value. Considered a predefined type but not useable as one. + PREDEF_TYPE_LAST_ID }; /// The number of predefined type IDs that are reserved for @@ -1087,7 +1101,13 @@ enum PredefinedTypeIDs { /// /// Type IDs for non-predefined types will start at /// NUM_PREDEF_TYPE_IDs. -const unsigned NUM_PREDEF_TYPE_IDS = 300; +const unsigned NUM_PREDEF_TYPE_IDS = 502; + +// Ensure we do not overrun the predefined types we reserved +// in the enum PredefinedTypeIDs above. +static_assert(PREDEF_TYPE_LAST_ID < NUM_PREDEF_TYPE_IDS, + "Too many enumerators in PredefinedTypeIDs. Review the value of " + "NUM_PREDEF_TYPE_IDS"); /// Record codes for each kind of type. /// @@ -1302,6 +1322,9 @@ enum DeclCode { /// A FileScopeAsmDecl record. DECL_FILE_SCOPE_ASM, + /// A TopLevelStmtDecl record. + DECL_TOP_LEVEL_STMT_DECL, + /// A BlockDecl record. DECL_BLOCK, @@ -1452,10 +1475,6 @@ enum DeclCode { /// template template parameter pack. DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK, - /// A ClassScopeFunctionSpecializationDecl record a class scope - /// function specialization. (Microsoft extension). - DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION, - /// An ImportDecl recording a module import. DECL_IMPORT, @@ -1495,7 +1514,16 @@ enum DeclCode { /// An OMPDeclareReductionDecl record. DECL_OMP_DECLARE_REDUCTION, - DECL_LAST = DECL_OMP_DECLARE_REDUCTION + /// A UnnamedGlobalConstantDecl record. + DECL_UNNAMED_GLOBAL_CONSTANT, + + /// A HLSLBufferDecl record. + DECL_HLSL_BUFFER, + + /// An ImplicitConceptSpecializationDecl record. + DECL_IMPLICIT_CONCEPT_SPECIALIZATION, + + DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION }; /// Record codes for each kind of statement or expression. @@ -1833,6 +1861,9 @@ enum StmtCode { /// A CXXBoolLiteralExpr record. EXPR_CXX_BOOL_LITERAL, + /// A CXXParenListInitExpr record. + EXPR_CXX_PAREN_LIST_INIT, + EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). @@ -1890,6 +1921,7 @@ enum StmtCode { STMT_SEH_TRY, // SEHTryStmt // OpenMP directives + STMT_OMP_META_DIRECTIVE, STMT_OMP_CANONICAL_LOOP, STMT_OMP_PARALLEL_DIRECTIVE, STMT_OMP_SIMD_DIRECTIVE, @@ -1905,9 +1937,11 @@ enum StmtCode { STMT_OMP_PARALLEL_FOR_DIRECTIVE, STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE, STMT_OMP_PARALLEL_MASTER_DIRECTIVE, + STMT_OMP_PARALLEL_MASKED_DIRECTIVE, STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE, STMT_OMP_TASK_DIRECTIVE, STMT_OMP_TASKYIELD_DIRECTIVE, + STMT_OMP_ERROR_DIRECTIVE, STMT_OMP_BARRIER_DIRECTIVE, STMT_OMP_TASKWAIT_DIRECTIVE, STMT_OMP_FLUSH_DIRECTIVE, @@ -1931,6 +1965,10 @@ enum StmtCode { STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE, STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE, STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE, + STMT_OMP_MASKED_TASKLOOP_DIRECTIVE, + STMT_OMP_MASKED_TASKLOOP_SIMD_DIRECTIVE, + STMT_OMP_PARALLEL_MASKED_TASKLOOP_DIRECTIVE, + STMT_OMP_PARALLEL_MASKED_TASKLOOP_SIMD_DIRECTIVE, STMT_OMP_DISTRIBUTE_DIRECTIVE, STMT_OMP_TARGET_UPDATE_DIRECTIVE, STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, @@ -1947,9 +1985,15 @@ enum StmtCode { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, + STMT_OMP_SCOPE_DIRECTIVE, STMT_OMP_INTEROP_DIRECTIVE, STMT_OMP_DISPATCH_DIRECTIVE, STMT_OMP_MASKED_DIRECTIVE, + STMT_OMP_GENERIC_LOOP_DIRECTIVE, + STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE, + STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE, + STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, EXPR_OMP_ITERATOR, diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h index 242b75baca6c..62c25f5b7a0d 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h @@ -32,12 +32,13 @@ #include "clang/Serialization/ModuleFile.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/ModuleManager.h" +#include "clang/Serialization/SourceLocationEncoding.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PagedVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -56,6 +57,7 @@ #include <ctime> #include <deque> #include <memory> +#include <optional> #include <set> #include <string> #include <utility> @@ -84,7 +86,6 @@ class GlobalModuleIndex; struct HeaderFileInfo; class HeaderSearchOptions; class LangOptions; -class LazyASTUnresolvedSet; class MacroInfo; class InMemoryModuleCache; class NamedDecl; @@ -94,7 +95,6 @@ class ObjCInterfaceDecl; class PCHContainerReader; class Preprocessor; class PreprocessorOptions; -struct QualifierInfo; class Sema; class SourceManager; class Stmt; @@ -165,6 +165,10 @@ public: /// Receives the header search options. /// + /// \param HSOpts The read header search options. The following fields are + /// missing and are reported in ReadHeaderSearchPaths(): + /// UserEntries, SystemHeaderPrefixes, VFSOverlayFiles. + /// /// \returns true to indicate the header search options are invalid, or false /// otherwise. virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, @@ -173,6 +177,20 @@ public: return false; } + /// Receives the header search paths. + /// + /// \param HSOpts The read header search paths. Only the following fields are + /// initialized: UserEntries, SystemHeaderPrefixes, + /// VFSOverlayFiles. The rest is reported in + /// ReadHeaderSearchOptions(). + /// + /// \returns true to indicate the header search paths are invalid, or false + /// otherwise. + virtual bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts, + bool Complain) { + return false; + } + /// Receives the preprocessor options. /// /// \param SuggestedPredefines Can be filled in with the set of predefines @@ -182,7 +200,7 @@ public: /// \returns true to indicate the preprocessor options are invalid, or false /// otherwise. virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, - bool Complain, + bool ReadMacros, bool Complain, std::string &SuggestedPredefines) { return false; } @@ -257,7 +275,7 @@ public: StringRef SpecificModuleCachePath, bool Complain) override; bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, - bool Complain, + bool ReadMacros, bool Complain, std::string &SuggestedPredefines) override; void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override; @@ -287,15 +305,13 @@ public: bool AllowCompatibleDifferences) override; bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) override; - bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool ReadMacros, bool Complain, std::string &SuggestedPredefines) override; bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, bool Complain) override; void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override; - -private: - void Error(const char *Msg); }; /// ASTReaderListenter implementation to set SuggestedPredefines of @@ -308,7 +324,8 @@ class SimpleASTReaderListener : public ASTReaderListener { public: SimpleASTReaderListener(Preprocessor &PP) : PP(PP) {} - bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool ReadMacros, bool Complain, std::string &SuggestedPredefines) override; }; @@ -382,7 +399,7 @@ public: /// The AST file was written by a different version of Clang. VersionMismatch, - /// The AST file was writtten with a different language/target + /// The AST file was written with a different language/target /// configuration. ConfigurationMismatch, @@ -398,6 +415,8 @@ public: using ModuleReverseIterator = ModuleManager::ModuleReverseIterator; private: + using LocSeq = SourceLocationSequence; + /// The receiver of some callbacks invoked by ASTReader. std::unique_ptr<ASTReaderListener> Listener; @@ -443,7 +462,7 @@ private: SourceLocation CurrentImportLoc; /// The module kind that is currently deserializing. - Optional<ModuleKind> CurrentDeserializingModuleKind; + std::optional<ModuleKind> CurrentDeserializingModuleKind; /// The global module index, if loaded. std::unique_ptr<GlobalModuleIndex> GlobalIndex; @@ -466,7 +485,7 @@ private: /// /// When the pointer at index I is non-NULL, the type with /// ID = (I + 1) << FastQual::Width has already been loaded - std::vector<QualType> TypesLoaded; + llvm::PagedVector<QualType> TypesLoaded; using GlobalTypeMapType = ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>; @@ -480,7 +499,7 @@ private: /// /// When the pointer at index I is non-NULL, the declaration with ID /// = I + 1 has already been loaded. - std::vector<Decl *> DeclsLoaded; + llvm::PagedVector<Decl *> DeclsLoaded; using GlobalDeclMapType = ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>; @@ -531,6 +550,10 @@ private: /// declaration and the value is the deduced return type. llvm::SmallMapVector<FunctionDecl *, QualType, 4> PendingDeducedTypeUpdates; + /// Functions has undededuced return type and we wish we can find the deduced + /// return type by iterating the redecls in other modules. + llvm::SmallVector<FunctionDecl *, 4> PendingUndeducedFunctionDecls; + /// Declarations that have been imported and have typedef names for /// linkage purposes. llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *> @@ -541,6 +564,10 @@ private: llvm::DenseMap<Decl*, llvm::SmallVector<NamedDecl*, 2>> AnonymousDeclarationsForMerging; + /// Map from numbering information for lambdas to the corresponding lambdas. + llvm::DenseMap<std::pair<const Decl *, unsigned>, NamedDecl *> + LambdaDeclarationsForMerging; + /// Key used to identify LifetimeExtendedTemporaryDecl for merging, /// containing the lifetime-extending declaration and the mangling number. using LETemporaryKey = std::pair<Decl *, unsigned>; @@ -688,7 +715,7 @@ private: Module *Mod; /// The kind of module reference. - enum { Import, Export, Conflict } Kind; + enum { Import, Export, Conflict, Affecting } Kind; /// The local ID of the module that is being exported. unsigned ID; @@ -863,7 +890,7 @@ private: SourceLocation PointersToMembersPragmaLocation; /// The pragma float_control state. - Optional<FPOptionsOverride> FpPragmaCurrentValue; + std::optional<FPOptionsOverride> FpPragmaCurrentValue; SourceLocation FpPragmaCurrentLocation; struct FpPragmaStackEntry { FPOptionsOverride Value; @@ -875,7 +902,7 @@ private: llvm::SmallVector<std::string, 2> FpPragmaStrings; /// The pragma align/pack state. - Optional<Sema::AlignPackInfo> PragmaAlignPackCurrentValue; + std::optional<Sema::AlignPackInfo> PragmaAlignPackCurrentValue; SourceLocation PragmaAlignPackCurrentLocation; struct PragmaAlignPackStackEntry { Sema::AlignPackInfo Value; @@ -914,7 +941,7 @@ private: /// Sema tracks these to emit deferred diags. llvm::SmallSetVector<serialization::DeclID, 4> DeclsToCheckForDeferredDiags; -public: +private: struct ImportedSubmodule { serialization::SubmoduleID ID; SourceLocation ImportLoc; @@ -923,10 +950,15 @@ public: : ID(ID), ImportLoc(ImportLoc) {} }; -private: /// A list of modules that were imported by precompiled headers or - /// any other non-module AST file. - SmallVector<ImportedSubmodule, 2> ImportedModules; + /// any other non-module AST file and have not yet been made visible. If a + /// module is made visible in the ASTReader, it will be transfered to + /// \c PendingImportedModulesSema. + SmallVector<ImportedSubmodule, 2> PendingImportedModules; + + /// A list of modules that were imported by precompiled headers or + /// any other non-module AST file and have not yet been made visible for Sema. + SmallVector<ImportedSubmodule, 2> PendingImportedModulesSema; //@} /// The system include root to be used when loading the @@ -1082,7 +1114,13 @@ private: /// they might contain a deduced return type that refers to a local type /// declared within the function. SmallVector<std::pair<FunctionDecl *, serialization::TypeID>, 16> - PendingFunctionTypes; + PendingDeducedFunctionTypes; + + /// The list of deduced variable types that we have not yet read, because + /// they might contain a deduced type that refers to a local type declared + /// within the variable. + SmallVector<std::pair<VarDecl *, serialization::TypeID>, 16> + PendingDeducedVarTypes; /// The list of redeclaration chains that still need to be /// reconstructed, and the local offset to the corresponding list @@ -1108,6 +1146,23 @@ private: /// been completed. std::deque<PendingDeclContextInfo> PendingDeclContextInfos; + template <typename DeclTy> + using DuplicateObjCDecls = std::pair<DeclTy *, DeclTy *>; + + /// When resolving duplicate ivars from Objective-C extensions we don't error + /// out immediately but check if can merge identical extensions. Not checking + /// extensions for equality immediately because ivar deserialization isn't + /// over yet at that point. + llvm::SmallMapVector<DuplicateObjCDecls<ObjCCategoryDecl>, + llvm::SmallVector<DuplicateObjCDecls<ObjCIvarDecl>, 4>, + 2> + PendingObjCExtensionIvarRedeclarations; + + /// Members that have been added to classes, for which the class has not yet + /// been notified. CXXRecordDecl::addedMember will be called for each of + /// these once recursive deserialization is complete. + SmallVector<std::pair<CXXRecordDecl*, Decl*>, 4> PendingAddedClassMembers; + /// The set of NamedDecls that have been loaded, but are members of a /// context that has been merged into another context where the corresponding /// declaration is either missing or has not yet been loaded. @@ -1118,11 +1173,20 @@ private: using DataPointers = std::pair<CXXRecordDecl *, struct CXXRecordDecl::DefinitionData *>; + using ObjCInterfaceDataPointers = + std::pair<ObjCInterfaceDecl *, + struct ObjCInterfaceDecl::DefinitionData *>; + using ObjCProtocolDataPointers = + std::pair<ObjCProtocolDecl *, struct ObjCProtocolDecl::DefinitionData *>; /// Record definitions in which we found an ODR violation. llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2> PendingOdrMergeFailures; + /// C/ObjC record definitions in which we found an ODR violation. + llvm::SmallDenseMap<RecordDecl *, llvm::SmallVector<RecordDecl *, 2>, 2> + PendingRecordOdrMergeFailures; + /// Function definitions in which we found an ODR violation. llvm::SmallDenseMap<FunctionDecl *, llvm::SmallVector<FunctionDecl *, 2>, 2> PendingFunctionOdrMergeFailures; @@ -1131,6 +1195,16 @@ private: llvm::SmallDenseMap<EnumDecl *, llvm::SmallVector<EnumDecl *, 2>, 2> PendingEnumOdrMergeFailures; + /// ObjCInterfaceDecl in which we found an ODR violation. + llvm::SmallDenseMap<ObjCInterfaceDecl *, + llvm::SmallVector<ObjCInterfaceDataPointers, 2>, 2> + PendingObjCInterfaceOdrMergeFailures; + + /// ObjCProtocolDecl in which we found an ODR violation. + llvm::SmallDenseMap<ObjCProtocolDecl *, + llvm::SmallVector<ObjCProtocolDataPointers, 2>, 2> + PendingObjCProtocolOdrMergeFailures; + /// DeclContexts in which we have diagnosed an ODR violation. llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures; @@ -1162,6 +1236,10 @@ private: /// definitions. Only populated when using modules in C++. llvm::DenseMap<EnumDecl *, EnumDecl *> EnumDefinitions; + /// A mapping from canonical declarations of records to their canonical + /// definitions. Doesn't cover CXXRecordDecl. + llvm::DenseMap<RecordDecl *, RecordDecl *> RecordDefinitions; + /// When reading a Stmt tree, Stmt operands are placed in this stack. SmallVector<Stmt *, 16> StmtStack; @@ -1223,18 +1301,8 @@ private: /// Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(ModuleFile &F); - struct InputFileInfo { - std::string Filename; - uint64_t ContentHash; - off_t StoredSize; - time_t StoredTime; - bool Overridden; - bool Transient; - bool TopLevelModuleMap; - }; - - /// Reads the stored information about an input file. - InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID); + /// Retrieve the stored information about an input file. + serialization::InputFileInfo getInputFileInfo(ModuleFile &F, unsigned ID); /// Retrieve the file entry and 'overridden' bit for an input /// file in the given module file. @@ -1320,18 +1388,17 @@ private: ASTReaderListener *Listener, bool ValidateDiagnosticOptions); - ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); - ASTReadResult ReadExtensionBlock(ModuleFile &F); + llvm::Error ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); + llvm::Error ReadExtensionBlock(ModuleFile &F); void ReadModuleOffsetMap(ModuleFile &F) const; - bool ParseLineTable(ModuleFile &F, const RecordData &Record); - bool ReadSourceManagerBlock(ModuleFile &F); - llvm::BitstreamCursor &SLocCursorForID(int ID); + void ParseLineTable(ModuleFile &F, const RecordData &Record); + llvm::Error ReadSourceManagerBlock(ModuleFile &F); SourceLocation getImportLocation(ModuleFile *F); ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities); - ASTReadResult ReadSubmoduleBlock(ModuleFile &F, - unsigned ClientLoadCapabilities); + llvm::Error ReadSubmoduleBlock(ModuleFile &F, + unsigned ClientLoadCapabilities); static bool ParseLanguageOptions(const RecordData &Record, bool Complain, ASTReaderListener &Listener, bool AllowCompatibleDifferences); @@ -1344,6 +1411,8 @@ private: ASTReaderListener &Listener); static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain, ASTReaderListener &Listener); + static bool ParseHeaderSearchPaths(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain, ASTReaderListener &Listener, std::string &SuggestedPredefines); @@ -1359,7 +1428,7 @@ private: RecordLocation TypeCursorForIndex(unsigned Index); void LoadedDecl(unsigned Index, Decl *D); Decl *ReadDeclRecord(serialization::DeclID ID); - void markIncompleteDeclChain(Decl *Canon); + void markIncompleteDeclChain(Decl *D); /// Returns the most recent declaration of a declaration (which must be /// of a redeclarable kind) that is either local or has already been loaded @@ -1566,12 +1635,17 @@ public: /// capabilities, represented as a bitset of the enumerators of /// LoadFailureCapabilities. /// - /// \param Imported optional out-parameter to append the list of modules - /// that were imported by precompiled headers or any other non-module AST file + /// \param LoadedModuleFile The optional out-parameter refers to the new + /// loaded modules. In case the module specified by FileName is already + /// loaded, the module file pointer referred by NewLoadedModuleFile wouldn't + /// change. Otherwise if the AST file get loaded successfully, + /// NewLoadedModuleFile would refer to the address of the new loaded top level + /// module. The state of NewLoadedModuleFile is unspecified if the AST file + /// isn't loaded successfully. ASTReadResult ReadAST(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, unsigned ClientLoadCapabilities, - SmallVectorImpl<ImportedSubmodule> *Imported = nullptr); + ModuleFile **NewLoadedModuleFile = nullptr); /// Make the entities in the given module and any of its (non-explicit) /// submodules visible to name lookup. @@ -1706,21 +1780,23 @@ public: /// Read the control block for the named AST file. /// /// \returns true if an error occurred, false otherwise. - static bool - readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, - const PCHContainerReader &PCHContainerRdr, - bool FindModuleFileExtensions, - ASTReaderListener &Listener, - bool ValidateDiagnosticOptions); + static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, + const InMemoryModuleCache &ModuleCache, + const PCHContainerReader &PCHContainerRdr, + bool FindModuleFileExtensions, + ASTReaderListener &Listener, + bool ValidateDiagnosticOptions); /// Determine whether the given AST file is acceptable to load into a /// translation unit with the given language and target options. static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, + const InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, - StringRef ExistingModuleCachePath); + StringRef ExistingModuleCachePath, + bool RequireStrictOptionMatches = false); /// Returns the suggested contents of the predefines buffer, /// which contains a (typically-empty) subset of the predefines @@ -1740,14 +1816,14 @@ public: /// Optionally returns true or false if the preallocated preprocessed /// entity with index \p Index came from file \p FID. - Optional<bool> isPreprocessedEntityInFileID(unsigned Index, - FileID FID) override; + std::optional<bool> isPreprocessedEntityInFileID(unsigned Index, + FileID FID) override; /// Read a preallocated skipped range from the external source. SourceRange ReadSkippedRange(unsigned Index) override; /// Read the header file information for the given file entry. - HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override; + HeaderFileInfo GetHeaderFileInfo(FileEntryRef FE) override; void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag); @@ -1826,10 +1902,6 @@ public: /// if the declaration is not from a module file. ModuleFile *getOwningModuleFile(const Decl *D); - /// Get the best name we know for the module that owns the given - /// declaration, or an empty string if the declaration is not from a module. - std::string getOwningModuleNameForDiagnostic(const Decl *D); - /// Returns the source location for the decl \p ID. SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID); @@ -1904,8 +1976,9 @@ public: /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the /// specified cursor. Read the abbreviations that are at the top of the block /// and then leave the cursor pointing into the block. - static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID, - uint64_t *StartOfBlockOffset = nullptr); + static llvm::Error ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, + unsigned BlockID, + uint64_t *StartOfBlockOffset = nullptr); /// Finds all the visible declarations with a given name. /// The current implementation of this method just loads the entire @@ -2024,7 +2097,7 @@ public: SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) override; void ReadWeakUndeclaredIdentifiers( - SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WI) override; + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WeakIDs) override; void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override; @@ -2036,6 +2109,8 @@ public: llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> &LPTMap) override; + void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) override; + /// Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); @@ -2080,6 +2155,12 @@ public: /// Read the source location entry with index ID. bool ReadSLocEntry(int ID) override; + /// Get the index ID for the loaded SourceLocation offset. + int getSLocEntryID(SourceLocation::UIntTy SLocOffset) override; + /// Try to read the offset of the SLocEntry at the given index in the given + /// module file. + llvm::Expected<SourceLocation::UIntTy> readSLocOffset(ModuleFile *F, + unsigned Index); /// Retrieve the module import location and module name for the /// given source manager entry ID. @@ -2107,7 +2188,7 @@ public: unsigned getModuleFileID(ModuleFile *M); /// Return a descriptor for the corresponding module. - llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override; + std::optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override; ExtKind hasExternalDefinitions(const Decl *D) override; @@ -2126,7 +2207,7 @@ public: /// Retrieve the global selector ID that corresponds to this /// the local selector ID in a given module. - serialization::SelectorID getGlobalSelectorID(ModuleFile &F, + serialization::SelectorID getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const; /// Read the contents of a CXXCtorInitializer array. @@ -2139,16 +2220,16 @@ public: /// Read a source location from raw form and return it in its /// originating module file's source location space. - SourceLocation - ReadUntranslatedSourceLocation(SourceLocation::UIntTy Raw) const { - return SourceLocation::getFromRawEncoding((Raw >> 1) | - (Raw << (8 * sizeof(Raw) - 1))); + SourceLocation ReadUntranslatedSourceLocation(SourceLocation::UIntTy Raw, + LocSeq *Seq = nullptr) const { + return SourceLocationEncoding::decode(Raw, Seq); } /// Read a source location from raw form. SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, - SourceLocation::UIntTy Raw) const { - SourceLocation Loc = ReadUntranslatedSourceLocation(Raw); + SourceLocation::UIntTy Raw, + LocSeq *Seq = nullptr) const { + SourceLocation Loc = ReadUntranslatedSourceLocation(Raw, Seq); return TranslateSourceLocation(ModuleFile, Loc); } @@ -2168,17 +2249,29 @@ public: /// Read a source location. SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, - const RecordDataImpl &Record, - unsigned &Idx) { - return ReadSourceLocation(ModuleFile, Record[Idx++]); + const RecordDataImpl &Record, unsigned &Idx, + LocSeq *Seq = nullptr) { + return ReadSourceLocation(ModuleFile, Record[Idx++], Seq); + } + + /// Read a FileID. + FileID ReadFileID(ModuleFile &F, const RecordDataImpl &Record, + unsigned &Idx) const { + return TranslateFileID(F, FileID::get(Record[Idx++])); + } + + /// Translate a FileID from another module file's FileID space into ours. + FileID TranslateFileID(ModuleFile &F, FileID FID) const { + assert(FID.ID >= 0 && "Reading non-local FileID."); + return FileID::get(F.SLocEntryBaseID + FID.ID - 1); } /// Read a source range. - SourceRange ReadSourceRange(ModuleFile &F, - const RecordData &Record, unsigned &Idx); + SourceRange ReadSourceRange(ModuleFile &F, const RecordData &Record, + unsigned &Idx, LocSeq *Seq = nullptr); // Read a string - static std::string ReadString(const RecordData &Record, unsigned &Idx); + static std::string ReadString(const RecordDataImpl &Record, unsigned &Idx); // Skip a string static void SkipString(const RecordData &Record, unsigned &Idx) { @@ -2294,6 +2387,13 @@ public: /// Loads comments ranges. void ReadComments() override; + /// Visit all the input file infos of the given module file. + void visitInputFileInfos( + serialization::ModuleFile &MF, bool IncludeSystem, + llvm::function_ref<void(const serialization::InputFileInfo &IFI, + bool IsSystem)> + Visitor); + /// Visit all the input files of the given module file. void visitInputFiles(serialization::ModuleFile &MF, bool IncludeSystem, bool Complain, @@ -2303,12 +2403,54 @@ public: /// Visit all the top-level module maps loaded when building the given module /// file. void visitTopLevelModuleMaps(serialization::ModuleFile &MF, - llvm::function_ref< - void(const FileEntry *)> Visitor); + llvm::function_ref<void(FileEntryRef)> Visitor); bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; } }; +/// A simple helper class to unpack an integer to bits and consuming +/// the bits in order. +class BitsUnpacker { + constexpr static uint32_t BitsIndexUpbound = 32; + +public: + BitsUnpacker(uint32_t V) { updateValue(V); } + BitsUnpacker(const BitsUnpacker &) = delete; + BitsUnpacker(BitsUnpacker &&) = delete; + BitsUnpacker operator=(const BitsUnpacker &) = delete; + BitsUnpacker operator=(BitsUnpacker &&) = delete; + ~BitsUnpacker() = default; + + void updateValue(uint32_t V) { + Value = V; + CurrentBitsIndex = 0; + } + + void advance(uint32_t BitsWidth) { CurrentBitsIndex += BitsWidth; } + + bool getNextBit() { + assert(isValid()); + return Value & (1 << CurrentBitsIndex++); + } + + uint32_t getNextBits(uint32_t Width) { + assert(isValid()); + assert(Width < BitsIndexUpbound); + uint32_t Ret = (Value >> CurrentBitsIndex) & ((1 << Width) - 1); + CurrentBitsIndex += Width; + return Ret; + } + + bool canGetNextNBits(uint32_t Width) const { + return CurrentBitsIndex + Width < BitsIndexUpbound; + } + +private: + bool isValid() const { return CurrentBitsIndex < BitsIndexUpbound; } + + uint32_t Value; + uint32_t CurrentBitsIndex = ~0; +}; } // namespace clang #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h index b85609bf4e05..80a1359fd16a 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h @@ -18,6 +18,7 @@ #include "clang/AST/AbstractBasicReader.h" #include "clang/Lex/Token.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/SourceLocationEncoding.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" @@ -30,6 +31,7 @@ class OMPChildren; class ASTRecordReader : public serialization::DataStreamBasicReader<ASTRecordReader> { using ModuleFile = serialization::ModuleFile; + using LocSeq = SourceLocationSequence; ASTReader *Reader; ModuleFile *F; @@ -72,7 +74,7 @@ public: uint64_t readInt() { return Record[Idx++]; } ArrayRef<uint64_t> readIntArray(unsigned Len) { - auto Array = llvm::makeArrayRef(Record).slice(Idx, Len); + auto Array = llvm::ArrayRef(Record).slice(Idx, Len); Idx += Len; return Array; } @@ -153,15 +155,19 @@ public: /// Reads a TemplateArgumentLoc, advancing Idx. TemplateArgumentLoc readTemplateArgumentLoc(); + void readTemplateArgumentListInfo(TemplateArgumentListInfo &Result); + const ASTTemplateArgumentListInfo* readASTTemplateArgumentListInfo(); + // Reads a concept reference from the given record. + ConceptReference *readConceptReference(); + /// Reads a declarator info from the given record, advancing Idx. TypeSourceInfo *readTypeSourceInfo(); /// Reads the location information for a type. - void readTypeLoc(TypeLoc TL); - + void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr); /// Map a local type ID within a given AST file to a global type ID. serialization::TypeID getGlobalTypeID(unsigned LocalID) const { @@ -271,13 +277,13 @@ public: void readOMPChildren(OMPChildren *Data); /// Read a source location, advancing Idx. - SourceLocation readSourceLocation() { - return Reader->ReadSourceLocation(*F, Record, Idx); + SourceLocation readSourceLocation(LocSeq *Seq = nullptr) { + return Reader->ReadSourceLocation(*F, Record, Idx, Seq); } /// Read a source range, advancing Idx. - SourceRange readSourceRange() { - return Reader->ReadSourceRange(*F, Record, Idx); + SourceRange readSourceRange(LocSeq *Seq = nullptr) { + return Reader->ReadSourceRange(*F, Record, Idx, Seq); } /// Read an arbitrary constant value, advancing Idx. @@ -326,6 +332,11 @@ public: /// Reads attributes from the current stream position, advancing Idx. void readAttributes(AttrVec &Attrs); + /// Read an BTFTypeTagAttr object. + BTFTypeTagAttr *readBTFTypeTagAttr() { + return cast<BTFTypeTagAttr>(readAttr()); + } + /// Reads a token out of a record, advancing Idx. Token readToken() { return Reader->ReadToken(*F, Record, Idx); @@ -350,7 +361,7 @@ struct SavedStreamPosition { ~SavedStreamPosition() { if (llvm::Error Err = Cursor.JumpToBit(Offset)) llvm::report_fatal_error( - "Cursor should always be able to go back, failed: " + + llvm::Twine("Cursor should always be able to go back, failed: ") + toString(std::move(Err))); } @@ -359,10 +370,6 @@ private: uint64_t Offset; }; -inline void PCHValidator::Error(const char *Msg) { - Reader.Error(Msg); -} - } // namespace clang #endif diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h index 0dc69bd3f3bd..9a64735c9fa5 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h @@ -17,6 +17,7 @@ #include "clang/AST/AbstractBasicWriter.h" #include "clang/AST/OpenMPClause.h" #include "clang/Serialization/ASTWriter.h" +#include "clang/Serialization/SourceLocationEncoding.h" namespace clang { @@ -25,6 +26,8 @@ class TypeLoc; /// An object for streaming information to a record. class ASTRecordWriter : public serialization::DataStreamBasicWriter<ASTRecordWriter> { + using LocSeq = SourceLocationSequence; + ASTWriter *Writer; ASTWriter::RecordDataImpl *Record; @@ -123,21 +126,24 @@ public: AddStmt(const_cast<Stmt*>(S)); } + /// Write an BTFTypeTagAttr object. + void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); } + /// Add a definition for the given function to the queue of statements /// to emit. void AddFunctionDefinition(const FunctionDecl *FD); /// Emit a source location. - void AddSourceLocation(SourceLocation Loc) { - return Writer->AddSourceLocation(Loc, *Record); + void AddSourceLocation(SourceLocation Loc, LocSeq *Seq = nullptr) { + return Writer->AddSourceLocation(Loc, *Record, Seq); } void writeSourceLocation(SourceLocation Loc) { AddSourceLocation(Loc); } /// Emit a source range. - void AddSourceRange(SourceRange Range) { - return Writer->AddSourceRange(Range, *Record); + void AddSourceRange(SourceRange Range, LocSeq *Seq = nullptr) { + return Writer->AddSourceRange(Range, *Record, Seq); } void writeBool(bool Value) { @@ -203,7 +209,7 @@ public: void AddTypeSourceInfo(TypeSourceInfo *TInfo); /// Emits source location information for a type. Does not emit the type. - void AddTypeLoc(TypeLoc TL); + void AddTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr); /// Emits a template argument location info. void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, @@ -216,6 +222,9 @@ public: void AddASTTemplateArgumentListInfo( const ASTTemplateArgumentListInfo *ASTTemplArgList); + // Emits a concept reference. + void AddConceptReference(const ConceptReference *CR); + /// Emit a reference to a declaration. void AddDeclRef(const Decl *D) { return Writer->AddDeclRef(D, *Record); diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h index ac88cb0a3177..de69f99003d8 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h @@ -18,12 +18,14 @@ #include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Serialization/PCHContainerOperations.h" +#include "clang/Serialization/SourceLocationEncoding.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -43,26 +45,13 @@ #include <utility> #include <vector> -namespace llvm { - -class APFloat; -class APInt; -class APSInt; - -} // namespace llvm - namespace clang { class ASTContext; class ASTReader; -class ASTUnresolvedSet; class Attr; -class CXXBaseSpecifier; -class CXXCtorInitializer; class CXXRecordDecl; -class CXXTemporary; class FileEntry; -class FPOptions; class FPOptionsOverride; class FunctionDecl; class HeaderSearch; @@ -79,16 +68,13 @@ class NamedDecl; class ObjCInterfaceDecl; class PreprocessingRecord; class Preprocessor; -struct QualifierInfo; class RecordDecl; class Sema; class SourceManager; class Stmt; class StoredDeclsList; class SwitchCase; -class TemplateParameterList; class Token; -class TypeSourceInfo; /// Writes an AST file containing the contents of a translation unit. /// @@ -119,6 +105,8 @@ private: using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx, serialization::UnsafeQualTypeDenseMapInfo>; + using LocSeq = SourceLocationSequence; + /// The bitstream writer used to emit this precompiled header. llvm::BitstreamWriter &Stream; @@ -140,10 +128,17 @@ private: /// The module we're currently writing, if any. Module *WritingModule = nullptr; - /// The offset of the first bit inside the AST_BLOCK. + /// The byte range representing all the UNHASHED_CONTROL_BLOCK. + std::pair<uint64_t, uint64_t> UnhashedControlBlockRange; + /// The bit offset of the AST block hash blob. + uint64_t ASTBlockHashOffset = 0; + /// The bit offset of the signature blob. + uint64_t SignatureOffset = 0; + + /// The bit offset of the first bit inside the AST_BLOCK. uint64_t ASTBlockStartOffset = 0; - /// The range representing all the AST_BLOCK. + /// The byte range representing all the AST_BLOCK. std::pair<uint64_t, uint64_t> ASTBlockRange; /// The base directory for any relative paths we emit. @@ -155,6 +150,11 @@ private: /// file is up to date, but not otherwise. bool IncludeTimestamps; + /// Indicates whether the AST file being written is an implicit module. + /// If that's the case, we may be able to skip writing some information that + /// are guaranteed to be the same in the importer by the context hash. + bool BuildingImplicitModule = false; + /// Indicates when the AST writing is actively performing /// serialization, rather than just queueing updates. bool WritingAST = false; @@ -456,6 +456,41 @@ private: std::vector<std::unique_ptr<ModuleFileExtensionWriter>> ModuleFileExtensionWriters; + /// Mapping from a source location entry to whether it is affecting or not. + llvm::BitVector IsSLocAffecting; + + /// Mapping from \c FileID to an index into the FileID adjustment table. + std::vector<FileID> NonAffectingFileIDs; + std::vector<unsigned> NonAffectingFileIDAdjustments; + + /// Mapping from an offset to an index into the offset adjustment table. + std::vector<SourceRange> NonAffectingRanges; + std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments; + + /// Collects input files that didn't affect compilation of the current module, + /// and initializes data structures necessary for leaving those files out + /// during \c SourceManager serialization. + void collectNonAffectingInputFiles(); + + /// Returns an adjusted \c FileID, accounting for any non-affecting input + /// files. + FileID getAdjustedFileID(FileID FID) const; + /// Returns an adjusted number of \c FileIDs created within the specified \c + /// FileID, accounting for any non-affecting input files. + unsigned getAdjustedNumCreatedFIDs(FileID FID) const; + /// Returns an adjusted \c SourceLocation, accounting for any non-affecting + /// input files. + SourceLocation getAdjustedLocation(SourceLocation Loc) const; + /// Returns an adjusted \c SourceRange, accounting for any non-affecting input + /// files. + SourceRange getAdjustedRange(SourceRange Range) const; + /// Returns an adjusted \c SourceLocation offset, accounting for any + /// non-affecting input files. + SourceLocation::UIntTy getAdjustedOffset(SourceLocation::UIntTy Offset) const; + /// Returns an adjustment for offset into SourceManager, accounting for any + /// non-affecting input files. + SourceLocation::UIntTy getAdjustment(SourceLocation::UIntTy Offset) const; + /// Retrieve or create a submodule ID for this module. unsigned getSubmoduleID(Module *Mod); @@ -464,18 +499,16 @@ private: void WriteBlockInfoBlock(); void WriteControlBlock(Preprocessor &PP, ASTContext &Context, - StringRef isysroot, const std::string &OutputFile); + StringRef isysroot); /// Write out the signature and diagnostic options, and return the signature. - ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP, - ASTContext &Context); + void writeUnhashedControlBlock(Preprocessor &PP, ASTContext &Context); + ASTFileSignature backpatchSignature(); /// Calculate hash of the pcm content. - static std::pair<ASTFileSignature, ASTFileSignature> - createSignature(StringRef AllBytes, StringRef ASTBlockBytes); + std::pair<ASTFileSignature, ASTFileSignature> createSignature() const; - void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, - bool Modules); + void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP); void WritePreprocessor(const Preprocessor &PP, bool IsModule); @@ -488,7 +521,6 @@ private: bool isModule); unsigned TypeExtQualAbbrev = 0; - unsigned TypeFunctionProtoAbbrev = 0; void WriteTypeAbbrevs(); void WriteType(QualType T); @@ -532,17 +564,30 @@ private: unsigned DeclEnumAbbrev = 0; unsigned DeclObjCIvarAbbrev = 0; unsigned DeclCXXMethodAbbrev = 0; + unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0; + unsigned DeclTemplateCXXMethodAbbrev = 0; + unsigned DeclMemberSpecializedCXXMethodAbbrev = 0; + unsigned DeclTemplateSpecializedCXXMethodAbbrev = 0; + unsigned DeclDependentSpecializationCXXMethodAbbrev = 0; + unsigned DeclTemplateTypeParmAbbrev = 0; + unsigned DeclUsingShadowAbbrev = 0; unsigned DeclRefExprAbbrev = 0; unsigned CharacterLiteralAbbrev = 0; unsigned IntegerLiteralAbbrev = 0; unsigned ExprImplicitCastAbbrev = 0; + unsigned BinaryOperatorAbbrev = 0; + unsigned CompoundAssignOperatorAbbrev = 0; + unsigned CallExprAbbrev = 0; + unsigned CXXOperatorCallExprAbbrev = 0; + unsigned CXXMemberCallExprAbbrev = 0; + + unsigned CompoundStmtAbbrev = 0; void WriteDeclAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot, - const std::string &OutputFile, Module *WritingModule); public: @@ -551,7 +596,7 @@ public: ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer, InMemoryModuleCache &ModuleCache, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, - bool IncludeTimestamps = true); + bool IncludeTimestamps = true, bool BuildingImplicitModule = false); ~ASTWriter() override; ASTContext &getASTContext() const { @@ -580,9 +625,8 @@ public: /// /// \return the module signature, which eventually will be a hash of /// the module but currently is merely a random 32-bit number. - ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile, + ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile, Module *WritingModule, StringRef isysroot, - bool hasErrors = false, bool ShouldCacheASTInMemory = false); /// Emit a token. @@ -592,11 +636,16 @@ public: void AddAlignPackInfo(const Sema::AlignPackInfo &Info, RecordDataImpl &Record); + /// Emit a FileID. + void AddFileID(FileID FID, RecordDataImpl &Record); + /// Emit a source location. - void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record); + void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record, + LocSeq *Seq = nullptr); /// Emit a source range. - void AddSourceRange(SourceRange Range, RecordDataImpl &Record); + void AddSourceRange(SourceRange Range, RecordDataImpl &Record, + LocSeq *Seq = nullptr); /// Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); @@ -693,10 +742,6 @@ public: return TypeExtQualAbbrev; } - unsigned getTypeFunctionProtoAbbrev() const { - return TypeFunctionProtoAbbrev; - } - unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; } unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; } unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; } @@ -704,16 +749,49 @@ public: unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; } unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; } unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; } - unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; } + unsigned getDeclCXXMethodAbbrev(FunctionDecl::TemplatedKind Kind) const { + switch (Kind) { + case FunctionDecl::TK_NonTemplate: + return DeclCXXMethodAbbrev; + case FunctionDecl::TK_FunctionTemplate: + return DeclTemplateCXXMethodAbbrev; + case FunctionDecl::TK_MemberSpecialization: + return DeclMemberSpecializedCXXMethodAbbrev; + case FunctionDecl::TK_FunctionTemplateSpecialization: + return DeclTemplateSpecializedCXXMethodAbbrev; + case FunctionDecl::TK_DependentNonTemplate: + return DeclDependentNonTemplateCXXMethodAbbrev; + case FunctionDecl::TK_DependentFunctionTemplateSpecialization: + return DeclDependentSpecializationCXXMethodAbbrev; + } + llvm_unreachable("Unknwon Template Kind!"); + } + unsigned getDeclTemplateTypeParmAbbrev() const { + return DeclTemplateTypeParmAbbrev; + } + unsigned getDeclUsingShadowAbbrev() const { return DeclUsingShadowAbbrev; } unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; } unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; } unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; } unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; } + unsigned getBinaryOperatorAbbrev() const { return BinaryOperatorAbbrev; } + unsigned getCompoundAssignOperatorAbbrev() const { + return CompoundAssignOperatorAbbrev; + } + unsigned getCallExprAbbrev() const { return CallExprAbbrev; } + unsigned getCXXOperatorCallExprAbbrev() { return CXXOperatorCallExprAbbrev; } + unsigned getCXXMemberCallExprAbbrev() { return CXXMemberCallExprAbbrev; } + + unsigned getCompoundStmtAbbrev() const { return CompoundStmtAbbrev; } bool hasChain() const { return Chain; } ASTReader *getChain() const { return Chain; } + bool isWritingStdCXXNamedModules() const { + return WritingModule && WritingModule->isNamedModule(); + } + private: // ASTDeserializationListener implementation void ReaderInitialized(ASTReader *Reader) override; @@ -784,6 +862,7 @@ public: std::shared_ptr<PCHBuffer> Buffer, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, bool AllowASTWithErrors = false, bool IncludeTimestamps = true, + bool BuildingImplicitModule = false, bool ShouldCacheASTInMemory = false); ~PCHGenerator() override; @@ -794,6 +873,46 @@ public: bool hasEmittedPCH() const { return Buffer->IsComplete; } }; +/// A simple helper class to pack several bits in order into (a) 32 bit +/// integer(s). +class BitsPacker { + constexpr static uint32_t BitIndexUpbound = 32u; + +public: + BitsPacker() = default; + BitsPacker(const BitsPacker &) = delete; + BitsPacker(BitsPacker &&) = delete; + BitsPacker operator=(const BitsPacker &) = delete; + BitsPacker operator=(BitsPacker &&) = delete; + ~BitsPacker() = default; + + bool canWriteNextNBits(uint32_t BitsWidth) const { + return CurrentBitIndex + BitsWidth < BitIndexUpbound; + } + + void reset(uint32_t Value) { + UnderlyingValue = Value; + CurrentBitIndex = 0; + } + + void addBit(bool Value) { addBits(Value, 1); } + void addBits(uint32_t Value, uint32_t BitsWidth) { + assert(BitsWidth < BitIndexUpbound); + assert((Value < (1u << BitsWidth)) && "Passing narrower bit width!"); + assert(canWriteNextNBits(BitsWidth) && + "Inserting too much bits into a value!"); + + UnderlyingValue |= Value << CurrentBitIndex; + CurrentBitIndex += BitsWidth; + } + + operator uint32_t() { return UnderlyingValue; } + +private: + uint32_t UnderlyingValue = 0; + uint32_t CurrentBitIndex = 0; +}; + } // namespace clang #endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H diff --git a/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h b/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h index 5f4812626224..93d674e44003 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h @@ -31,8 +31,6 @@ class MemoryBuffer; namespace clang { -class DirectoryEntry; -class FileEntry; class FileManager; class IdentifierIterator; class PCHContainerOperations; @@ -69,20 +67,20 @@ class GlobalModuleIndex { /// Information about a given module file. struct ModuleInfo { - ModuleInfo() : File(), Size(), ModTime() { } + ModuleInfo() = default; /// The module file, once it has been resolved. - ModuleFile *File; + ModuleFile *File = nullptr; /// The module file name. std::string FileName; /// Size of the module file at the time the global index was built. - off_t Size; + off_t Size = 0; /// Modification time of the module file at the time the global /// index was built. - time_t ModTime; + time_t ModTime = 0; /// The module IDs on which this module directly depends. /// FIXME: We don't really need a vector here. @@ -138,12 +136,6 @@ public: /// The caller accepts ownership of the returned object. IdentifierIterator *createIdentifierIterator() const; - /// Retrieve the set of modules that have up-to-date indexes. - /// - /// \param ModuleFiles Will be populated with the set of module files that - /// have been indexed. - void getKnownModules(llvm::SmallVectorImpl<ModuleFile *> &ModuleFiles); - /// Retrieve the set of module files on which the given module file /// directly depends. void getModuleDependencies(ModuleFile *File, diff --git a/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h b/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h index 7b5b5c1cf1be..fc3ba334fc64 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h @@ -10,7 +10,6 @@ #define LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/MemoryBuffer.h" #include <memory> diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h index b1c8a8c8e72b..9a14129d72ff 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h @@ -20,6 +20,7 @@ #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ContinuousRangeMap.h" #include "clang/Serialization/ModuleFileExtension.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SetVector.h" @@ -58,6 +59,19 @@ enum ModuleKind { MK_PrebuiltModule }; +/// The input file info that has been loaded from an AST file. +struct InputFileInfo { + std::string FilenameAsRequested; + std::string Filename; + uint64_t ContentHash; + off_t StoredSize; + time_t StoredTime; + bool Overridden; + bool Transient; + bool TopLevel; + bool ModuleMap; +}; + /// The input file that has been loaded from this AST file, along with /// bools indicating whether this was an overridden buffer or if it was /// out-of-date or not-found. @@ -90,10 +104,10 @@ public: return File; } - OptionalFileEntryRefDegradesToFileEntryPtr getFile() const { + OptionalFileEntryRef getFile() const { if (auto *P = Val.getPointer()) return FileEntryRef(*P); - return None; + return std::nullopt; } bool isOverridden() const { return Val.getInt() == Overridden; } bool isOutOfDate() const { return Val.getInt() == OutOfDate; } @@ -109,8 +123,8 @@ public: /// other modules. class ModuleFile { public: - ModuleFile(ModuleKind Kind, unsigned Generation) - : Kind(Kind), Generation(Generation) {} + ModuleFile(ModuleKind Kind, FileEntryRef File, unsigned Generation) + : Kind(Kind), File(File), Generation(Generation) {} ~ModuleFile(); // === General information === @@ -147,15 +161,14 @@ public: /// build this AST file. FileID OriginalSourceFileID; - /// The directory that the PCH was originally created in. Used to - /// allow resolving headers even after headers+PCH was moved to a new path. - std::string OriginalDir; - std::string ModuleMapPath; /// Whether this precompiled header is a relocatable PCH file. bool RelocatablePCH = false; + /// Whether this module file is a standard C++ module. + bool StandardCXXModule = false; + /// Whether timestamps are included in this module file. bool HasTimestamps = false; @@ -163,7 +176,7 @@ public: bool DidReadTopLevelSubmodule = false; /// The file entry for the module file. - OptionalFileEntryRefDegradesToFileEntryPtr File; + FileEntryRef File; /// The signature of the module file, which may be used instead of the size /// and modification time to identify this particular file. @@ -173,6 +186,9 @@ public: /// unique module files based on AST contents. ASTFileSignature ASTBlockHash; + /// The bit vector denoting usage of each header search entry (true = used). + llvm::BitVector SearchPathUsage; + /// Whether this module has been directly imported by the /// user. bool DirectlyImported = false; @@ -182,7 +198,7 @@ public: /// The memory buffer that stores the data associated with /// this AST file, owned by the InMemoryModuleCache. - llvm::MemoryBuffer *Buffer; + llvm::MemoryBuffer *Buffer = nullptr; /// The size of this file, in bits. uint64_t SizeInBits = 0; @@ -229,12 +245,18 @@ public: /// The cursor to the start of the input-files block. llvm::BitstreamCursor InputFilesCursor; - /// Offsets for all of the input file entries in the AST file. + /// Absolute offset of the start of the input-files block. + uint64_t InputFilesOffsetBase = 0; + + /// Relative offsets for all of the input file entries in the AST file. const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr; /// The input files that have been loaded from this AST file. std::vector<InputFile> InputFilesLoaded; + /// The input file infos that have been loaded from this AST file. + std::vector<InputFileInfo> InputFileInfosLoaded; + // All user input files reside at the index range [0, NumUserInputFiles), and // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()). unsigned NumUserInputFiles = 0; @@ -270,9 +292,6 @@ public: /// AST file. const uint32_t *SLocEntryOffsets = nullptr; - /// SLocEntries that we're going to preload. - SmallVector<uint64_t, 4> PreloadSLocEntries; - /// Remapping table for source locations in this module. ContinuousRangeMap<SourceLocation::UIntTy, SourceLocation::IntTy, 2> SLocRemap; diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h index 34ea870724a4..d7d456c8b5db 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h @@ -11,13 +11,14 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Support/ExtensibleRTTI.h" +#include "llvm/Support/HashBuilder.h" +#include "llvm/Support/MD5.h" #include <memory> #include <string> namespace llvm { class BitstreamCursor; class BitstreamWriter; -class hash_code; class raw_ostream; } @@ -74,19 +75,19 @@ public: virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0; /// Hash information about the presence of this extension into the - /// module hash code. + /// module hash. /// - /// The module hash code is used to distinguish different variants - /// of a module that are incompatible. If the presence, absence, or - /// version of the module file extension should force the creation - /// of a separate set of module files, override this method to - /// combine that distinguishing information into the module hash - /// code. + /// The module hash is used to distinguish different variants of a module that + /// are incompatible. If the presence, absence, or version of the module file + /// extension should force the creation of a separate set of module files, + /// override this method to combine that distinguishing information into the + /// module hash. /// - /// The default implementation of this function simply returns the - /// hash code as given, so the presence/absence of this extension - /// does not distinguish module files. - virtual llvm::hash_code hashExtension(llvm::hash_code c) const; + /// The default implementation of this function simply does nothing, so the + /// presence/absence of this extension does not distinguish module files. + using ExtensionHashBuilder = + llvm::HashBuilder<llvm::MD5, llvm::endianness::native>; + virtual void hashExtension(ExtensionHashBuilder &HBuilder) const; /// Create a new module file extension writer, which will be /// responsible for writing the extension contents into a particular @@ -152,4 +153,4 @@ public: } // end namespace clang -#endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H +#endif // LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h index 7081eedad4b4..3bd379acf7ed 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h @@ -39,7 +39,6 @@ class FileManager; class GlobalModuleIndex; class HeaderSearch; class InMemoryModuleCache; -class ModuleMap; class PCHContainerReader; namespace serialization { @@ -105,10 +104,6 @@ class ModuleManager { Stack.reserve(N); } - ~VisitState() { - delete NextState; - } - /// The stack used when marking the imports of a particular module /// as not-to-be-visited. SmallVector<ModuleFile *, 4> Stack; @@ -121,14 +116,14 @@ class ModuleManager { unsigned NextVisitNumber = 1; /// The next visit state. - VisitState *NextState = nullptr; + std::unique_ptr<VisitState> NextState; }; /// The first visit() state in the chain. - VisitState *FirstVisitState = nullptr; + std::unique_ptr<VisitState> FirstVisitState; - VisitState *allocateVisitState(); - void returnVisitState(VisitState *State); + std::unique_ptr<VisitState> allocateVisitState(); + void returnVisitState(std::unique_ptr<VisitState> State); public: using ModuleIterator = llvm::pointee_iterator< @@ -142,7 +137,6 @@ public: explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const HeaderSearch &HeaderSearchInfo); - ~ModuleManager(); /// Forward iterator to traverse all loaded modules. ModuleIterator begin() { return Chain.begin(); } @@ -255,7 +249,7 @@ public: std::string &ErrorStr); /// Remove the modules starting from First (to the end). - void removeModules(ModuleIterator First, ModuleMap *modMap); + void removeModules(ModuleIterator First); /// Add an in-memory buffer the list of known buffers void addInMemoryBuffer(StringRef FileName, @@ -308,7 +302,7 @@ public: /// modification time criteria, false if the file is either available and /// suitable, or is missing. bool lookupModuleFile(StringRef FileName, off_t ExpectedSize, - time_t ExpectedModTime, Optional<FileEntryRef> &File); + time_t ExpectedModTime, OptionalFileEntryRef &File); /// View the graphviz representation of the module graph. void viewGraph(); diff --git a/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h b/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h index 33fc4a0a24e0..be10feb5e351 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h +++ b/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h @@ -22,8 +22,6 @@ class raw_pwrite_stream; namespace clang { class ASTConsumer; -class CodeGenOptions; -class DiagnosticsEngine; class CompilerInstance; struct PCHBuffer { @@ -58,7 +56,7 @@ class PCHContainerReader { public: virtual ~PCHContainerReader() = 0; /// Equivalent to the format passed to -fmodule-format= - virtual llvm::StringRef getFormat() const = 0; + virtual llvm::ArrayRef<llvm::StringRef> getFormats() const = 0; /// Returns the serialized AST inside the PCH container Buffer. virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0; @@ -80,8 +78,7 @@ class RawPCHContainerWriter : public PCHContainerWriter { /// Implements read operations for a raw pass-through PCH container. class RawPCHContainerReader : public PCHContainerReader { - llvm::StringRef getFormat() const override { return "raw"; } - + llvm::ArrayRef<llvm::StringRef> getFormats() const override; /// Simply returns the buffer contained in Buffer. llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override; }; @@ -89,7 +86,9 @@ class RawPCHContainerReader : public PCHContainerReader { /// A registry of PCHContainerWriter and -Reader objects for different formats. class PCHContainerOperations { llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers; - llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers; + llvm::StringMap<PCHContainerReader *> Readers; + llvm::SmallVector<std::unique_ptr<PCHContainerReader>> OwnedReaders; + public: /// Automatically registers a RawPCHContainerWriter and /// RawPCHContainerReader. @@ -98,13 +97,17 @@ public: Writers[Writer->getFormat()] = std::move(Writer); } void registerReader(std::unique_ptr<PCHContainerReader> Reader) { - Readers[Reader->getFormat()] = std::move(Reader); + assert(!Reader->getFormats().empty() && + "PCHContainerReader must handle >=1 format"); + for (llvm::StringRef Fmt : Reader->getFormats()) + Readers[Fmt] = Reader.get(); + OwnedReaders.push_back(std::move(Reader)); } const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) { return Writers[Format].get(); } const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) { - return Readers[Format].get(); + return Readers[Format]; } const PCHContainerReader &getRawReader() { return *getReaderOrNull("raw"); diff --git a/contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h b/contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h new file mode 100644 index 000000000000..9bb0dbe2e4d6 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h @@ -0,0 +1,163 @@ +//===--- SourceLocationEncoding.h - Small serialized locations --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Source locations are stored pervasively in the AST, making up a third of +// the size of typical serialized files. Storing them efficiently is important. +// +// We use integers optimized by VBR-encoding, because: +// - when abbreviations cannot be used, VBR6 encoding is our only choice +// - in the worst case a SourceLocation can be ~any 32-bit number, but in +// practice they are highly predictable +// +// We encode the integer so that likely values encode as small numbers that +// turn into few VBR chunks: +// - the invalid sentinel location is a very common value: it encodes as 0 +// - the "macro or not" bit is stored at the bottom of the integer +// (rather than at the top, as in memory), so macro locations can have +// small representations. +// - related locations (e.g. of a left and right paren pair) are usually +// similar, so when encoding a sequence of locations we store only +// differences between successive elements. +// +//===----------------------------------------------------------------------===// + +#include <climits> +#include "clang/Basic/SourceLocation.h" + +#ifndef LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H +#define LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H + +namespace clang { +class SourceLocationSequence; + +/// Serialized encoding of SourceLocations without context. +/// Optimized to have small unsigned values (=> small after VBR encoding). +/// +// Macro locations have the top bit set, we rotate by one so it is the low bit. +class SourceLocationEncoding { + using UIntTy = SourceLocation::UIntTy; + constexpr static unsigned UIntBits = CHAR_BIT * sizeof(UIntTy); + + static UIntTy encodeRaw(UIntTy Raw) { + return (Raw << 1) | (Raw >> (UIntBits - 1)); + } + static UIntTy decodeRaw(UIntTy Raw) { + return (Raw >> 1) | (Raw << (UIntBits - 1)); + } + friend SourceLocationSequence; + +public: + static uint64_t encode(SourceLocation Loc, + SourceLocationSequence * = nullptr); + static SourceLocation decode(uint64_t, SourceLocationSequence * = nullptr); +}; + +/// Serialized encoding of a sequence of SourceLocations. +/// +/// Optimized to produce small values when locations with the sequence are +/// similar. Each element can be delta-encoded against the last nonzero element. +/// +/// Sequences should be started by creating a SourceLocationSequence::State, +/// and then passed around as SourceLocationSequence*. Example: +/// +/// // establishes a sequence +/// void EmitTopLevelThing() { +/// SourceLocationSequence::State Seq; +/// EmitContainedThing(Seq); +/// EmitRecursiveThing(Seq); +/// } +/// +/// // optionally part of a sequence +/// void EmitContainedThing(SourceLocationSequence *Seq = nullptr) { +/// Record.push_back(SourceLocationEncoding::encode(SomeLoc, Seq)); +/// } +/// +/// // establishes a sequence if there isn't one already +/// void EmitRecursiveThing(SourceLocationSequence *ParentSeq = nullptr) { +/// SourceLocationSequence::State Seq(ParentSeq); +/// Record.push_back(SourceLocationEncoding::encode(SomeLoc, Seq)); +/// EmitRecursiveThing(Seq); +/// } +/// +class SourceLocationSequence { + using UIntTy = SourceLocation::UIntTy; + using EncodedTy = uint64_t; + constexpr static auto UIntBits = SourceLocationEncoding::UIntBits; + static_assert(sizeof(EncodedTy) > sizeof(UIntTy), "Need one extra bit!"); + + // Prev stores the rotated last nonzero location. + UIntTy &Prev; + + // Zig-zag encoding turns small signed integers into small unsigned integers. + // 0 => 0, -1 => 1, 1 => 2, -2 => 3, ... + static UIntTy zigZag(UIntTy V) { + UIntTy Sign = (V & (1 << (UIntBits - 1))) ? UIntTy(-1) : UIntTy(0); + return Sign ^ (V << 1); + } + static UIntTy zagZig(UIntTy V) { return (V >> 1) ^ -(V & 1); } + + SourceLocationSequence(UIntTy &Prev) : Prev(Prev) {} + + EncodedTy encodeRaw(UIntTy Raw) { + if (Raw == 0) + return 0; + UIntTy Rotated = SourceLocationEncoding::encodeRaw(Raw); + if (Prev == 0) + return Prev = Rotated; + UIntTy Delta = Rotated - Prev; + Prev = Rotated; + // Exactly one 33 bit value is possible! (1 << 32). + // This is because we have two representations of zero: trivial & relative. + return 1 + EncodedTy{zigZag(Delta)}; + } + UIntTy decodeRaw(EncodedTy Encoded) { + if (Encoded == 0) + return 0; + if (Prev == 0) + return SourceLocationEncoding::decodeRaw(Prev = Encoded); + return SourceLocationEncoding::decodeRaw(Prev += zagZig(Encoded - 1)); + } + +public: + SourceLocation decode(EncodedTy Encoded) { + return SourceLocation::getFromRawEncoding(decodeRaw(Encoded)); + } + EncodedTy encode(SourceLocation Loc) { + return encodeRaw(Loc.getRawEncoding()); + } + + class State; +}; + +/// This object establishes a SourceLocationSequence. +class SourceLocationSequence::State { + UIntTy Prev = 0; + SourceLocationSequence Seq; + +public: + // If Parent is provided and non-null, then this root becomes part of that + // enclosing sequence instead of establishing a new one. + State(SourceLocationSequence *Parent = nullptr) + : Seq(Parent ? Parent->Prev : Prev) {} + + // Implicit conversion for uniform use of roots vs propagated sequences. + operator SourceLocationSequence *() { return &Seq; } +}; + +inline uint64_t SourceLocationEncoding::encode(SourceLocation Loc, + SourceLocationSequence *Seq) { + return Seq ? Seq->encode(Loc) : encodeRaw(Loc.getRawEncoding()); +} +inline SourceLocation +SourceLocationEncoding::decode(uint64_t Encoded, SourceLocationSequence *Seq) { + return Seq ? Seq->decode(Encoded) + : SourceLocation::getFromRawEncoding(decodeRaw(Encoded)); +} + +} // namespace clang +#endif diff --git a/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def b/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def index e92e05810648..89ae1a2fa395 100644 --- a/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def +++ b/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def @@ -58,9 +58,11 @@ TYPE_BIT_CODE(DependentSizedExtVector, DEPENDENT_SIZED_EXT_VECTOR, 46) TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47) TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48) TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49) -TYPE_BIT_CODE(ExtInt, EXT_INT, 50) -TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51) +TYPE_BIT_CODE(BitInt, BIT_INT, 50) +TYPE_BIT_CODE(DependentBitInt, DEPENDENT_BIT_INT, 51) TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52) TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53) +TYPE_BIT_CODE(Using, USING, 54) +TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55) #undef TYPE_BIT_CODE |