diff options
Diffstat (limited to 'clang-r353983/include/clang/Serialization')
13 files changed, 12147 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/Serialization/ASTBitCodes.h b/clang-r353983/include/clang/Serialization/ASTBitCodes.h new file mode 100644 index 00000000..a1ab6116 --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ASTBitCodes.h @@ -0,0 +1,2142 @@ +//===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- 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 +// +//===----------------------------------------------------------------------===// +// +// This header defines Bitcode enum values for Clang serialized AST files. +// +// The enum values defined in this file should be considered permanent. If +// new features are added, they should have values added at the end of the +// respective lists. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H +#define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H + +#include "clang/AST/DeclarationName.h" +#include "clang/AST/Type.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/Bitcode/BitCodes.h" +#include <cassert> +#include <cstdint> + +namespace clang { +namespace serialization { + + /// AST file major version number supported by this version of + /// Clang. + /// + /// Whenever the AST file format changes in a way that makes it + /// incompatible with previous versions (such that a reader + /// designed for the previous version could not support reading + /// the new version), this number should be increased. + /// + /// 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 = 7; + + /// AST file minor version number supported by this version of + /// Clang. + /// + /// Whenever the AST format changes in a way that is still + /// compatible with previous versions (such that a reader designed + /// 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; + + /// An ID number that refers to an identifier in an AST file. + /// + /// The ID numbers of identifiers are consecutive (in order of discovery) + /// and start at 1. 0 is reserved for NULL. + using IdentifierID = uint32_t; + + /// An ID number that refers to a declaration in an AST file. + /// + /// The ID numbers of declarations are consecutive (in order of + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. + using DeclID = uint32_t; + + // FIXME: Turn these into classes so we can have some type safety when + // we go from local ID to global and vice-versa. + using LocalDeclID = DeclID; + using GlobalDeclID = DeclID; + + /// An ID number that refers to a type in an AST file. + /// + /// The ID of a type is partitioned into two parts: the lower + /// three bits are used to store the const/volatile/restrict + /// qualifiers (as with QualType) and the upper bits provide a + /// type index. The type index values are partitioned into two + /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type + /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a + /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are + /// other types that have serialized representations. + using TypeID = uint32_t; + + /// A type index; the type ID with the qualifier bits removed. + class TypeIdx { + uint32_t Idx = 0; + + public: + TypeIdx() = default; + explicit TypeIdx(uint32_t index) : Idx(index) {} + + uint32_t getIndex() const { return Idx; } + + TypeID asTypeID(unsigned FastQuals) const { + if (Idx == uint32_t(-1)) + return TypeID(-1); + + return (Idx << Qualifiers::FastWidth) | FastQuals; + } + + static TypeIdx fromTypeID(TypeID ID) { + if (ID == TypeID(-1)) + return TypeIdx(-1); + + return TypeIdx(ID >> Qualifiers::FastWidth); + } + }; + + /// A structure for putting "fast"-unqualified QualTypes into a + /// DenseMap. This uses the standard pointer hash function. + struct UnsafeQualTypeDenseMapInfo { + static bool isEqual(QualType A, QualType B) { return A == B; } + + static QualType getEmptyKey() { + return QualType::getFromOpaquePtr((void*) 1); + } + + static QualType getTombstoneKey() { + return QualType::getFromOpaquePtr((void*) 2); + } + + static unsigned getHashValue(QualType T) { + assert(!T.getLocalFastQualifiers() && + "hash invalid for types with fast quals"); + uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); + return (unsigned(v) >> 4) ^ (unsigned(v) >> 9); + } + }; + + /// An ID number that refers to an identifier in an AST file. + using IdentID = uint32_t; + + /// The number of predefined identifier IDs. + const unsigned int NUM_PREDEF_IDENT_IDS = 1; + + /// An ID number that refers to a macro in an AST file. + using MacroID = uint32_t; + + /// A global ID number that refers to a macro in an AST file. + using GlobalMacroID = uint32_t; + + /// A local to a module ID number that refers to a macro in an + /// AST file. + using LocalMacroID = uint32_t; + + /// The number of predefined macro IDs. + const unsigned int NUM_PREDEF_MACRO_IDS = 1; + + /// An ID number that refers to an ObjC selector in an AST file. + using SelectorID = uint32_t; + + /// The number of predefined selector IDs. + const unsigned int NUM_PREDEF_SELECTOR_IDS = 1; + + /// An ID number that refers to a set of CXXBaseSpecifiers in an + /// AST file. + using CXXBaseSpecifiersID = uint32_t; + + /// An ID number that refers to a list of CXXCtorInitializers in an + /// AST file. + using CXXCtorInitializersID = uint32_t; + + /// An ID number that refers to an entity in the detailed + /// preprocessing record. + using PreprocessedEntityID = uint32_t; + + /// An ID number that refers to a submodule in a module file. + using SubmoduleID = uint32_t; + + /// The number of predefined submodule IDs. + const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1; + + /// Source range/offset of a preprocessed entity. + struct PPEntityOffset { + /// Raw source location of beginning of range. + unsigned Begin; + + /// Raw source location of end of range. + unsigned End; + + /// Offset in the AST file. + uint32_t BitOffset; + + PPEntityOffset(SourceRange R, uint32_t BitOffset) + : Begin(R.getBegin().getRawEncoding()), + End(R.getEnd().getRawEncoding()), BitOffset(BitOffset) {} + + SourceLocation getBegin() const { + return SourceLocation::getFromRawEncoding(Begin); + } + + SourceLocation getEnd() const { + return SourceLocation::getFromRawEncoding(End); + } + }; + + /// Source range of a skipped preprocessor region + struct PPSkippedRange { + /// Raw source location of beginning of range. + unsigned Begin; + /// Raw source location of end of range. + unsigned End; + + PPSkippedRange(SourceRange R) + : Begin(R.getBegin().getRawEncoding()), + End(R.getEnd().getRawEncoding()) { } + + SourceLocation getBegin() const { + return SourceLocation::getFromRawEncoding(Begin); + } + SourceLocation getEnd() const { + return SourceLocation::getFromRawEncoding(End); + } + }; + + /// Source range/offset of a preprocessed entity. + struct DeclOffset { + /// Raw source location. + unsigned Loc = 0; + + /// Offset in the AST file. + uint32_t BitOffset = 0; + + DeclOffset() = default; + DeclOffset(SourceLocation Loc, uint32_t BitOffset) + : Loc(Loc.getRawEncoding()), BitOffset(BitOffset) {} + + void setLocation(SourceLocation L) { + Loc = L.getRawEncoding(); + } + + SourceLocation getLocation() const { + return SourceLocation::getFromRawEncoding(Loc); + } + }; + + /// The number of predefined preprocessed entity IDs. + const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1; + + /// Describes the various kinds of blocks that occur within + /// an AST file. + enum BlockIDs { + /// The AST block, which acts as a container around the + /// full AST block. + AST_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID, + + /// The block containing information about the source + /// manager. + SOURCE_MANAGER_BLOCK_ID, + + /// The block containing information about the + /// preprocessor. + PREPROCESSOR_BLOCK_ID, + + /// The block containing the definitions of all of the + /// types and decls used within the AST file. + DECLTYPES_BLOCK_ID, + + /// The block containing the detailed preprocessing record. + PREPROCESSOR_DETAIL_BLOCK_ID, + + /// The block containing the submodule structure. + SUBMODULE_BLOCK_ID, + + /// The block containing comments. + COMMENTS_BLOCK_ID, + + /// The control block, which contains all of the + /// information that needs to be validated prior to committing + /// to loading the AST file. + CONTROL_BLOCK_ID, + + /// The block of input files, which were used as inputs + /// to create this AST file. + /// + /// This block is part of the control block. + INPUT_FILES_BLOCK_ID, + + /// The block of configuration options, used to check that + /// a module is being used in a configuration compatible with the + /// configuration in which it was built. + /// + /// This block is part of the control block. + OPTIONS_BLOCK_ID, + + /// A block containing a module file extension. + EXTENSION_BLOCK_ID, + + /// A block with unhashed content. + /// + /// These records should not change the \a ASTFileSignature. See \a + /// UnhashedControlBlockRecordTypes for the list of records. + UNHASHED_CONTROL_BLOCK_ID, + }; + + /// Record types that occur within the control block. + enum ControlRecordTypes { + /// AST file metadata, including the AST file version number + /// and information about the compiler used to build this AST file. + METADATA = 1, + + /// Record code for the list of other AST files imported by + /// this AST file. + IMPORTS, + + /// Record code for the original file that was used to + /// generate the AST file, including both its file ID and its + /// 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, + + /// Offsets into the input-files block where input files + /// reside. + INPUT_FILE_OFFSETS, + + /// Record code for the module name. + MODULE_NAME, + + /// Record code for the module map file that was used to build this + /// AST file. + MODULE_MAP_FILE, + + /// Record code for the module build directory. + MODULE_DIRECTORY, + }; + + /// Record types that occur within the options block inside + /// the control block. + enum OptionsRecordTypes { + /// Record code for the language options table. + /// + /// The record with this code contains the contents of the + /// LangOptions structure. We serialize the entire contents of + /// the structure, and let the reader decide which options are + /// actually important to check. + LANGUAGE_OPTIONS = 1, + + /// Record code for the target options table. + TARGET_OPTIONS, + + /// Record code for the filesystem options table. + FILE_SYSTEM_OPTIONS, + + /// Record code for the headers search options table. + HEADER_SEARCH_OPTIONS, + + /// Record code for the preprocessor options table. + PREPROCESSOR_OPTIONS, + }; + + /// Record codes for the unhashed control block. + enum UnhashedControlBlockRecordTypes { + /// Record code for the signature that identifiers this AST file. + SIGNATURE = 1, + + /// Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS, + + /// Record code for \#pragma diagnostic mappings. + DIAG_PRAGMA_MAPPINGS, + }; + + /// Record code for extension blocks. + enum ExtensionBlockRecordTypes { + /// Metadata describing this particular extension. + EXTENSION_METADATA = 1, + + /// The first record ID allocated to the extensions themselves. + FIRST_EXTENSION_RECORD_ID = 4 + }; + + /// Record types that occur within the input-files block + /// inside the control block. + enum InputFileRecordTypes { + /// An input file. + INPUT_FILE = 1 + }; + + /// Record types that occur within the AST block itself. + enum ASTRecordTypes { + /// Record code for the offsets of each type. + /// + /// The TYPE_OFFSET constant describes the record that occurs + /// within the AST block. The record itself is an array of offsets that + /// point into the declarations and types block (identified by + /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID + /// of a type. For a given type ID @c T, the lower three bits of + /// @c T are its qualifiers (const, volatile, restrict), as in + /// the QualType class. The upper bits, after being shifted and + /// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the + /// TYPE_OFFSET block to determine the offset of that type's + /// corresponding record within the DECLTYPES_BLOCK_ID block. + TYPE_OFFSET = 1, + + /// Record code for the offsets of each decl. + /// + /// The DECL_OFFSET constant describes the record that occurs + /// within the block identified by DECL_OFFSETS_BLOCK_ID within + /// the AST block. The record itself is an array of offsets that + /// point into the declarations and types block (identified by + /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this + /// record, after subtracting one to account for the use of + /// declaration ID 0 for a NULL declaration pointer. Index 0 is + /// reserved for the translation unit declaration. + DECL_OFFSET = 2, + + /// Record code for the table of offsets of each + /// identifier ID. + /// + /// The offset table contains offsets into the blob stored in + /// the IDENTIFIER_TABLE record. Each offset points to the + /// NULL-terminated string that corresponds to that identifier. + IDENTIFIER_OFFSET = 3, + + /// This is so that older clang versions, before the introduction + /// of the control block, can read and reject the newer PCH format. + /// *DON'T CHANGE THIS NUMBER*. + METADATA_OLD_FORMAT = 4, + + /// Record code for the identifier table. + /// + /// The identifier table is a simple blob that contains + /// NULL-terminated strings for all of the identifiers + /// referenced by the AST file. The IDENTIFIER_OFFSET table + /// contains the mapping from identifier IDs to the characters + /// in this blob. Note that the starting offsets of all of the + /// identifiers are odd, so that, when the identifier offset + /// table is loaded in, we can use the low bit to distinguish + /// between offsets (for unresolved identifier IDs) and + /// IdentifierInfo pointers (for already-resolved identifier + /// IDs). + IDENTIFIER_TABLE = 5, + + /// Record code for the array of eagerly deserialized decls. + /// + /// The AST file contains a list of all of the declarations that should be + /// eagerly deserialized present within the parsed headers, stored as an + /// array of declaration IDs. These declarations will be + /// reported to the AST consumer after the AST file has been + /// read, since their presence can affect the semantics of the + /// program (e.g., for code generation). + EAGERLY_DESERIALIZED_DECLS = 6, + + /// Record code for the set of non-builtin, special + /// types. + /// + /// This record contains the type IDs for the various type nodes + /// that are constructed during semantic analysis (e.g., + /// __builtin_va_list). The SPECIAL_TYPE_* constants provide + /// offsets into this record. + SPECIAL_TYPES = 7, + + /// Record code for the extra statistics we gather while + /// generating an AST file. + STATISTICS = 8, + + /// Record code for the array of tentative definitions. + TENTATIVE_DEFINITIONS = 9, + + // ID 10 used to be for a list of extern "C" declarations. + + /// Record code for the table of offsets into the + /// Objective-C method pool. + SELECTOR_OFFSETS = 11, + + /// Record code for the Objective-C method pool, + METHOD_POOL = 12, + + /// The value of the next __COUNTER__ to dispense. + /// [PP_COUNTER_VALUE, Val] + PP_COUNTER_VALUE = 13, + + /// Record code for the table of offsets into the block + /// 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, + + /// Record code for the set of ext_vector type names. + EXT_VECTOR_DECLS = 16, + + /// Record code for the array of unused file scoped decls. + UNUSED_FILESCOPED_DECLS = 17, + + /// Record code for the table of offsets to entries in the + /// preprocessing record. + PPD_ENTITIES_OFFSETS = 18, + + /// Record code for the array of VTable uses. + VTABLE_USES = 19, + + // ID 20 used to be for a list of dynamic classes. + + /// Record code for referenced selector pool. + REFERENCED_SELECTOR_POOL = 21, + + /// Record code for an update to the TU's lexically contained + /// declarations. + TU_UPDATE_LEXICAL = 22, + + // ID 23 used to be for a list of local redeclarations. + + /// Record code for declarations that Sema keeps references of. + SEMA_DECL_REFS = 24, + + /// Record code for weak undeclared identifiers. + WEAK_UNDECLARED_IDENTIFIERS = 25, + + /// Record code for pending implicit instantiations. + PENDING_IMPLICIT_INSTANTIATIONS = 26, + + // ID 27 used to be for a list of replacement decls. + + /// Record code for an update to a decl context's lookup table. + /// + /// In practice, this should only be used for the TU and namespaces. + UPDATE_VISIBLE = 28, + + /// Record for offsets of DECL_UPDATES records for declarations + /// that were modified after being deserialized and need updates. + DECL_UPDATE_OFFSETS = 29, + + // ID 30 used to be a decl update record. These are now in the DECLTYPES + // block. + + // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records. + + // ID 32 used to be the code for \#pragma diagnostic mappings. + + /// Record code for special CUDA declarations. + CUDA_SPECIAL_DECL_REFS = 33, + + /// Record code for header search information. + HEADER_SEARCH_TABLE = 34, + + /// Record code for floating point \#pragma options. + FP_PRAGMA_OPTIONS = 35, + + /// Record code for enabled OpenCL extensions. + OPENCL_EXTENSIONS = 36, + + /// The list of delegating constructor declarations. + DELEGATING_CTORS = 37, + + /// Record code for the set of known namespaces, which are used + /// for typo correction. + KNOWN_NAMESPACES = 38, + + /// Record code for the remapping information used to relate + /// loaded modules to the various offsets and IDs(e.g., source location + /// offests, declaration and type IDs) that are used in that module to + /// refer to other modules. + MODULE_OFFSET_MAP = 39, + + /// Record code for the source manager line table information, + /// which stores information about \#line directives. + SOURCE_MANAGER_LINE_TABLE = 40, + + /// Record code for map of Objective-C class definition IDs to the + /// ObjC categories in a module that are attached to that class. + OBJC_CATEGORIES_MAP = 41, + + /// Record code for a file sorted array of DeclIDs in a module. + FILE_SORTED_DECLS = 42, + + /// Record code for an array of all of the (sub)modules that were + /// imported by the AST file. + IMPORTED_MODULES = 43, + + // ID 44 used to be a table of merged canonical declarations. + // ID 45 used to be a list of declaration IDs of local redeclarations. + + /// Record code for the array of Objective-C categories (including + /// extensions). + /// + /// This array can only be interpreted properly using the Objective-C + /// categories map. + OBJC_CATEGORIES = 46, + + /// Record code for the table of offsets of each macro ID. + /// + /// The offset table contains offsets into the blob stored in + /// the preprocessor block. Each offset points to the corresponding + /// macro definition. + MACRO_OFFSET = 47, + + /// A list of "interesting" identifiers. Only used in C++ (where we + /// don't normally do lookups into the serialized identifier table). These + /// are eagerly deserialized. + INTERESTING_IDENTIFIERS = 48, + + /// Record code for undefined but used functions and variables that + /// need a definition in this TU. + UNDEFINED_BUT_USED = 49, + + /// Record code for late parsed template functions. + LATE_PARSED_TEMPLATE = 50, + + /// Record code for \#pragma optimize options. + OPTIMIZE_PRAGMA_OPTIONS = 51, + + /// Record code for potentially unused local typedef names. + UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52, + + // ID 53 used to be a table of constructor initializer records. + + /// Delete expressions that will be analyzed later. + DELETE_EXPRS_TO_ANALYZE = 54, + + /// Record code for \#pragma ms_struct options. + MSSTRUCT_PRAGMA_OPTIONS = 55, + + /// Record code for \#pragma ms_struct options. + POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56, + + /// Number of unmatched #pragma clang cuda_force_host_device begin + /// directives we've seen. + CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH = 57, + + /// Record code for types associated with OpenCL extensions. + OPENCL_EXTENSION_TYPES = 58, + + /// Record code for declarations associated with OpenCL extensions. + OPENCL_EXTENSION_DECLS = 59, + + MODULAR_CODEGEN_DECLS = 60, + + /// Record code for \#pragma pack options. + PACK_PRAGMA_OPTIONS = 61, + + /// The stack of open #ifs/#ifdefs recorded in a preamble. + PP_CONDITIONAL_STACK = 62, + + /// A table of skipped ranges within the preprocessing record. + PPD_SKIPPED_RANGES = 63 + }; + + /// Record types used within a source manager block. + enum SourceManagerRecordTypes { + /// Describes a source location entry (SLocEntry) for a + /// file. + SM_SLOC_FILE_ENTRY = 1, + + /// Describes a source location entry (SLocEntry) for a + /// buffer. + SM_SLOC_BUFFER_ENTRY = 2, + + /// Describes a blob that contains the data for a buffer + /// entry. This kind of record always directly follows a + /// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an + /// overridden buffer. + SM_SLOC_BUFFER_BLOB = 3, + + /// Describes a zlib-compressed blob that contains the data for + /// a buffer entry. + SM_SLOC_BUFFER_BLOB_COMPRESSED = 4, + + /// Describes a source location entry (SLocEntry) for a + /// macro expansion. + SM_SLOC_EXPANSION_ENTRY = 5 + }; + + /// Record types used within a preprocessor block. + enum PreprocessorRecordTypes { + // The macros in the PP section are a PP_MACRO_* instance followed by a + // list of PP_TOKEN instances for each token in the definition. + + /// An object-like macro definition. + /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed] + PP_MACRO_OBJECT_LIKE = 1, + + /// A function-like macro definition. + /// [PP_MACRO_FUNCTION_LIKE, \<ObjectLikeStuff>, IsC99Varargs, + /// IsGNUVarars, NumArgs, ArgIdentInfoID* ] + PP_MACRO_FUNCTION_LIKE = 2, + + /// Describes one token. + /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags] + PP_TOKEN = 3, + + /// The macro directives history for a particular identifier. + PP_MACRO_DIRECTIVE_HISTORY = 4, + + /// A macro directive exported by a module. + /// [PP_MODULE_MACRO, SubmoduleID, MacroID, (Overridden SubmoduleID)*] + PP_MODULE_MACRO = 5, + }; + + /// Record types used within a preprocessor detail block. + enum PreprocessorDetailRecordTypes { + /// Describes a macro expansion within the preprocessing record. + PPD_MACRO_EXPANSION = 0, + + /// Describes a macro definition within the preprocessing record. + PPD_MACRO_DEFINITION = 1, + + /// Describes an inclusion directive within the preprocessing + /// record. + PPD_INCLUSION_DIRECTIVE = 2 + }; + + /// Record types used within a submodule description block. + enum SubmoduleRecordTypes { + /// Metadata for submodules as a whole. + SUBMODULE_METADATA = 0, + + /// Defines the major attributes of a submodule, including its + /// name and parent. + SUBMODULE_DEFINITION = 1, + + /// Specifies the umbrella header used to create this module, + /// if any. + SUBMODULE_UMBRELLA_HEADER = 2, + + /// Specifies a header that falls into this (sub)module. + SUBMODULE_HEADER = 3, + + /// Specifies a top-level header that falls into this (sub)module. + SUBMODULE_TOPHEADER = 4, + + /// Specifies an umbrella directory. + SUBMODULE_UMBRELLA_DIR = 5, + + /// Specifies the submodules that are imported by this + /// submodule. + SUBMODULE_IMPORTS = 6, + + /// Specifies the submodules that are re-exported from this + /// submodule. + SUBMODULE_EXPORTS = 7, + + /// Specifies a required feature. + SUBMODULE_REQUIRES = 8, + + /// Specifies a header that has been explicitly excluded + /// from this submodule. + SUBMODULE_EXCLUDED_HEADER = 9, + + /// Specifies a library or framework to link against. + SUBMODULE_LINK_LIBRARY = 10, + + /// Specifies a configuration macro for this module. + SUBMODULE_CONFIG_MACRO = 11, + + /// Specifies a conflict with another module. + SUBMODULE_CONFLICT = 12, + + /// Specifies a header that is private to this submodule. + SUBMODULE_PRIVATE_HEADER = 13, + + /// Specifies a header that is part of the module but must be + /// textually included. + SUBMODULE_TEXTUAL_HEADER = 14, + + /// Specifies a header that is private to this submodule but + /// must be textually included. + SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15, + + /// Specifies some declarations with initializers that must be + /// emitted to initialize the module. + SUBMODULE_INITIALIZERS = 16, + + /// Specifies the name of the module that will eventually + /// re-export the entities in this module. + SUBMODULE_EXPORT_AS = 17, + }; + + /// Record types used within a comments block. + enum CommentRecordTypes { + COMMENTS_RAW_COMMENT = 0 + }; + + /// \defgroup ASTAST AST file AST constants + /// + /// The constants in this group describe various components of the + /// abstract syntax tree within an AST file. + /// + /// @{ + + /// Predefined type IDs. + /// + /// These type IDs correspond to predefined types in the AST + /// context, such as built-in types (int) and special place-holder + /// types (the \<overload> and \<dependent> type markers). Such + /// types are never actually serialized, since they will be built + /// by the AST context when it is created. + enum PredefinedTypeIDs { + /// The NULL type. + PREDEF_TYPE_NULL_ID = 0, + + /// The void type. + PREDEF_TYPE_VOID_ID = 1, + + /// The 'bool' or '_Bool' type. + PREDEF_TYPE_BOOL_ID = 2, + + /// The 'char' type, when it is unsigned. + PREDEF_TYPE_CHAR_U_ID = 3, + + /// The 'unsigned char' type. + PREDEF_TYPE_UCHAR_ID = 4, + + /// The 'unsigned short' type. + PREDEF_TYPE_USHORT_ID = 5, + + /// The 'unsigned int' type. + PREDEF_TYPE_UINT_ID = 6, + + /// The 'unsigned long' type. + PREDEF_TYPE_ULONG_ID = 7, + + /// The 'unsigned long long' type. + PREDEF_TYPE_ULONGLONG_ID = 8, + + /// The 'char' type, when it is signed. + PREDEF_TYPE_CHAR_S_ID = 9, + + /// The 'signed char' type. + PREDEF_TYPE_SCHAR_ID = 10, + + /// The C++ 'wchar_t' type. + PREDEF_TYPE_WCHAR_ID = 11, + + /// The (signed) 'short' type. + PREDEF_TYPE_SHORT_ID = 12, + + /// The (signed) 'int' type. + PREDEF_TYPE_INT_ID = 13, + + /// The (signed) 'long' type. + PREDEF_TYPE_LONG_ID = 14, + + /// The (signed) 'long long' type. + PREDEF_TYPE_LONGLONG_ID = 15, + + /// The 'float' type. + PREDEF_TYPE_FLOAT_ID = 16, + + /// The 'double' type. + PREDEF_TYPE_DOUBLE_ID = 17, + + /// The 'long double' type. + PREDEF_TYPE_LONGDOUBLE_ID = 18, + + /// The placeholder type for overloaded function sets. + PREDEF_TYPE_OVERLOAD_ID = 19, + + /// The placeholder type for dependent types. + PREDEF_TYPE_DEPENDENT_ID = 20, + + /// The '__uint128_t' type. + PREDEF_TYPE_UINT128_ID = 21, + + /// The '__int128_t' type. + PREDEF_TYPE_INT128_ID = 22, + + /// The type of 'nullptr'. + PREDEF_TYPE_NULLPTR_ID = 23, + + /// The C++ 'char16_t' type. + PREDEF_TYPE_CHAR16_ID = 24, + + /// The C++ 'char32_t' type. + PREDEF_TYPE_CHAR32_ID = 25, + + /// The ObjC 'id' type. + PREDEF_TYPE_OBJC_ID = 26, + + /// The ObjC 'Class' type. + PREDEF_TYPE_OBJC_CLASS = 27, + + /// The ObjC 'SEL' type. + PREDEF_TYPE_OBJC_SEL = 28, + + /// The 'unknown any' placeholder type. + PREDEF_TYPE_UNKNOWN_ANY = 29, + + /// The placeholder type for bound member functions. + PREDEF_TYPE_BOUND_MEMBER = 30, + + /// The "auto" deduction type. + PREDEF_TYPE_AUTO_DEDUCT = 31, + + /// The "auto &&" deduction type. + PREDEF_TYPE_AUTO_RREF_DEDUCT = 32, + + /// The OpenCL 'half' / ARM NEON __fp16 type. + PREDEF_TYPE_HALF_ID = 33, + + /// ARC's unbridged-cast placeholder type. + PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34, + + /// The pseudo-object placeholder type. + PREDEF_TYPE_PSEUDO_OBJECT = 35, + + /// The placeholder type for builtin functions. + PREDEF_TYPE_BUILTIN_FN = 36, + + /// OpenCL event type. + PREDEF_TYPE_EVENT_ID = 37, + + /// OpenCL clk event type. + PREDEF_TYPE_CLK_EVENT_ID = 38, + + /// OpenCL sampler type. + PREDEF_TYPE_SAMPLER_ID = 39, + + /// OpenCL queue type. + PREDEF_TYPE_QUEUE_ID = 40, + + /// OpenCL reserve_id type. + PREDEF_TYPE_RESERVE_ID_ID = 41, + + /// The placeholder type for OpenMP array section. + PREDEF_TYPE_OMP_ARRAY_SECTION = 42, + + /// The '__float128' type + PREDEF_TYPE_FLOAT128_ID = 43, + + /// The '_Float16' type + PREDEF_TYPE_FLOAT16_ID = 44, + + /// The C++ 'char8_t' type. + PREDEF_TYPE_CHAR8_ID = 45, + + /// \brief The 'short _Accum' type + PREDEF_TYPE_SHORT_ACCUM_ID = 46, + + /// \brief The '_Accum' type + PREDEF_TYPE_ACCUM_ID = 47, + + /// \brief The 'long _Accum' type + PREDEF_TYPE_LONG_ACCUM_ID = 48, + + /// \brief The 'unsigned short _Accum' type + PREDEF_TYPE_USHORT_ACCUM_ID = 49, + + /// \brief The 'unsigned _Accum' type + PREDEF_TYPE_UACCUM_ID = 50, + + /// \brief The 'unsigned long _Accum' type + PREDEF_TYPE_ULONG_ACCUM_ID = 51, + + /// \brief The 'short _Fract' type + PREDEF_TYPE_SHORT_FRACT_ID = 52, + + /// \brief The '_Fract' type + PREDEF_TYPE_FRACT_ID = 53, + + /// \brief The 'long _Fract' type + PREDEF_TYPE_LONG_FRACT_ID = 54, + + /// \brief The 'unsigned short _Fract' type + PREDEF_TYPE_USHORT_FRACT_ID = 55, + + /// \brief The 'unsigned _Fract' type + PREDEF_TYPE_UFRACT_ID = 56, + + /// \brief The 'unsigned long _Fract' type + PREDEF_TYPE_ULONG_FRACT_ID = 57, + + /// \brief The '_Sat short _Accum' type + PREDEF_TYPE_SAT_SHORT_ACCUM_ID = 58, + + /// \brief The '_Sat _Accum' type + PREDEF_TYPE_SAT_ACCUM_ID = 59, + + /// \brief The '_Sat long _Accum' type + PREDEF_TYPE_SAT_LONG_ACCUM_ID = 60, + + /// \brief The '_Sat unsigned short _Accum' type + PREDEF_TYPE_SAT_USHORT_ACCUM_ID = 61, + + /// \brief The '_Sat unsigned _Accum' type + PREDEF_TYPE_SAT_UACCUM_ID = 62, + + /// \brief The '_Sat unsigned long _Accum' type + PREDEF_TYPE_SAT_ULONG_ACCUM_ID = 63, + + /// \brief The '_Sat short _Fract' type + PREDEF_TYPE_SAT_SHORT_FRACT_ID = 64, + + /// \brief The '_Sat _Fract' type + PREDEF_TYPE_SAT_FRACT_ID = 65, + + /// \brief The '_Sat long _Fract' type + PREDEF_TYPE_SAT_LONG_FRACT_ID = 66, + + /// \brief The '_Sat unsigned short _Fract' type + PREDEF_TYPE_SAT_USHORT_FRACT_ID = 67, + + /// \brief The '_Sat unsigned _Fract' type + PREDEF_TYPE_SAT_UFRACT_ID = 68, + + /// \brief The '_Sat unsigned long _Fract' type + PREDEF_TYPE_SAT_ULONG_FRACT_ID = 69, + + /// OpenCL image types with auto numeration +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + PREDEF_TYPE_##Id##_ID, +#include "clang/Basic/OpenCLImageTypes.def" + /// \brief OpenCL extension types with auto numeration +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + PREDEF_TYPE_##Id##_ID, +#include "clang/Basic/OpenCLExtensionTypes.def" + }; + + /// The number of predefined type IDs that are reserved for + /// the PREDEF_TYPE_* constants. + /// + /// Type IDs for non-predefined types will start at + /// NUM_PREDEF_TYPE_IDs. + const unsigned NUM_PREDEF_TYPE_IDS = 200; + + /// Record codes for each kind of type. + /// + /// These constants describe the type records that can occur within a + /// block identified by DECLTYPES_BLOCK_ID in the AST file. Each + /// constant describes a record for a specific type class in the + /// AST. Note that DeclCode values share this code space. + enum TypeCode { + /// An ExtQualType record. + TYPE_EXT_QUAL = 1, + + /// A ComplexType record. + TYPE_COMPLEX = 3, + + /// A PointerType record. + TYPE_POINTER = 4, + + /// A BlockPointerType record. + TYPE_BLOCK_POINTER = 5, + + /// An LValueReferenceType record. + TYPE_LVALUE_REFERENCE = 6, + + /// An RValueReferenceType record. + TYPE_RVALUE_REFERENCE = 7, + + /// A MemberPointerType record. + TYPE_MEMBER_POINTER = 8, + + /// A ConstantArrayType record. + TYPE_CONSTANT_ARRAY = 9, + + /// An IncompleteArrayType record. + TYPE_INCOMPLETE_ARRAY = 10, + + /// A VariableArrayType record. + TYPE_VARIABLE_ARRAY = 11, + + /// A VectorType record. + TYPE_VECTOR = 12, + + /// An ExtVectorType record. + TYPE_EXT_VECTOR = 13, + + /// A FunctionNoProtoType record. + TYPE_FUNCTION_NO_PROTO = 14, + + /// A FunctionProtoType record. + TYPE_FUNCTION_PROTO = 15, + + /// A TypedefType record. + TYPE_TYPEDEF = 16, + + /// A TypeOfExprType record. + TYPE_TYPEOF_EXPR = 17, + + /// A TypeOfType record. + TYPE_TYPEOF = 18, + + /// A RecordType record. + TYPE_RECORD = 19, + + /// An EnumType record. + TYPE_ENUM = 20, + + /// An ObjCInterfaceType record. + TYPE_OBJC_INTERFACE = 21, + + /// An ObjCObjectPointerType record. + TYPE_OBJC_OBJECT_POINTER = 22, + + /// a DecltypeType record. + TYPE_DECLTYPE = 23, + + /// An ElaboratedType record. + TYPE_ELABORATED = 24, + + /// A SubstTemplateTypeParmType record. + TYPE_SUBST_TEMPLATE_TYPE_PARM = 25, + + /// An UnresolvedUsingType record. + TYPE_UNRESOLVED_USING = 26, + + /// An InjectedClassNameType record. + TYPE_INJECTED_CLASS_NAME = 27, + + /// An ObjCObjectType record. + TYPE_OBJC_OBJECT = 28, + + /// An TemplateTypeParmType record. + TYPE_TEMPLATE_TYPE_PARM = 29, + + /// An TemplateSpecializationType record. + TYPE_TEMPLATE_SPECIALIZATION = 30, + + /// A DependentNameType record. + TYPE_DEPENDENT_NAME = 31, + + /// A DependentTemplateSpecializationType record. + TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32, + + /// A DependentSizedArrayType record. + TYPE_DEPENDENT_SIZED_ARRAY = 33, + + /// A ParenType record. + TYPE_PAREN = 34, + + /// A PackExpansionType record. + TYPE_PACK_EXPANSION = 35, + + /// An AttributedType record. + TYPE_ATTRIBUTED = 36, + + /// A SubstTemplateTypeParmPackType record. + TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37, + + /// A AutoType record. + TYPE_AUTO = 38, + + /// A UnaryTransformType record. + TYPE_UNARY_TRANSFORM = 39, + + /// An AtomicType record. + TYPE_ATOMIC = 40, + + /// A DecayedType record. + TYPE_DECAYED = 41, + + /// An AdjustedType record. + TYPE_ADJUSTED = 42, + + /// A PipeType record. + TYPE_PIPE = 43, + + /// An ObjCTypeParamType record. + TYPE_OBJC_TYPE_PARAM = 44, + + /// A DeducedTemplateSpecializationType record. + TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45, + + /// A DependentSizedExtVectorType record. + TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46, + + /// A DependentAddressSpaceType record. + TYPE_DEPENDENT_ADDRESS_SPACE = 47, + + /// A dependentSizedVectorType record. + TYPE_DEPENDENT_SIZED_VECTOR = 48 + }; + + /// The type IDs for special types constructed by semantic + /// analysis. + /// + /// The constants in this enumeration are indices into the + /// SPECIAL_TYPES record. + enum SpecialTypeIDs { + /// CFConstantString type + SPECIAL_TYPE_CF_CONSTANT_STRING = 0, + + /// C FILE typedef type + SPECIAL_TYPE_FILE = 1, + + /// C jmp_buf typedef type + SPECIAL_TYPE_JMP_BUF = 2, + + /// C sigjmp_buf typedef type + SPECIAL_TYPE_SIGJMP_BUF = 3, + + /// Objective-C "id" redefinition type + SPECIAL_TYPE_OBJC_ID_REDEFINITION = 4, + + /// Objective-C "Class" redefinition type + SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 5, + + /// Objective-C "SEL" redefinition type + SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6, + + /// C ucontext_t typedef type + SPECIAL_TYPE_UCONTEXT_T = 7 + }; + + /// The number of special type IDs. + const unsigned NumSpecialTypeIDs = 8; + + /// Predefined declaration IDs. + /// + /// These declaration IDs correspond to predefined declarations in the AST + /// context, such as the NULL declaration ID. Such declarations are never + /// actually serialized, since they will be built by the AST context when + /// it is created. + enum PredefinedDeclIDs { + /// The NULL declaration. + PREDEF_DECL_NULL_ID = 0, + + /// The translation unit. + PREDEF_DECL_TRANSLATION_UNIT_ID = 1, + + /// The Objective-C 'id' type. + PREDEF_DECL_OBJC_ID_ID = 2, + + /// The Objective-C 'SEL' type. + PREDEF_DECL_OBJC_SEL_ID = 3, + + /// The Objective-C 'Class' type. + PREDEF_DECL_OBJC_CLASS_ID = 4, + + /// The Objective-C 'Protocol' type. + PREDEF_DECL_OBJC_PROTOCOL_ID = 5, + + /// The signed 128-bit integer type. + PREDEF_DECL_INT_128_ID = 6, + + /// The unsigned 128-bit integer type. + PREDEF_DECL_UNSIGNED_INT_128_ID = 7, + + /// The internal 'instancetype' typedef. + PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, + + /// The internal '__builtin_va_list' typedef. + PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, + + /// The internal '__va_list_tag' struct, if any. + PREDEF_DECL_VA_LIST_TAG = 10, + + /// The internal '__builtin_ms_va_list' typedef. + PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, + + /// The extern "C" context. + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12, + + /// The internal '__make_integer_seq' template. + PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13, + + /// The internal '__NSConstantString' typedef. + PREDEF_DECL_CF_CONSTANT_STRING_ID = 14, + + /// The internal '__NSConstantString' tag type. + PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 15, + + /// The internal '__type_pack_element' template. + PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 16, + }; + + /// The number of declaration IDs that are predefined. + /// + /// For more information about predefined declarations, see the + /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. + const unsigned int NUM_PREDEF_DECL_IDS = 17; + + /// Record of updates for a declaration that was modified after + /// being deserialized. This can occur within DECLTYPES_BLOCK_ID. + const unsigned int DECL_UPDATES = 49; + + /// Record code for a list of local redeclarations of a declaration. + /// This can occur within DECLTYPES_BLOCK_ID. + const unsigned int LOCAL_REDECLARATIONS = 50; + + /// Record codes for each kind of declaration. + /// + /// These constants describe the declaration records that can occur within + /// a declarations block (identified by DECLTYPES_BLOCK_ID). Each + /// constant describes a record for a specific declaration class + /// in the AST. Note that TypeCode values share this code space. + enum DeclCode { + /// A TypedefDecl record. + DECL_TYPEDEF = 51, + /// A TypeAliasDecl record. + + DECL_TYPEALIAS, + + /// An EnumDecl record. + DECL_ENUM, + + /// A RecordDecl record. + DECL_RECORD, + + /// An EnumConstantDecl record. + DECL_ENUM_CONSTANT, + + /// A FunctionDecl record. + DECL_FUNCTION, + + /// A ObjCMethodDecl record. + DECL_OBJC_METHOD, + + /// A ObjCInterfaceDecl record. + DECL_OBJC_INTERFACE, + + /// A ObjCProtocolDecl record. + DECL_OBJC_PROTOCOL, + + /// A ObjCIvarDecl record. + DECL_OBJC_IVAR, + + /// A ObjCAtDefsFieldDecl record. + DECL_OBJC_AT_DEFS_FIELD, + + /// A ObjCCategoryDecl record. + DECL_OBJC_CATEGORY, + + /// A ObjCCategoryImplDecl record. + DECL_OBJC_CATEGORY_IMPL, + + /// A ObjCImplementationDecl record. + DECL_OBJC_IMPLEMENTATION, + + /// A ObjCCompatibleAliasDecl record. + DECL_OBJC_COMPATIBLE_ALIAS, + + /// A ObjCPropertyDecl record. + DECL_OBJC_PROPERTY, + + /// A ObjCPropertyImplDecl record. + DECL_OBJC_PROPERTY_IMPL, + + /// A FieldDecl record. + DECL_FIELD, + + /// A MSPropertyDecl record. + DECL_MS_PROPERTY, + + /// A VarDecl record. + DECL_VAR, + + /// An ImplicitParamDecl record. + DECL_IMPLICIT_PARAM, + + /// A ParmVarDecl record. + DECL_PARM_VAR, + + /// A DecompositionDecl record. + DECL_DECOMPOSITION, + + /// A BindingDecl record. + DECL_BINDING, + + /// A FileScopeAsmDecl record. + DECL_FILE_SCOPE_ASM, + + /// A BlockDecl record. + DECL_BLOCK, + + /// A CapturedDecl record. + DECL_CAPTURED, + + /// A record that stores the set of declarations that are + /// lexically stored within a given DeclContext. + /// + /// The record itself is a blob that is an array of declaration IDs, + /// in the order in which those declarations were added to the + /// declaration context. This data is used when iterating over + /// the contents of a DeclContext, e.g., via + /// DeclContext::decls_begin() and DeclContext::decls_end(). + DECL_CONTEXT_LEXICAL, + + /// A record that stores the set of declarations that are + /// visible from a given DeclContext. + /// + /// The record itself stores a set of mappings, each of which + /// associates a declaration name with one or more declaration + /// IDs. This data is used when performing qualified name lookup + /// into a DeclContext via DeclContext::lookup. + DECL_CONTEXT_VISIBLE, + + /// A LabelDecl record. + DECL_LABEL, + + /// A NamespaceDecl record. + DECL_NAMESPACE, + + /// A NamespaceAliasDecl record. + DECL_NAMESPACE_ALIAS, + + /// A UsingDecl record. + DECL_USING, + + /// A UsingPackDecl record. + DECL_USING_PACK, + + /// A UsingShadowDecl record. + DECL_USING_SHADOW, + + /// A ConstructorUsingShadowDecl record. + DECL_CONSTRUCTOR_USING_SHADOW, + + /// A UsingDirecitveDecl record. + DECL_USING_DIRECTIVE, + + /// An UnresolvedUsingValueDecl record. + DECL_UNRESOLVED_USING_VALUE, + + /// An UnresolvedUsingTypenameDecl record. + DECL_UNRESOLVED_USING_TYPENAME, + + /// A LinkageSpecDecl record. + DECL_LINKAGE_SPEC, + + /// An ExportDecl record. + DECL_EXPORT, + + /// A CXXRecordDecl record. + DECL_CXX_RECORD, + + /// A CXXDeductionGuideDecl record. + DECL_CXX_DEDUCTION_GUIDE, + + /// A CXXMethodDecl record. + DECL_CXX_METHOD, + + /// A CXXConstructorDecl record. + DECL_CXX_CONSTRUCTOR, + + /// A CXXConstructorDecl record for an inherited constructor. + DECL_CXX_INHERITED_CONSTRUCTOR, + + /// A CXXDestructorDecl record. + DECL_CXX_DESTRUCTOR, + + /// A CXXConversionDecl record. + DECL_CXX_CONVERSION, + + /// An AccessSpecDecl record. + DECL_ACCESS_SPEC, + + /// A FriendDecl record. + DECL_FRIEND, + + /// A FriendTemplateDecl record. + DECL_FRIEND_TEMPLATE, + + /// A ClassTemplateDecl record. + DECL_CLASS_TEMPLATE, + + /// A ClassTemplateSpecializationDecl record. + DECL_CLASS_TEMPLATE_SPECIALIZATION, + + /// A ClassTemplatePartialSpecializationDecl record. + DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION, + + /// A VarTemplateDecl record. + DECL_VAR_TEMPLATE, + + /// A VarTemplateSpecializationDecl record. + DECL_VAR_TEMPLATE_SPECIALIZATION, + + /// A VarTemplatePartialSpecializationDecl record. + DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION, + + /// A FunctionTemplateDecl record. + DECL_FUNCTION_TEMPLATE, + + /// A TemplateTypeParmDecl record. + DECL_TEMPLATE_TYPE_PARM, + + /// A NonTypeTemplateParmDecl record. + DECL_NON_TYPE_TEMPLATE_PARM, + + /// A TemplateTemplateParmDecl record. + DECL_TEMPLATE_TEMPLATE_PARM, + + /// A TypeAliasTemplateDecl record. + DECL_TYPE_ALIAS_TEMPLATE, + + /// A StaticAssertDecl record. + DECL_STATIC_ASSERT, + + /// A record containing CXXBaseSpecifiers. + DECL_CXX_BASE_SPECIFIERS, + + /// A record containing CXXCtorInitializers. + DECL_CXX_CTOR_INITIALIZERS, + + /// A IndirectFieldDecl record. + DECL_INDIRECTFIELD, + + /// A NonTypeTemplateParmDecl record that stores an expanded + /// non-type template parameter pack. + DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK, + + /// A TemplateTemplateParmDecl record that stores an expanded + /// 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, + + /// An OMPThreadPrivateDecl record. + DECL_OMP_THREADPRIVATE, + + /// An OMPRequiresDecl record. + DECL_OMP_REQUIRES, + + /// An EmptyDecl record. + DECL_EMPTY, + + /// An ObjCTypeParamDecl record. + DECL_OBJC_TYPE_PARAM, + + /// An OMPCapturedExprDecl record. + DECL_OMP_CAPTUREDEXPR, + + /// A PragmaCommentDecl record. + DECL_PRAGMA_COMMENT, + + /// A PragmaDetectMismatchDecl record. + DECL_PRAGMA_DETECT_MISMATCH, + + /// An OMPDeclareMapperDecl record. + DECL_OMP_DECLARE_MAPPER, + + /// An OMPDeclareReductionDecl record. + DECL_OMP_DECLARE_REDUCTION, + + DECL_LAST = DECL_OMP_DECLARE_REDUCTION + }; + + /// Record codes for each kind of statement or expression. + /// + /// These constants describe the records that describe statements + /// or expressions. These records occur within type and declarations + /// block, so they begin with record values of 128. Each constant + /// describes a record for a specific statement or expression class in the + /// AST. + enum StmtCode { + /// A marker record that indicates that we are at the end + /// of an expression. + STMT_STOP = DECL_LAST + 1, + + /// A NULL expression. + STMT_NULL_PTR, + + /// A reference to a previously [de]serialized Stmt record. + STMT_REF_PTR, + + /// A NullStmt record. + STMT_NULL, + + /// A CompoundStmt record. + STMT_COMPOUND, + + /// A CaseStmt record. + STMT_CASE, + + /// A DefaultStmt record. + STMT_DEFAULT, + + /// A LabelStmt record. + STMT_LABEL, + + /// An AttributedStmt record. + STMT_ATTRIBUTED, + + /// An IfStmt record. + STMT_IF, + + /// A SwitchStmt record. + STMT_SWITCH, + + /// A WhileStmt record. + STMT_WHILE, + + /// A DoStmt record. + STMT_DO, + + /// A ForStmt record. + STMT_FOR, + + /// A GotoStmt record. + STMT_GOTO, + + /// An IndirectGotoStmt record. + STMT_INDIRECT_GOTO, + + /// A ContinueStmt record. + STMT_CONTINUE, + + /// A BreakStmt record. + STMT_BREAK, + + /// A ReturnStmt record. + STMT_RETURN, + + /// A DeclStmt record. + STMT_DECL, + + /// A CapturedStmt record. + STMT_CAPTURED, + + /// A GCC-style AsmStmt record. + STMT_GCCASM, + + /// A MS-style AsmStmt record. + STMT_MSASM, + + /// A constant expression context. + EXPR_CONSTANT, + + /// A PredefinedExpr record. + EXPR_PREDEFINED, + + /// A DeclRefExpr record. + EXPR_DECL_REF, + + /// An IntegerLiteral record. + EXPR_INTEGER_LITERAL, + + /// A FloatingLiteral record. + EXPR_FLOATING_LITERAL, + + /// An ImaginaryLiteral record. + EXPR_IMAGINARY_LITERAL, + + /// A StringLiteral record. + EXPR_STRING_LITERAL, + + /// A CharacterLiteral record. + EXPR_CHARACTER_LITERAL, + + /// A ParenExpr record. + EXPR_PAREN, + + /// A ParenListExpr record. + EXPR_PAREN_LIST, + + /// A UnaryOperator record. + EXPR_UNARY_OPERATOR, + + /// An OffsetOfExpr record. + EXPR_OFFSETOF, + + /// A SizefAlignOfExpr record. + EXPR_SIZEOF_ALIGN_OF, + + /// An ArraySubscriptExpr record. + EXPR_ARRAY_SUBSCRIPT, + + /// A CallExpr record. + EXPR_CALL, + + /// A MemberExpr record. + EXPR_MEMBER, + + /// A BinaryOperator record. + EXPR_BINARY_OPERATOR, + + /// A CompoundAssignOperator record. + EXPR_COMPOUND_ASSIGN_OPERATOR, + + /// A ConditionOperator record. + EXPR_CONDITIONAL_OPERATOR, + + /// An ImplicitCastExpr record. + EXPR_IMPLICIT_CAST, + + /// A CStyleCastExpr record. + EXPR_CSTYLE_CAST, + + /// A CompoundLiteralExpr record. + EXPR_COMPOUND_LITERAL, + + /// An ExtVectorElementExpr record. + EXPR_EXT_VECTOR_ELEMENT, + + /// An InitListExpr record. + EXPR_INIT_LIST, + + /// A DesignatedInitExpr record. + EXPR_DESIGNATED_INIT, + + /// A DesignatedInitUpdateExpr record. + EXPR_DESIGNATED_INIT_UPDATE, + + /// An NoInitExpr record. + EXPR_NO_INIT, + + /// An ArrayInitLoopExpr record. + EXPR_ARRAY_INIT_LOOP, + + /// An ArrayInitIndexExpr record. + EXPR_ARRAY_INIT_INDEX, + + /// An ImplicitValueInitExpr record. + EXPR_IMPLICIT_VALUE_INIT, + + /// A VAArgExpr record. + EXPR_VA_ARG, + + /// An AddrLabelExpr record. + EXPR_ADDR_LABEL, + + /// A StmtExpr record. + EXPR_STMT, + + /// A ChooseExpr record. + EXPR_CHOOSE, + + /// A GNUNullExpr record. + EXPR_GNU_NULL, + + /// A ShuffleVectorExpr record. + EXPR_SHUFFLE_VECTOR, + + /// A ConvertVectorExpr record. + EXPR_CONVERT_VECTOR, + + /// BlockExpr + EXPR_BLOCK, + + /// A GenericSelectionExpr record. + EXPR_GENERIC_SELECTION, + + /// A PseudoObjectExpr record. + EXPR_PSEUDO_OBJECT, + + /// An AtomicExpr record. + EXPR_ATOMIC, + + // Objective-C + + /// An ObjCStringLiteral record. + EXPR_OBJC_STRING_LITERAL, + + EXPR_OBJC_BOXED_EXPRESSION, + EXPR_OBJC_ARRAY_LITERAL, + EXPR_OBJC_DICTIONARY_LITERAL, + + /// An ObjCEncodeExpr record. + EXPR_OBJC_ENCODE, + + /// An ObjCSelectorExpr record. + EXPR_OBJC_SELECTOR_EXPR, + + /// An ObjCProtocolExpr record. + EXPR_OBJC_PROTOCOL_EXPR, + + /// An ObjCIvarRefExpr record. + EXPR_OBJC_IVAR_REF_EXPR, + + /// An ObjCPropertyRefExpr record. + EXPR_OBJC_PROPERTY_REF_EXPR, + + /// An ObjCSubscriptRefExpr record. + EXPR_OBJC_SUBSCRIPT_REF_EXPR, + + /// UNUSED + EXPR_OBJC_KVC_REF_EXPR, + + /// An ObjCMessageExpr record. + EXPR_OBJC_MESSAGE_EXPR, + + /// An ObjCIsa Expr record. + EXPR_OBJC_ISA, + + /// An ObjCIndirectCopyRestoreExpr record. + EXPR_OBJC_INDIRECT_COPY_RESTORE, + + /// An ObjCForCollectionStmt record. + STMT_OBJC_FOR_COLLECTION, + + /// An ObjCAtCatchStmt record. + STMT_OBJC_CATCH, + + /// An ObjCAtFinallyStmt record. + STMT_OBJC_FINALLY, + + /// An ObjCAtTryStmt record. + STMT_OBJC_AT_TRY, + + /// An ObjCAtSynchronizedStmt record. + STMT_OBJC_AT_SYNCHRONIZED, + + /// An ObjCAtThrowStmt record. + STMT_OBJC_AT_THROW, + + /// An ObjCAutoreleasePoolStmt record. + STMT_OBJC_AUTORELEASE_POOL, + + /// An ObjCBoolLiteralExpr record. + EXPR_OBJC_BOOL_LITERAL, + + /// An ObjCAvailabilityCheckExpr record. + EXPR_OBJC_AVAILABILITY_CHECK, + + // C++ + + /// A CXXCatchStmt record. + STMT_CXX_CATCH, + + /// A CXXTryStmt record. + STMT_CXX_TRY, + /// A CXXForRangeStmt record. + + STMT_CXX_FOR_RANGE, + + /// A CXXOperatorCallExpr record. + EXPR_CXX_OPERATOR_CALL, + + /// A CXXMemberCallExpr record. + EXPR_CXX_MEMBER_CALL, + + /// A CXXConstructExpr record. + EXPR_CXX_CONSTRUCT, + + /// A CXXInheritedCtorInitExpr record. + EXPR_CXX_INHERITED_CTOR_INIT, + + /// A CXXTemporaryObjectExpr record. + EXPR_CXX_TEMPORARY_OBJECT, + + /// A CXXStaticCastExpr record. + EXPR_CXX_STATIC_CAST, + + /// A CXXDynamicCastExpr record. + EXPR_CXX_DYNAMIC_CAST, + + /// A CXXReinterpretCastExpr record. + EXPR_CXX_REINTERPRET_CAST, + + /// A CXXConstCastExpr record. + EXPR_CXX_CONST_CAST, + + /// A CXXFunctionalCastExpr record. + EXPR_CXX_FUNCTIONAL_CAST, + + /// A UserDefinedLiteral record. + EXPR_USER_DEFINED_LITERAL, + + /// A CXXStdInitializerListExpr record. + EXPR_CXX_STD_INITIALIZER_LIST, + + /// A CXXBoolLiteralExpr record. + EXPR_CXX_BOOL_LITERAL, + + EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr + EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). + EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). + EXPR_CXX_THIS, // CXXThisExpr + EXPR_CXX_THROW, // CXXThrowExpr + EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr + EXPR_CXX_DEFAULT_INIT, // CXXDefaultInitExpr + EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr + + EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr + EXPR_CXX_NEW, // CXXNewExpr + EXPR_CXX_DELETE, // CXXDeleteExpr + EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr + + EXPR_EXPR_WITH_CLEANUPS, // ExprWithCleanups + + EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr + EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr + EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr + EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr + EXPR_CXX_UNRESOLVED_LOOKUP, // UnresolvedLookupExpr + + EXPR_CXX_EXPRESSION_TRAIT, // ExpressionTraitExpr + EXPR_CXX_NOEXCEPT, // CXXNoexceptExpr + + EXPR_OPAQUE_VALUE, // OpaqueValueExpr + EXPR_BINARY_CONDITIONAL_OPERATOR, // BinaryConditionalOperator + EXPR_TYPE_TRAIT, // TypeTraitExpr + EXPR_ARRAY_TYPE_TRAIT, // ArrayTypeTraitIntExpr + + EXPR_PACK_EXPANSION, // PackExpansionExpr + EXPR_SIZEOF_PACK, // SizeOfPackExpr + EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr + EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr + EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr + EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr + EXPR_CXX_FOLD, // CXXFoldExpr + + // CUDA + EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr + + // OpenCL + EXPR_ASTYPE, // AsTypeExpr + + // Microsoft + EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr + EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR, // MSPropertySubscriptExpr + EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). + EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). + STMT_SEH_LEAVE, // SEHLeaveStmt + STMT_SEH_EXCEPT, // SEHExceptStmt + STMT_SEH_FINALLY, // SEHFinallyStmt + STMT_SEH_TRY, // SEHTryStmt + + // OpenMP directives + STMT_OMP_PARALLEL_DIRECTIVE, + STMT_OMP_SIMD_DIRECTIVE, + STMT_OMP_FOR_DIRECTIVE, + STMT_OMP_FOR_SIMD_DIRECTIVE, + STMT_OMP_SECTIONS_DIRECTIVE, + STMT_OMP_SECTION_DIRECTIVE, + STMT_OMP_SINGLE_DIRECTIVE, + STMT_OMP_MASTER_DIRECTIVE, + STMT_OMP_CRITICAL_DIRECTIVE, + STMT_OMP_PARALLEL_FOR_DIRECTIVE, + STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE, + STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE, + STMT_OMP_TASK_DIRECTIVE, + STMT_OMP_TASKYIELD_DIRECTIVE, + STMT_OMP_BARRIER_DIRECTIVE, + STMT_OMP_TASKWAIT_DIRECTIVE, + STMT_OMP_FLUSH_DIRECTIVE, + STMT_OMP_ORDERED_DIRECTIVE, + STMT_OMP_ATOMIC_DIRECTIVE, + STMT_OMP_TARGET_DIRECTIVE, + STMT_OMP_TARGET_DATA_DIRECTIVE, + STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE, + STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE, + STMT_OMP_TEAMS_DIRECTIVE, + STMT_OMP_TASKGROUP_DIRECTIVE, + STMT_OMP_CANCELLATION_POINT_DIRECTIVE, + STMT_OMP_CANCEL_DIRECTIVE, + STMT_OMP_TASKLOOP_DIRECTIVE, + STMT_OMP_TASKLOOP_SIMD_DIRECTIVE, + STMT_OMP_DISTRIBUTE_DIRECTIVE, + STMT_OMP_TARGET_UPDATE_DIRECTIVE, + STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, + STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, + STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE, + STMT_OMP_TARGET_SIMD_DIRECTIVE, + STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE, + STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, + STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, + STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, + STMT_OMP_TARGET_TEAMS_DIRECTIVE, + STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE, + STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, + STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, + STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, + EXPR_OMP_ARRAY_SECTION, + + // ARC + EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr + + STMT_MS_DEPENDENT_EXISTS, // MSDependentExistsStmt + EXPR_LAMBDA, // LambdaExpr + STMT_COROUTINE_BODY, + STMT_CORETURN, + EXPR_COAWAIT, + EXPR_COYIELD, + EXPR_DEPENDENT_COAWAIT, + }; + + /// The kinds of designators that can occur in a + /// DesignatedInitExpr. + enum DesignatorTypes { + /// Field designator where only the field name is known. + DESIG_FIELD_NAME = 0, + + /// Field designator where the field has been resolved to + /// a declaration. + DESIG_FIELD_DECL = 1, + + /// Array designator. + DESIG_ARRAY = 2, + + /// GNU array range designator. + DESIG_ARRAY_RANGE = 3 + }; + + /// The different kinds of data that can occur in a + /// CtorInitializer. + enum CtorInitializerType { + CTOR_INITIALIZER_BASE, + CTOR_INITIALIZER_DELEGATING, + CTOR_INITIALIZER_MEMBER, + CTOR_INITIALIZER_INDIRECT_MEMBER + }; + + /// Describes the redeclarations of a declaration. + struct LocalRedeclarationsInfo { + // The ID of the first declaration + DeclID FirstID; + + // Offset into the array of redeclaration chains. + unsigned Offset; + + friend bool operator<(const LocalRedeclarationsInfo &X, + const LocalRedeclarationsInfo &Y) { + return X.FirstID < Y.FirstID; + } + + friend bool operator>(const LocalRedeclarationsInfo &X, + const LocalRedeclarationsInfo &Y) { + return X.FirstID > Y.FirstID; + } + + friend bool operator<=(const LocalRedeclarationsInfo &X, + const LocalRedeclarationsInfo &Y) { + return X.FirstID <= Y.FirstID; + } + + friend bool operator>=(const LocalRedeclarationsInfo &X, + const LocalRedeclarationsInfo &Y) { + return X.FirstID >= Y.FirstID; + } + }; + + /// Describes the categories of an Objective-C class. + struct ObjCCategoriesInfo { + // The ID of the definition + DeclID DefinitionID; + + // Offset into the array of category lists. + unsigned Offset; + + friend bool operator<(const ObjCCategoriesInfo &X, + const ObjCCategoriesInfo &Y) { + return X.DefinitionID < Y.DefinitionID; + } + + friend bool operator>(const ObjCCategoriesInfo &X, + const ObjCCategoriesInfo &Y) { + return X.DefinitionID > Y.DefinitionID; + } + + friend bool operator<=(const ObjCCategoriesInfo &X, + const ObjCCategoriesInfo &Y) { + return X.DefinitionID <= Y.DefinitionID; + } + + friend bool operator>=(const ObjCCategoriesInfo &X, + const ObjCCategoriesInfo &Y) { + return X.DefinitionID >= Y.DefinitionID; + } + }; + + /// A key used when looking up entities by \ref DeclarationName. + /// + /// Different \ref DeclarationNames are mapped to different keys, but the + /// same key can occasionally represent multiple names (for names that + /// contain types, in particular). + class DeclarationNameKey { + using NameKind = unsigned; + + NameKind Kind = 0; + uint64_t Data = 0; + + public: + DeclarationNameKey() = default; + DeclarationNameKey(DeclarationName Name); + DeclarationNameKey(NameKind Kind, uint64_t Data) + : Kind(Kind), Data(Data) {} + + NameKind getKind() const { return Kind; } + + IdentifierInfo *getIdentifier() const { + assert(Kind == DeclarationName::Identifier || + Kind == DeclarationName::CXXLiteralOperatorName || + Kind == DeclarationName::CXXDeductionGuideName); + return (IdentifierInfo *)Data; + } + + Selector getSelector() const { + assert(Kind == DeclarationName::ObjCZeroArgSelector || + Kind == DeclarationName::ObjCOneArgSelector || + Kind == DeclarationName::ObjCMultiArgSelector); + return Selector(Data); + } + + OverloadedOperatorKind getOperatorKind() const { + assert(Kind == DeclarationName::CXXOperatorName); + return (OverloadedOperatorKind)Data; + } + + /// Compute a fingerprint of this key for use in on-disk hash table. + unsigned getHash() const; + + friend bool operator==(const DeclarationNameKey &A, + const DeclarationNameKey &B) { + return A.Kind == B.Kind && A.Data == B.Data; + } + }; + + /// @} + +} // namespace serialization +} // namespace clang + +namespace llvm { + + template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> { + static clang::serialization::DeclarationNameKey getEmptyKey() { + return clang::serialization::DeclarationNameKey(-1, 1); + } + + static clang::serialization::DeclarationNameKey getTombstoneKey() { + return clang::serialization::DeclarationNameKey(-1, 2); + } + + static unsigned + getHashValue(const clang::serialization::DeclarationNameKey &Key) { + return Key.getHash(); + } + + static bool isEqual(const clang::serialization::DeclarationNameKey &L, + const clang::serialization::DeclarationNameKey &R) { + return L == R; + } + }; + +} // namespace llvm + +#endif // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H diff --git a/clang-r353983/include/clang/Serialization/ASTDeserializationListener.h b/clang-r353983/include/clang/Serialization/ASTDeserializationListener.h new file mode 100644 index 00000000..f3a01a4b --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ASTDeserializationListener.h @@ -0,0 +1,61 @@ +//===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTDeserializationListener class, which is notified +// by the ASTReader whenever a type or declaration is deserialized. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H +#define LLVM_CLANG_SERIALIZATION_ASTDESERIALIZATIONLISTENER_H + +#include "clang/Basic/IdentifierTable.h" +#include "clang/Serialization/ASTBitCodes.h" + +namespace clang { + +class Decl; +class ASTReader; +class QualType; +class MacroDefinitionRecord; +class MacroInfo; +class Module; +class SourceLocation; + +class ASTDeserializationListener { +public: + virtual ~ASTDeserializationListener(); + + /// The ASTReader was initialized. + virtual void ReaderInitialized(ASTReader *Reader) { } + + /// An identifier was deserialized from the AST file. + virtual void IdentifierRead(serialization::IdentID ID, + IdentifierInfo *II) { } + /// A macro was read from the AST file. + virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { } + /// A type was deserialized from the AST file. The ID here has the + /// qualifier bits already removed, and T is guaranteed to be locally + /// unqualified. + virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } + /// A decl was deserialized from the AST file. + virtual void DeclRead(serialization::DeclID ID, const Decl *D) { } + /// A selector was read from the AST file. + virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} + /// A macro definition was read from the AST file. + virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, + MacroDefinitionRecord *MD) {} + /// A module definition was read from the AST file. + virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {} + /// A module import was read from the AST file. + virtual void ModuleImportRead(serialization::SubmoduleID ID, + SourceLocation ImportLoc) {} +}; +} + +#endif diff --git a/clang-r353983/include/clang/Serialization/ASTReader.h b/clang-r353983/include/clang/Serialization/ASTReader.h new file mode 100644 index 00000000..798adeea --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ASTReader.h @@ -0,0 +1,2698 @@ +//===- ASTReader.h - AST File Reader ----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTReader class, which reads AST files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H +#define LLVM_CLANG_SERIALIZATION_ASTREADER_H + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclarationName.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/Module.h" +#include "clang/Basic/OpenCLOptions.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Version.h" +#include "clang/Lex/ExternalPreprocessorSource.h" +#include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/PreprocessingRecord.h" +#include "clang/Lex/Token.h" +#include "clang/Sema/ExternalSemaSource.h" +#include "clang/Sema/IdentifierResolver.h" +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/Module.h" +#include "clang/Serialization/ModuleFileExtension.h" +#include "clang/Serialization/ModuleManager.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.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/STLExtras.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/VersionTuple.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <ctime> +#include <deque> +#include <memory> +#include <set> +#include <string> +#include <utility> +#include <vector> + +namespace clang { + +class ASTConsumer; +class ASTContext; +class ASTDeserializationListener; +class ASTReader; +class ASTRecordReader; +class CXXTemporary; +class Decl; +class DeclaratorDecl; +class DeclContext; +class EnumDecl; +class Expr; +class FieldDecl; +class FileEntry; +class FileManager; +class FileSystemOptions; +class FunctionDecl; +class GlobalModuleIndex; +struct HeaderFileInfo; +class HeaderSearchOptions; +class LangOptions; +class LazyASTUnresolvedSet; +class MacroInfo; +class MemoryBufferCache; +class NamedDecl; +class NamespaceDecl; +class ObjCCategoryDecl; +class ObjCInterfaceDecl; +class PCHContainerReader; +class Preprocessor; +class PreprocessorOptions; +struct QualifierInfo; +class Sema; +class SourceManager; +class Stmt; +class SwitchCase; +class TargetOptions; +class TemplateParameterList; +class TypedefNameDecl; +class TypeSourceInfo; +class ValueDecl; +class VarDecl; + +/// Abstract interface for callback invocations by the ASTReader. +/// +/// While reading an AST file, the ASTReader will call the methods of the +/// listener to pass on specific information. Some of the listener methods can +/// return true to indicate to the ASTReader that the information (and +/// consequently the AST file) is invalid. +class ASTReaderListener { +public: + virtual ~ASTReaderListener(); + + /// Receives the full Clang version information. + /// + /// \returns true to indicate that the version is invalid. Subclasses should + /// generally defer to this implementation. + virtual bool ReadFullVersionInformation(StringRef FullVersion) { + return FullVersion != getClangFullRepositoryVersion(); + } + + virtual void ReadModuleName(StringRef ModuleName) {} + virtual void ReadModuleMapFile(StringRef ModuleMapPath) {} + + /// Receives the language options. + /// + /// \returns true to indicate the options are invalid or false otherwise. + virtual bool ReadLanguageOptions(const LangOptions &LangOpts, + bool Complain, + bool AllowCompatibleDifferences) { + return false; + } + + /// Receives the target options. + /// + /// \returns true to indicate the target options are invalid, or false + /// otherwise. + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) { + return false; + } + + /// Receives the diagnostic options. + /// + /// \returns true to indicate the diagnostic options are invalid, or false + /// otherwise. + virtual bool + ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, + bool Complain) { + return false; + } + + /// Receives the file system options. + /// + /// \returns true to indicate the file system options are invalid, or false + /// otherwise. + virtual bool ReadFileSystemOptions(const FileSystemOptions &FSOpts, + bool Complain) { + return false; + } + + /// Receives the header search options. + /// + /// \returns true to indicate the header search options are invalid, or false + /// otherwise. + virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, + bool Complain) { + return false; + } + + /// Receives the preprocessor options. + /// + /// \param SuggestedPredefines Can be filled in with the set of predefines + /// that are suggested by the preprocessor options. Typically only used when + /// loading a precompiled header. + /// + /// \returns true to indicate the preprocessor options are invalid, or false + /// otherwise. + virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines) { + return false; + } + + /// Receives __COUNTER__ value. + virtual void ReadCounter(const serialization::ModuleFile &M, + unsigned Value) {} + + /// This is called for each AST file loaded. + virtual void visitModuleFile(StringRef Filename, + serialization::ModuleKind Kind) {} + + /// Returns true if this \c ASTReaderListener wants to receive the + /// input files of the AST file via \c visitInputFile, false otherwise. + virtual bool needsInputFileVisitation() { return false; } + + /// Returns true if this \c ASTReaderListener wants to receive the + /// system input files of the AST file via \c visitInputFile, false otherwise. + virtual bool needsSystemInputFileVisitation() { return false; } + + /// if \c needsInputFileVisitation returns true, this is called for + /// each non-system input file of the AST File. If + /// \c needsSystemInputFileVisitation is true, then it is called for all + /// system input files as well. + /// + /// \returns true to continue receiving the next input file, false to stop. + virtual bool visitInputFile(StringRef Filename, bool isSystem, + bool isOverridden, bool isExplicitModule) { + return true; + } + + /// Returns true if this \c ASTReaderListener wants to receive the + /// imports of the AST file via \c visitImport, false otherwise. + virtual bool needsImportVisitation() const { return false; } + + /// If needsImportVisitation returns \c true, this is called for each + /// AST file imported by this AST file. + virtual void visitImport(StringRef ModuleName, StringRef Filename) {} + + /// Indicates that a particular module file extension has been read. + virtual void readModuleFileExtension( + const ModuleFileExtensionMetadata &Metadata) {} +}; + +/// Simple wrapper class for chaining listeners. +class ChainedASTReaderListener : public ASTReaderListener { + std::unique_ptr<ASTReaderListener> First; + std::unique_ptr<ASTReaderListener> Second; + +public: + /// Takes ownership of \p First and \p Second. + ChainedASTReaderListener(std::unique_ptr<ASTReaderListener> First, + std::unique_ptr<ASTReaderListener> Second) + : First(std::move(First)), Second(std::move(Second)) {} + + std::unique_ptr<ASTReaderListener> takeFirst() { return std::move(First); } + std::unique_ptr<ASTReaderListener> takeSecond() { return std::move(Second); } + + bool ReadFullVersionInformation(StringRef FullVersion) override; + void ReadModuleName(StringRef ModuleName) override; + void ReadModuleMapFile(StringRef ModuleMapPath) override; + bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, + bool AllowCompatibleDifferences) override; + bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) override; + bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, + bool Complain) override; + bool ReadFileSystemOptions(const FileSystemOptions &FSOpts, + bool Complain) override; + + bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, + bool Complain) override; + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, + bool Complain, + std::string &SuggestedPredefines) override; + + void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override; + bool needsInputFileVisitation() override; + bool needsSystemInputFileVisitation() override; + void visitModuleFile(StringRef Filename, + serialization::ModuleKind Kind) override; + bool visitInputFile(StringRef Filename, bool isSystem, + bool isOverridden, bool isExplicitModule) override; + void readModuleFileExtension( + const ModuleFileExtensionMetadata &Metadata) override; +}; + +/// ASTReaderListener implementation to validate the information of +/// the PCH file against an initialized Preprocessor. +class PCHValidator : public ASTReaderListener { + Preprocessor &PP; + ASTReader &Reader; + +public: + PCHValidator(Preprocessor &PP, ASTReader &Reader) + : PP(PP), Reader(Reader) {} + + bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, + bool AllowCompatibleDifferences) override; + bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) override; + bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, + bool Complain) override; + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, 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 +/// ASTReader which is required to use a pch file. This is the replacement +/// of PCHValidator or SimplePCHValidator when using a pch file without +/// validating it. +class SimpleASTReaderListener : public ASTReaderListener { + Preprocessor &PP; + +public: + SimpleASTReaderListener(Preprocessor &PP) : PP(PP) {} + + bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, + std::string &SuggestedPredefines) override; +}; + +namespace serialization { + +class ReadMethodPoolVisitor; + +namespace reader { + +class ASTIdentifierLookupTrait; + +/// The on-disk hash table(s) used for DeclContext name lookup. +struct DeclContextLookupTable; + +} // namespace reader + +} // namespace serialization + +/// Reads an AST files chain containing the contents of a translation +/// unit. +/// +/// The ASTReader class reads bitstreams (produced by the ASTWriter +/// class) containing the serialized representation of a given +/// abstract syntax tree and its supporting data structures. An +/// instance of the ASTReader can be attached to an ASTContext object, +/// which will provide access to the contents of the AST files. +/// +/// The AST reader provides lazy de-serialization of declarations, as +/// required when traversing the AST. Only those AST nodes that are +/// actually required will be de-serialized. +class ASTReader + : public ExternalPreprocessorSource, + public ExternalPreprocessingRecordSource, + public ExternalHeaderFileInfoSource, + public ExternalSemaSource, + public IdentifierInfoLookup, + public ExternalSLocEntrySource +{ +public: + /// Types of AST files. + friend class ASTDeclReader; + friend class ASTIdentifierIterator; + friend class ASTRecordReader; + friend class ASTStmtReader; + friend class ASTUnit; // ASTUnit needs to remap source locations. + friend class ASTWriter; + friend class PCHValidator; + friend class serialization::reader::ASTIdentifierLookupTrait; + friend class serialization::ReadMethodPoolVisitor; + friend class TypeLocReader; + + using RecordData = SmallVector<uint64_t, 64>; + using RecordDataImpl = SmallVectorImpl<uint64_t>; + + /// The result of reading the control block of an AST file, which + /// can fail for various reasons. + enum ASTReadResult { + /// The control block was read successfully. Aside from failures, + /// the AST file is safe to read into the current context. + Success, + + /// The AST file itself appears corrupted. + Failure, + + /// The AST file was missing. + Missing, + + /// The AST file is out-of-date relative to its input files, + /// and needs to be regenerated. + OutOfDate, + + /// The AST file was written by a different version of Clang. + VersionMismatch, + + /// The AST file was writtten with a different language/target + /// configuration. + ConfigurationMismatch, + + /// The AST file has errors. + HadErrors + }; + + using ModuleFile = serialization::ModuleFile; + using ModuleKind = serialization::ModuleKind; + using ModuleManager = serialization::ModuleManager; + using ModuleIterator = ModuleManager::ModuleIterator; + using ModuleConstIterator = ModuleManager::ModuleConstIterator; + using ModuleReverseIterator = ModuleManager::ModuleReverseIterator; + +private: + /// The receiver of some callbacks invoked by ASTReader. + std::unique_ptr<ASTReaderListener> Listener; + + /// The receiver of deserialization events. + ASTDeserializationListener *DeserializationListener = nullptr; + + bool OwnsDeserializationListener = false; + + SourceManager &SourceMgr; + FileManager &FileMgr; + const PCHContainerReader &PCHContainerRdr; + DiagnosticsEngine &Diags; + + /// The semantic analysis object that will be processing the + /// AST files and the translation unit that uses it. + Sema *SemaObj = nullptr; + + /// The preprocessor that will be loading the source file. + Preprocessor &PP; + + /// The AST context into which we'll read the AST files. + ASTContext *ContextObj = nullptr; + + /// The AST consumer. + ASTConsumer *Consumer = nullptr; + + /// The module manager which manages modules and their dependencies + ModuleManager ModuleMgr; + + /// The cache that manages memory buffers for PCM files. + MemoryBufferCache &PCMCache; + + /// A dummy identifier resolver used to merge TU-scope declarations in + /// C, for the cases where we don't have a Sema object to provide a real + /// identifier resolver. + IdentifierResolver DummyIdResolver; + + /// A mapping from extension block names to module file extensions. + llvm::StringMap<std::shared_ptr<ModuleFileExtension>> ModuleFileExtensions; + + /// A timer used to track the time spent deserializing. + std::unique_ptr<llvm::Timer> ReadTimer; + + /// The location where the module file will be considered as + /// imported from. For non-module AST types it should be invalid. + SourceLocation CurrentImportLoc; + + /// The global module index, if loaded. + std::unique_ptr<GlobalModuleIndex> GlobalIndex; + + /// A map of global bit offsets to the module that stores entities + /// at those bit offsets. + ContinuousRangeMap<uint64_t, ModuleFile*, 4> GlobalBitOffsetsMap; + + /// A map of negated SLocEntryIDs to the modules containing them. + ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap; + + using GlobalSLocOffsetMapType = + ContinuousRangeMap<unsigned, ModuleFile *, 64>; + + /// A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset) + /// SourceLocation offsets to the modules containing them. + GlobalSLocOffsetMapType GlobalSLocOffsetMap; + + /// Types that have already been loaded from the chain. + /// + /// 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; + + using GlobalTypeMapType = + ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>; + + /// Mapping from global type IDs to the module in which the + /// type resides along with the offset that should be added to the + /// global type ID to produce a local ID. + GlobalTypeMapType GlobalTypeMap; + + /// Declarations that have already been loaded from the chain. + /// + /// When the pointer at index I is non-NULL, the declaration with ID + /// = I + 1 has already been loaded. + std::vector<Decl *> DeclsLoaded; + + using GlobalDeclMapType = + ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>; + + /// Mapping from global declaration IDs to the module in which the + /// declaration resides. + GlobalDeclMapType GlobalDeclMap; + + using FileOffset = std::pair<ModuleFile *, uint64_t>; + using FileOffsetsTy = SmallVector<FileOffset, 2>; + using DeclUpdateOffsetsMap = + llvm::DenseMap<serialization::DeclID, FileOffsetsTy>; + + /// Declarations that have modifications residing in a later file + /// in the chain. + DeclUpdateOffsetsMap DeclUpdateOffsets; + + struct PendingUpdateRecord { + Decl *D; + serialization::GlobalDeclID ID; + + // Whether the declaration was just deserialized. + bool JustLoaded; + + PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D, + bool JustLoaded) + : D(D), ID(ID), JustLoaded(JustLoaded) {} + }; + + /// Declaration updates for already-loaded declarations that we need + /// to apply once we finish processing an import. + llvm::SmallVector<PendingUpdateRecord, 16> PendingUpdateRecords; + + enum class PendingFakeDefinitionKind { NotFake, Fake, FakeLoaded }; + + /// The DefinitionData pointers that we faked up for class definitions + /// that we needed but hadn't loaded yet. + llvm::DenseMap<void *, PendingFakeDefinitionKind> PendingFakeDefinitionData; + + /// Exception specification updates that have been loaded but not yet + /// propagated across the relevant redeclaration chain. The map key is the + /// canonical declaration (used only for deduplication) and the value is a + /// declaration that has an exception specification. + llvm::SmallMapVector<Decl *, FunctionDecl *, 4> PendingExceptionSpecUpdates; + + /// Deduced return type updates that have been loaded but not yet propagated + /// across the relevant redeclaration chain. The map key is the canonical + /// declaration and the value is the deduced return type. + llvm::SmallMapVector<FunctionDecl *, QualType, 4> PendingDeducedTypeUpdates; + + /// Declarations that have been imported and have typedef names for + /// linkage purposes. + llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *> + ImportedTypedefNamesForLinkage; + + /// Mergeable declaration contexts that have anonymous declarations + /// within them, and those anonymous declarations. + llvm::DenseMap<Decl*, llvm::SmallVector<NamedDecl*, 2>> + AnonymousDeclarationsForMerging; + + struct FileDeclsInfo { + ModuleFile *Mod = nullptr; + ArrayRef<serialization::LocalDeclID> Decls; + + FileDeclsInfo() = default; + FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls) + : Mod(Mod), Decls(Decls) {} + }; + + /// Map from a FileID to the file-level declarations that it contains. + llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs; + + /// An array of lexical contents of a declaration context, as a sequence of + /// Decl::Kind, DeclID pairs. + using LexicalContents = ArrayRef<llvm::support::unaligned_uint32_t>; + + /// Map from a DeclContext to its lexical contents. + llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>> + LexicalDecls; + + /// Map from the TU to its lexical contents from each module file. + std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls; + + /// Map from a DeclContext to its lookup tables. + llvm::DenseMap<const DeclContext *, + serialization::reader::DeclContextLookupTable> Lookups; + + // Updates for visible decls can occur for other contexts than just the + // TU, and when we read those update records, the actual context may not + // be available yet, so have this pending map using the ID as a key. It + // will be realized when the context is actually loaded. + struct PendingVisibleUpdate { + ModuleFile *Mod; + const unsigned char *Data; + }; + using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>; + + /// Updates to the visible declarations of declaration contexts that + /// haven't been loaded yet. + llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates> + PendingVisibleUpdates; + + /// The set of C++ or Objective-C classes that have forward + /// declarations that have not yet been linked to their definitions. + llvm::SmallPtrSet<Decl *, 4> PendingDefinitions; + + using PendingBodiesMap = + llvm::MapVector<Decl *, uint64_t, + llvm::SmallDenseMap<Decl *, unsigned, 4>, + SmallVector<std::pair<Decl *, uint64_t>, 4>>; + + /// Functions or methods that have bodies that will be attached. + PendingBodiesMap PendingBodies; + + /// Definitions for which we have added merged definitions but not yet + /// performed deduplication. + llvm::SetVector<NamedDecl *> PendingMergedDefinitionsToDeduplicate; + + /// Read the record that describes the lexical contents of a DC. + bool ReadLexicalDeclContextStorage(ModuleFile &M, + llvm::BitstreamCursor &Cursor, + uint64_t Offset, DeclContext *DC); + + /// Read the record that describes the visible contents of a DC. + bool ReadVisibleDeclContextStorage(ModuleFile &M, + llvm::BitstreamCursor &Cursor, + uint64_t Offset, serialization::DeclID ID); + + /// A vector containing identifiers that have already been + /// loaded. + /// + /// If the pointer at index I is non-NULL, then it refers to the + /// IdentifierInfo for the identifier with ID=I+1 that has already + /// been loaded. + std::vector<IdentifierInfo *> IdentifiersLoaded; + + using GlobalIdentifierMapType = + ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>; + + /// Mapping from global identifier IDs to the module in which the + /// identifier resides along with the offset that should be added to the + /// global identifier ID to produce a local ID. + GlobalIdentifierMapType GlobalIdentifierMap; + + /// A vector containing macros that have already been + /// loaded. + /// + /// If the pointer at index I is non-NULL, then it refers to the + /// MacroInfo for the identifier with ID=I+1 that has already + /// been loaded. + std::vector<MacroInfo *> MacrosLoaded; + + using LoadedMacroInfo = + std::pair<IdentifierInfo *, serialization::SubmoduleID>; + + /// A set of #undef directives that we have loaded; used to + /// deduplicate the same #undef information coming from multiple module + /// files. + llvm::DenseSet<LoadedMacroInfo> LoadedUndefs; + + using GlobalMacroMapType = + ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>; + + /// Mapping from global macro IDs to the module in which the + /// macro resides along with the offset that should be added to the + /// global macro ID to produce a local ID. + GlobalMacroMapType GlobalMacroMap; + + /// A vector containing submodules that have already been loaded. + /// + /// This vector is indexed by the Submodule ID (-1). NULL submodule entries + /// indicate that the particular submodule ID has not yet been loaded. + SmallVector<Module *, 2> SubmodulesLoaded; + + using GlobalSubmoduleMapType = + ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>; + + /// Mapping from global submodule IDs to the module file in which the + /// submodule resides along with the offset that should be added to the + /// global submodule ID to produce a local ID. + GlobalSubmoduleMapType GlobalSubmoduleMap; + + /// A set of hidden declarations. + using HiddenNames = SmallVector<Decl *, 2>; + using HiddenNamesMapType = llvm::DenseMap<Module *, HiddenNames>; + + /// A mapping from each of the hidden submodules to the deserialized + /// declarations in that submodule that could be made visible. + HiddenNamesMapType HiddenNamesMap; + + /// A module import, export, or conflict that hasn't yet been resolved. + struct UnresolvedModuleRef { + /// The file in which this module resides. + ModuleFile *File; + + /// The module that is importing or exporting. + Module *Mod; + + /// The kind of module reference. + enum { Import, Export, Conflict } Kind; + + /// The local ID of the module that is being exported. + unsigned ID; + + /// Whether this is a wildcard export. + unsigned IsWildcard : 1; + + /// String data. + StringRef String; + }; + + /// The set of module imports and exports that still need to be + /// resolved. + SmallVector<UnresolvedModuleRef, 2> UnresolvedModuleRefs; + + /// A vector containing selectors that have already been loaded. + /// + /// This vector is indexed by the Selector ID (-1). NULL selector + /// entries indicate that the particular selector ID has not yet + /// been loaded. + SmallVector<Selector, 16> SelectorsLoaded; + + using GlobalSelectorMapType = + ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>; + + /// Mapping from global selector IDs to the module in which the + /// global selector ID to produce a local ID. + GlobalSelectorMapType GlobalSelectorMap; + + /// The generation number of the last time we loaded data from the + /// global method pool for this selector. + llvm::DenseMap<Selector, unsigned> SelectorGeneration; + + /// Whether a selector is out of date. We mark a selector as out of date + /// if we load another module after the method pool entry was pulled in. + llvm::DenseMap<Selector, bool> SelectorOutOfDate; + + struct PendingMacroInfo { + ModuleFile *M; + uint64_t MacroDirectivesOffset; + + PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) + : M(M), MacroDirectivesOffset(MacroDirectivesOffset) {} + }; + + using PendingMacroIDsMap = + llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2>>; + + /// Mapping from identifiers that have a macro history to the global + /// IDs have not yet been deserialized to the global IDs of those macros. + PendingMacroIDsMap PendingMacroIDs; + + using GlobalPreprocessedEntityMapType = + ContinuousRangeMap<unsigned, ModuleFile *, 4>; + + /// Mapping from global preprocessing entity IDs to the module in + /// which the preprocessed entity resides along with the offset that should be + /// added to the global preprocessing entity ID to produce a local ID. + GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap; + + using GlobalSkippedRangeMapType = + ContinuousRangeMap<unsigned, ModuleFile *, 4>; + + /// Mapping from global skipped range base IDs to the module in which + /// the skipped ranges reside. + GlobalSkippedRangeMapType GlobalSkippedRangeMap; + + /// \name CodeGen-relevant special data + /// Fields containing data that is relevant to CodeGen. + //@{ + + /// The IDs of all declarations that fulfill the criteria of + /// "interesting" decls. + /// + /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks + /// in the chain. The referenced declarations are deserialized and passed to + /// the consumer eagerly. + SmallVector<uint64_t, 16> EagerlyDeserializedDecls; + + /// The IDs of all tentative definitions stored in the chain. + /// + /// Sema keeps track of all tentative definitions in a TU because it has to + /// complete them and pass them on to CodeGen. Thus, tentative definitions in + /// the PCH chain must be eagerly deserialized. + SmallVector<uint64_t, 16> TentativeDefinitions; + + /// The IDs of all CXXRecordDecls stored in the chain whose VTables are + /// used. + /// + /// CodeGen has to emit VTables for these records, so they have to be eagerly + /// deserialized. + SmallVector<uint64_t, 64> VTableUses; + + /// A snapshot of the pending instantiations in the chain. + /// + /// This record tracks the instantiations that Sema has to perform at the + /// end of the TU. It consists of a pair of values for every pending + /// instantiation where the first value is the ID of the decl and the second + /// is the instantiation location. + SmallVector<uint64_t, 64> PendingInstantiations; + + //@} + + /// \name DiagnosticsEngine-relevant special data + /// Fields containing data that is used for generating diagnostics + //@{ + + /// A snapshot of Sema's unused file-scoped variable tracking, for + /// generating warnings. + SmallVector<uint64_t, 16> UnusedFileScopedDecls; + + /// A list of all the delegating constructors we've seen, to diagnose + /// cycles. + SmallVector<uint64_t, 4> DelegatingCtorDecls; + + /// Method selectors used in a @selector expression. Used for + /// implementation of -Wselector. + SmallVector<uint64_t, 64> ReferencedSelectorsData; + + /// A snapshot of Sema's weak undeclared identifier tracking, for + /// generating warnings. + SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers; + + /// The IDs of type aliases for ext_vectors that exist in the chain. + /// + /// Used by Sema for finding sugared names for ext_vectors in diagnostics. + SmallVector<uint64_t, 4> ExtVectorDecls; + + //@} + + /// \name Sema-relevant special data + /// Fields containing data that is used for semantic analysis + //@{ + + /// The IDs of all potentially unused typedef names in the chain. + /// + /// Sema tracks these to emit warnings. + SmallVector<uint64_t, 16> UnusedLocalTypedefNameCandidates; + + /// Our current depth in #pragma cuda force_host_device begin/end + /// macros. + unsigned ForceCUDAHostDeviceDepth = 0; + + /// The IDs of the declarations Sema stores directly. + /// + /// Sema tracks a few important decls, such as namespace std, directly. + SmallVector<uint64_t, 4> SemaDeclRefs; + + /// The IDs of the types ASTContext stores directly. + /// + /// The AST context tracks a few important types, such as va_list, directly. + SmallVector<uint64_t, 16> SpecialTypes; + + /// The IDs of CUDA-specific declarations ASTContext stores directly. + /// + /// The AST context tracks a few important decls, currently cudaConfigureCall, + /// directly. + SmallVector<uint64_t, 2> CUDASpecialDeclRefs; + + /// The floating point pragma option settings. + SmallVector<uint64_t, 1> FPPragmaOptions; + + /// The pragma clang optimize location (if the pragma state is "off"). + SourceLocation OptimizeOffPragmaLocation; + + /// The PragmaMSStructKind pragma ms_struct state if set, or -1. + int PragmaMSStructState = -1; + + /// The PragmaMSPointersToMembersKind pragma pointers_to_members state. + int PragmaMSPointersToMembersState = -1; + SourceLocation PointersToMembersPragmaLocation; + + /// The pragma pack state. + Optional<unsigned> PragmaPackCurrentValue; + SourceLocation PragmaPackCurrentLocation; + struct PragmaPackStackEntry { + unsigned Value; + SourceLocation Location; + SourceLocation PushLocation; + StringRef SlotLabel; + }; + llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack; + llvm::SmallVector<std::string, 2> PragmaPackStrings; + + /// The OpenCL extension settings. + OpenCLOptions OpenCLExtensions; + + /// Extensions required by an OpenCL type. + llvm::DenseMap<const Type *, std::set<std::string>> OpenCLTypeExtMap; + + /// Extensions required by an OpenCL declaration. + llvm::DenseMap<const Decl *, std::set<std::string>> OpenCLDeclExtMap; + + /// A list of the namespaces we've seen. + SmallVector<uint64_t, 4> KnownNamespaces; + + /// A list of undefined decls with internal linkage followed by the + /// SourceLocation of a matching ODR-use. + SmallVector<uint64_t, 8> UndefinedButUsed; + + /// Delete expressions to analyze at the end of translation unit. + SmallVector<uint64_t, 8> DelayedDeleteExprs; + + // A list of late parsed template function data. + SmallVector<uint64_t, 1> LateParsedTemplates; + +public: + struct ImportedSubmodule { + serialization::SubmoduleID ID; + SourceLocation ImportLoc; + + ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc) + : 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; + //@} + + /// The system include root to be used when loading the + /// precompiled header. + std::string isysroot; + + /// Whether to disable the normal validation performed on precompiled + /// headers when they are loaded. + bool DisableValidation; + + /// Whether to accept an AST file with compiler errors. + bool AllowASTWithCompilerErrors; + + /// Whether to accept an AST file that has a different configuration + /// from the current compiler instance. + bool AllowConfigurationMismatch; + + /// Whether validate system input files. + bool ValidateSystemInputs; + + /// Whether we are allowed to use the global module index. + bool UseGlobalIndex; + + /// Whether we have tried loading the global module index yet. + bool TriedLoadingGlobalIndex = false; + + ///Whether we are currently processing update records. + bool ProcessingUpdateRecords = false; + + using SwitchCaseMapTy = llvm::DenseMap<unsigned, SwitchCase *>; + + /// Mapping from switch-case IDs in the chain to switch-case statements + /// + /// Statements usually don't have IDs, but switch cases need them, so that the + /// switch statement can refer to them. + SwitchCaseMapTy SwitchCaseStmts; + + SwitchCaseMapTy *CurrSwitchCaseStmts; + + /// The number of source location entries de-serialized from + /// the PCH file. + unsigned NumSLocEntriesRead = 0; + + /// The number of source location entries in the chain. + unsigned TotalNumSLocEntries = 0; + + /// The number of statements (and expressions) de-serialized + /// from the chain. + unsigned NumStatementsRead = 0; + + /// The total number of statements (and expressions) stored + /// in the chain. + unsigned TotalNumStatements = 0; + + /// The number of macros de-serialized from the chain. + unsigned NumMacrosRead = 0; + + /// The total number of macros stored in the chain. + unsigned TotalNumMacros = 0; + + /// The number of lookups into identifier tables. + unsigned NumIdentifierLookups = 0; + + /// The number of lookups into identifier tables that succeed. + unsigned NumIdentifierLookupHits = 0; + + /// The number of selectors that have been read. + unsigned NumSelectorsRead = 0; + + /// The number of method pool entries that have been read. + unsigned NumMethodPoolEntriesRead = 0; + + /// The number of times we have looked up a selector in the method + /// pool. + unsigned NumMethodPoolLookups = 0; + + /// The number of times we have looked up a selector in the method + /// pool and found something. + unsigned NumMethodPoolHits = 0; + + /// The number of times we have looked up a selector in the method + /// pool within a specific module. + unsigned NumMethodPoolTableLookups = 0; + + /// The number of times we have looked up a selector in the method + /// pool within a specific module and found something. + unsigned NumMethodPoolTableHits = 0; + + /// The total number of method pool entries in the selector table. + unsigned TotalNumMethodPoolEntries = 0; + + /// Number of lexical decl contexts read/total. + unsigned NumLexicalDeclContextsRead = 0, TotalLexicalDeclContexts = 0; + + /// Number of visible decl contexts read/total. + unsigned NumVisibleDeclContextsRead = 0, TotalVisibleDeclContexts = 0; + + /// Total size of modules, in bits, currently loaded + uint64_t TotalModulesSizeInBits = 0; + + /// Number of Decl/types that are currently deserializing. + unsigned NumCurrentElementsDeserializing = 0; + + /// Set true while we are in the process of passing deserialized + /// "interesting" decls to consumer inside FinishedDeserializing(). + /// This is used as a guard to avoid recursively repeating the process of + /// passing decls to consumer. + bool PassingDeclsToConsumer = false; + + /// The set of identifiers that were read while the AST reader was + /// (recursively) loading declarations. + /// + /// The declarations on the identifier chain for these identifiers will be + /// loaded once the recursive loading has completed. + llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4>> + PendingIdentifierInfos; + + /// The set of lookup results that we have faked in order to support + /// merging of partially deserialized decls but that we have not yet removed. + llvm::SmallMapVector<IdentifierInfo *, SmallVector<NamedDecl*, 2>, 16> + PendingFakeLookupResults; + + /// The generation number of each identifier, which keeps track of + /// the last time we loaded information about this identifier. + llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration; + + class InterestingDecl { + Decl *D; + bool DeclHasPendingBody; + + public: + InterestingDecl(Decl *D, bool HasBody) + : D(D), DeclHasPendingBody(HasBody) {} + + Decl *getDecl() { return D; } + + /// Whether the declaration has a pending body. + bool hasPendingBody() { return DeclHasPendingBody; } + }; + + /// Contains declarations and definitions that could be + /// "interesting" to the ASTConsumer, when we get that AST consumer. + /// + /// "Interesting" declarations are those that have data that may + /// need to be emitted, such as inline function definitions or + /// Objective-C protocols. + std::deque<InterestingDecl> PotentiallyInterestingDecls; + + /// The list of deduced function types that we have not yet read, because + /// 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; + + /// The list of redeclaration chains that still need to be + /// reconstructed, and the local offset to the corresponding list + /// of redeclarations. + SmallVector<std::pair<Decl *, uint64_t>, 16> PendingDeclChains; + + /// The list of canonical declarations whose redeclaration chains + /// need to be marked as incomplete once we're done deserializing things. + SmallVector<Decl *, 16> PendingIncompleteDeclChains; + + /// The Decl IDs for the Sema/Lexical DeclContext of a Decl that has + /// been loaded but its DeclContext was not set yet. + struct PendingDeclContextInfo { + Decl *D; + serialization::GlobalDeclID SemaDC; + serialization::GlobalDeclID LexicalDC; + }; + + /// The set of Decls that have been loaded but their DeclContexts are + /// not set yet. + /// + /// The DeclContexts for these Decls will be set once recursive loading has + /// been completed. + std::deque<PendingDeclContextInfo> PendingDeclContextInfos; + + /// 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. + /// + /// We will check whether the corresponding declaration is in fact missing + /// once recursing loading has been completed. + llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks; + + using DataPointers = + std::pair<CXXRecordDecl *, struct CXXRecordDecl::DefinitionData *>; + + /// Record definitions in which we found an ODR violation. + llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2> + PendingOdrMergeFailures; + + /// Function definitions in which we found an ODR violation. + llvm::SmallDenseMap<FunctionDecl *, llvm::SmallVector<FunctionDecl *, 2>, 2> + PendingFunctionOdrMergeFailures; + + /// Enum definitions in which we found an ODR violation. + llvm::SmallDenseMap<EnumDecl *, llvm::SmallVector<EnumDecl *, 2>, 2> + PendingEnumOdrMergeFailures; + + /// DeclContexts in which we have diagnosed an ODR violation. + llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures; + + /// The set of Objective-C categories that have been deserialized + /// since the last time the declaration chains were linked. + llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized; + + /// The set of Objective-C class definitions that have already been + /// loaded, for which we will need to check for categories whenever a new + /// module is loaded. + SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded; + + using KeyDeclsMap = + llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2>>; + + /// A mapping from canonical declarations to the set of global + /// declaration IDs for key declaration that have been merged with that + /// canonical declaration. A key declaration is a formerly-canonical + /// declaration whose module did not import any other key declaration for that + /// entity. These are the IDs that we use as keys when finding redecl chains. + KeyDeclsMap KeyDecls; + + /// A mapping from DeclContexts to the semantic DeclContext that we + /// are treating as the definition of the entity. This is used, for instance, + /// when merging implicit instantiations of class templates across modules. + llvm::DenseMap<DeclContext *, DeclContext *> MergedDeclContexts; + + /// A mapping from canonical declarations of enums to their canonical + /// definitions. Only populated when using modules in C++. + llvm::DenseMap<EnumDecl *, EnumDecl *> EnumDefinitions; + + /// When reading a Stmt tree, Stmt operands are placed in this stack. + SmallVector<Stmt *, 16> StmtStack; + + /// What kind of records we are reading. + enum ReadingKind { + Read_None, Read_Decl, Read_Type, Read_Stmt + }; + + /// What kind of records we are reading. + ReadingKind ReadingKind = Read_None; + + /// RAII object to change the reading kind. + class ReadingKindTracker { + ASTReader &Reader; + enum ReadingKind PrevKind; + + public: + ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader) + : Reader(reader), PrevKind(Reader.ReadingKind) { + Reader.ReadingKind = newKind; + } + + ReadingKindTracker(const ReadingKindTracker &) = delete; + ReadingKindTracker &operator=(const ReadingKindTracker &) = delete; + ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; } + }; + + /// RAII object to mark the start of processing updates. + class ProcessingUpdatesRAIIObj { + ASTReader &Reader; + bool PrevState; + + public: + ProcessingUpdatesRAIIObj(ASTReader &reader) + : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) { + Reader.ProcessingUpdateRecords = true; + } + + ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete; + ProcessingUpdatesRAIIObj & + operator=(const ProcessingUpdatesRAIIObj &) = delete; + ~ProcessingUpdatesRAIIObj() { Reader.ProcessingUpdateRecords = PrevState; } + }; + + /// Suggested contents of the predefines buffer, after this + /// PCH file has been processed. + /// + /// In most cases, this string will be empty, because the predefines + /// buffer computed to build the PCH file will be identical to the + /// predefines buffer computed from the command line. However, when + /// there are differences that the PCH reader can work around, this + /// predefines buffer may contain additional definitions. + std::string SuggestedPredefines; + + llvm::DenseMap<const Decl *, bool> DefinitionSource; + + /// Reads a statement from the specified cursor. + Stmt *ReadStmtFromStream(ModuleFile &F); + + struct InputFileInfo { + std::string Filename; + 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 file entry and 'overridden' bit for an input + /// file in the given module file. + serialization::InputFile getInputFile(ModuleFile &F, unsigned ID, + bool Complain = true); + +public: + void ResolveImportedPath(ModuleFile &M, std::string &Filename); + static void ResolveImportedPath(std::string &Filename, StringRef Prefix); + + /// Returns the first key declaration for the given declaration. This + /// is one that is formerly-canonical (or still canonical) and whose module + /// did not import any other key declaration of the entity. + Decl *getKeyDeclaration(Decl *D) { + D = D->getCanonicalDecl(); + if (D->isFromASTFile()) + return D; + + auto I = KeyDecls.find(D); + if (I == KeyDecls.end() || I->second.empty()) + return D; + return GetExistingDecl(I->second[0]); + } + const Decl *getKeyDeclaration(const Decl *D) { + return getKeyDeclaration(const_cast<Decl*>(D)); + } + + /// Run a callback on each imported key declaration of \p D. + template <typename Fn> + void forEachImportedKeyDecl(const Decl *D, Fn Visit) { + D = D->getCanonicalDecl(); + if (D->isFromASTFile()) + Visit(D); + + auto It = KeyDecls.find(const_cast<Decl*>(D)); + if (It != KeyDecls.end()) + for (auto ID : It->second) + Visit(GetExistingDecl(ID)); + } + + /// Get the loaded lookup tables for \p Primary, if any. + const serialization::reader::DeclContextLookupTable * + getLoadedLookupTables(DeclContext *Primary) const; + +private: + struct ImportedModule { + ModuleFile *Mod; + ModuleFile *ImportedBy; + SourceLocation ImportLoc; + + ImportedModule(ModuleFile *Mod, + ModuleFile *ImportedBy, + SourceLocation ImportLoc) + : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {} + }; + + ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, + SourceLocation ImportLoc, ModuleFile *ImportedBy, + SmallVectorImpl<ImportedModule> &Loaded, + off_t ExpectedSize, time_t ExpectedModTime, + ASTFileSignature ExpectedSignature, + unsigned ClientLoadCapabilities); + ASTReadResult ReadControlBlock(ModuleFile &F, + SmallVectorImpl<ImportedModule> &Loaded, + const ModuleFile *ImportedBy, + unsigned ClientLoadCapabilities); + static ASTReadResult ReadOptionsBlock( + llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities, + bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, + std::string &SuggestedPredefines); + + /// Read the unhashed control block. + /// + /// This has no effect on \c F.Stream, instead creating a fresh cursor from + /// \c F.Data and reading ahead. + ASTReadResult readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy, + unsigned ClientLoadCapabilities); + + static ASTReadResult + readUnhashedControlBlockImpl(ModuleFile *F, llvm::StringRef StreamData, + unsigned ClientLoadCapabilities, + bool AllowCompatibleConfigurationMismatch, + ASTReaderListener *Listener, + bool ValidateDiagnosticOptions); + + ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); + ASTReadResult ReadExtensionBlock(ModuleFile &F); + void ReadModuleOffsetMap(ModuleFile &F) const; + bool ParseLineTable(ModuleFile &F, const RecordData &Record); + bool ReadSourceManagerBlock(ModuleFile &F); + llvm::BitstreamCursor &SLocCursorForID(int ID); + SourceLocation getImportLocation(ModuleFile *F); + ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, + const ModuleFile *ImportedBy, + unsigned ClientLoadCapabilities); + ASTReadResult ReadSubmoduleBlock(ModuleFile &F, + unsigned ClientLoadCapabilities); + static bool ParseLanguageOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener, + bool AllowCompatibleDifferences); + static bool ParseTargetOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener, + bool AllowCompatibleDifferences); + static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseFileSystemOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener); + static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain, + ASTReaderListener &Listener, + std::string &SuggestedPredefines); + + struct RecordLocation { + ModuleFile *F; + uint64_t Offset; + + RecordLocation(ModuleFile *M, uint64_t O) : F(M), Offset(O) {} + }; + + QualType readTypeRecord(unsigned Index); + void readExceptionSpec(ModuleFile &ModuleFile, + SmallVectorImpl<QualType> &ExceptionStorage, + FunctionProtoType::ExceptionSpecInfo &ESI, + const RecordData &Record, unsigned &Index); + RecordLocation TypeCursorForIndex(unsigned Index); + void LoadedDecl(unsigned Index, Decl *D); + Decl *ReadDeclRecord(serialization::DeclID ID); + void markIncompleteDeclChain(Decl *Canon); + + /// Returns the most recent declaration of a declaration (which must be + /// of a redeclarable kind) that is either local or has already been loaded + /// merged into its redecl chain. + Decl *getMostRecentExistingDecl(Decl *D); + + RecordLocation DeclCursorForID(serialization::DeclID ID, + SourceLocation &Location); + void loadDeclUpdateRecords(PendingUpdateRecord &Record); + void loadPendingDeclChain(Decl *D, uint64_t LocalOffset); + void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, + unsigned PreviousGeneration = 0); + + RecordLocation getLocalBitOffset(uint64_t GlobalOffset); + uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset); + + /// Returns the first preprocessed entity ID that begins or ends after + /// \arg Loc. + serialization::PreprocessedEntityID + findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const; + + /// Find the next module that contains entities and return the ID + /// of the first entry. + /// + /// \param SLocMapI points at a chunk of a module that contains no + /// preprocessed entities or the entities it contains are not the + /// ones we are looking for. + serialization::PreprocessedEntityID + findNextPreprocessedEntity( + GlobalSLocOffsetMapType::const_iterator SLocMapI) const; + + /// Returns (ModuleFile, Local index) pair for \p GlobalIndex of a + /// preprocessed entity. + std::pair<ModuleFile *, unsigned> + getModulePreprocessedEntity(unsigned GlobalIndex); + + /// Returns (begin, end) pair for the preprocessed entities of a + /// particular module. + llvm::iterator_range<PreprocessingRecord::iterator> + getModulePreprocessedEntities(ModuleFile &Mod) const; + +public: + class ModuleDeclIterator + : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const serialization::LocalDeclID *, + std::random_access_iterator_tag, const Decl *, ptrdiff_t, + const Decl *, const Decl *> { + ASTReader *Reader = nullptr; + ModuleFile *Mod = nullptr; + + public: + ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} + + ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, + const serialization::LocalDeclID *Pos) + : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} + + value_type operator*() const { + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I)); + } + + value_type operator->() const { return **this; } + + bool operator==(const ModuleDeclIterator &RHS) const { + assert(Reader == RHS.Reader && Mod == RHS.Mod); + return I == RHS.I; + } + }; + + llvm::iterator_range<ModuleDeclIterator> + getModuleFileLevelDecls(ModuleFile &Mod); + +private: + void PassInterestingDeclsToConsumer(); + void PassInterestingDeclToConsumer(Decl *D); + + void finishPendingActions(); + void diagnoseOdrViolations(); + + void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); + + void addPendingDeclContextInfo(Decl *D, + serialization::GlobalDeclID SemaDC, + serialization::GlobalDeclID LexicalDC) { + assert(D); + PendingDeclContextInfo Info = { D, SemaDC, LexicalDC }; + PendingDeclContextInfos.push_back(Info); + } + + /// Produce an error diagnostic and return true. + /// + /// This routine should only be used for fatal errors that have to + /// do with non-routine failures (e.g., corrupted AST file). + void Error(StringRef Msg) const; + void Error(unsigned DiagID, StringRef Arg1 = StringRef(), + StringRef Arg2 = StringRef()) const; + +public: + /// Load the AST file and validate its contents against the given + /// Preprocessor. + /// + /// \param PP the preprocessor associated with the context in which this + /// precompiled header will be loaded. + /// + /// \param Context the AST context that this precompiled header will be + /// loaded into, if any. + /// + /// \param PCHContainerRdr the PCHContainerOperations to use for loading and + /// creating modules. + /// + /// \param Extensions the list of module file extensions that can be loaded + /// from the AST files. + /// + /// \param isysroot If non-NULL, the system include path specified by the + /// user. This is only used with relocatable PCH files. If non-NULL, + /// a relocatable PCH file will use the default path "/". + /// + /// \param DisableValidation If true, the AST reader will suppress most + /// of its regular consistency checking, allowing the use of precompiled + /// headers that cannot be determined to be compatible. + /// + /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an + /// AST file the was created out of an AST with compiler errors, + /// otherwise it will reject it. + /// + /// \param AllowConfigurationMismatch If true, the AST reader will not check + /// for configuration differences between the AST file and the invocation. + /// + /// \param ValidateSystemInputs If true, the AST reader will validate + /// system input files in addition to user input files. This is only + /// meaningful if \p DisableValidation is false. + /// + /// \param UseGlobalIndex If true, the AST reader will try to load and use + /// the global module index. + /// + /// \param ReadTimer If non-null, a timer used to track the time spent + /// deserializing. + ASTReader(Preprocessor &PP, ASTContext *Context, + const PCHContainerReader &PCHContainerRdr, + ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + StringRef isysroot = "", bool DisableValidation = false, + bool AllowASTWithCompilerErrors = false, + bool AllowConfigurationMismatch = false, + bool ValidateSystemInputs = false, bool UseGlobalIndex = true, + std::unique_ptr<llvm::Timer> ReadTimer = {}); + ASTReader(const ASTReader &) = delete; + ASTReader &operator=(const ASTReader &) = delete; + ~ASTReader() override; + + SourceManager &getSourceManager() const { return SourceMgr; } + FileManager &getFileManager() const { return FileMgr; } + DiagnosticsEngine &getDiags() const { return Diags; } + + /// Flags that indicate what kind of AST loading failures the client + /// of the AST reader can directly handle. + /// + /// When a client states that it can handle a particular kind of failure, + /// the AST reader will not emit errors when producing that kind of failure. + enum LoadFailureCapabilities { + /// The client can't handle any AST loading failures. + ARR_None = 0, + + /// The client can handle an AST file that cannot load because it + /// is missing. + ARR_Missing = 0x1, + + /// The client can handle an AST file that cannot load because it + /// is out-of-date relative to its input files. + ARR_OutOfDate = 0x2, + + /// The client can handle an AST file that cannot load because it + /// was built with a different version of Clang. + ARR_VersionMismatch = 0x4, + + /// The client can handle an AST file that cannot load because it's + /// compiled configuration doesn't match that of the context it was + /// loaded into. + ARR_ConfigurationMismatch = 0x8 + }; + + /// Load the AST file designated by the given file name. + /// + /// \param FileName The name of the AST file to load. + /// + /// \param Type The kind of AST being loaded, e.g., PCH, module, main file, + /// or preamble. + /// + /// \param ImportLoc the location where the module file will be considered as + /// imported from. For non-module AST types it should be invalid. + /// + /// \param ClientLoadCapabilities The set of client load-failure + /// 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 + ASTReadResult ReadAST(StringRef FileName, ModuleKind Type, + SourceLocation ImportLoc, + unsigned ClientLoadCapabilities, + SmallVectorImpl<ImportedSubmodule> *Imported = nullptr); + + /// Make the entities in the given module and any of its (non-explicit) + /// submodules visible to name lookup. + /// + /// \param Mod The module whose names should be made visible. + /// + /// \param NameVisibility The level of visibility to give the names in the + /// module. Visibility can only be increased over time. + /// + /// \param ImportLoc The location at which the import occurs. + void makeModuleVisible(Module *Mod, + Module::NameVisibilityKind NameVisibility, + SourceLocation ImportLoc); + + /// Make the names within this set of hidden names visible. + void makeNamesVisible(const HiddenNames &Names, Module *Owner); + + /// Note that MergedDef is a redefinition of the canonical definition + /// Def, so Def should be visible whenever MergedDef is. + void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef); + + /// Take the AST callbacks listener. + std::unique_ptr<ASTReaderListener> takeListener() { + return std::move(Listener); + } + + /// Set the AST callbacks listener. + void setListener(std::unique_ptr<ASTReaderListener> Listener) { + this->Listener = std::move(Listener); + } + + /// Add an AST callback listener. + /// + /// Takes ownership of \p L. + void addListener(std::unique_ptr<ASTReaderListener> L) { + if (Listener) + L = llvm::make_unique<ChainedASTReaderListener>(std::move(L), + std::move(Listener)); + Listener = std::move(L); + } + + /// RAII object to temporarily add an AST callback listener. + class ListenerScope { + ASTReader &Reader; + bool Chained = false; + + public: + ListenerScope(ASTReader &Reader, std::unique_ptr<ASTReaderListener> L) + : Reader(Reader) { + auto Old = Reader.takeListener(); + if (Old) { + Chained = true; + L = llvm::make_unique<ChainedASTReaderListener>(std::move(L), + std::move(Old)); + } + Reader.setListener(std::move(L)); + } + + ~ListenerScope() { + auto New = Reader.takeListener(); + if (Chained) + Reader.setListener(static_cast<ChainedASTReaderListener *>(New.get()) + ->takeSecond()); + } + }; + + /// Set the AST deserialization listener. + void setDeserializationListener(ASTDeserializationListener *Listener, + bool TakeOwnership = false); + + /// Get the AST deserialization listener. + ASTDeserializationListener *getDeserializationListener() { + return DeserializationListener; + } + + /// Determine whether this AST reader has a global index. + bool hasGlobalIndex() const { return (bool)GlobalIndex; } + + /// Return global module index. + GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); } + + /// Reset reader for a reload try. + void resetForReload() { TriedLoadingGlobalIndex = false; } + + /// Attempts to load the global index. + /// + /// \returns true if loading the global index has failed for any reason. + bool loadGlobalIndex(); + + /// Determine whether we tried to load the global index, but failed, + /// e.g., because it is out-of-date or does not exist. + bool isGlobalIndexUnavailable() const; + + /// Initializes the ASTContext + void InitializeContext(); + + /// Update the state of Sema after loading some additional modules. + void UpdateSema(); + + /// Add in-memory (virtual file) buffer. + void addInMemoryBuffer(StringRef &FileName, + std::unique_ptr<llvm::MemoryBuffer> Buffer) { + ModuleMgr.addInMemoryBuffer(FileName, std::move(Buffer)); + } + + /// Finalizes the AST reader's state before writing an AST file to + /// disk. + /// + /// This operation may undo temporary state in the AST that should not be + /// emitted. + void finalizeForWriting(); + + /// Retrieve the module manager. + ModuleManager &getModuleManager() { return ModuleMgr; } + + /// Retrieve the preprocessor. + Preprocessor &getPreprocessor() const { return PP; } + + /// Retrieve the name of the original source file name for the primary + /// module file. + StringRef getOriginalSourceFile() { + return ModuleMgr.getPrimaryModule().OriginalSourceFileName; + } + + /// Retrieve the name of the original source file name directly from + /// the AST file, without actually loading the AST file. + static std::string + getOriginalSourceFile(const std::string &ASTFileName, FileManager &FileMgr, + const PCHContainerReader &PCHContainerRdr, + DiagnosticsEngine &Diags); + + /// 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); + + /// 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 PCHContainerReader &PCHContainerRdr, + const LangOptions &LangOpts, + const TargetOptions &TargetOpts, + const PreprocessorOptions &PPOpts, + StringRef ExistingModuleCachePath); + + /// Returns the suggested contents of the predefines buffer, + /// which contains a (typically-empty) subset of the predefines + /// build prior to including the precompiled header. + const std::string &getSuggestedPredefines() { return SuggestedPredefines; } + + /// Read a preallocated preprocessed entity from the external source. + /// + /// \returns null if an error occurred that prevented the preprocessed + /// entity from being loaded. + PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) override; + + /// Returns a pair of [Begin, End) indices of preallocated + /// preprocessed entities that \p Range encompasses. + std::pair<unsigned, unsigned> + findPreprocessedEntitiesInRange(SourceRange Range) override; + + /// 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; + + /// 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; + + void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag); + + /// Returns the number of source locations found in the chain. + unsigned getTotalNumSLocs() const { + return TotalNumSLocEntries; + } + + /// Returns the number of identifiers found in the chain. + unsigned getTotalNumIdentifiers() const { + return static_cast<unsigned>(IdentifiersLoaded.size()); + } + + /// Returns the number of macros found in the chain. + unsigned getTotalNumMacros() const { + return static_cast<unsigned>(MacrosLoaded.size()); + } + + /// Returns the number of types found in the chain. + unsigned getTotalNumTypes() const { + return static_cast<unsigned>(TypesLoaded.size()); + } + + /// Returns the number of declarations found in the chain. + unsigned getTotalNumDecls() const { + return static_cast<unsigned>(DeclsLoaded.size()); + } + + /// Returns the number of submodules known. + unsigned getTotalNumSubmodules() const { + return static_cast<unsigned>(SubmodulesLoaded.size()); + } + + /// Returns the number of selectors found in the chain. + unsigned getTotalNumSelectors() const { + return static_cast<unsigned>(SelectorsLoaded.size()); + } + + /// Returns the number of preprocessed entities known to the AST + /// reader. + unsigned getTotalNumPreprocessedEntities() const { + unsigned Result = 0; + for (const auto &M : ModuleMgr) + Result += M.NumPreprocessedEntities; + return Result; + } + + /// Reads a TemplateArgumentLocInfo appropriate for the + /// given TemplateArgument kind. + TemplateArgumentLocInfo + GetTemplateArgumentLocInfo(ModuleFile &F, TemplateArgument::ArgKind Kind, + const RecordData &Record, unsigned &Idx); + + /// Reads a TemplateArgumentLoc. + TemplateArgumentLoc + ReadTemplateArgumentLoc(ModuleFile &F, + const RecordData &Record, unsigned &Idx); + + const ASTTemplateArgumentListInfo* + ReadASTTemplateArgumentListInfo(ModuleFile &F, + const RecordData &Record, unsigned &Index); + + /// Reads a declarator info from the given record. + TypeSourceInfo *GetTypeSourceInfo(ModuleFile &F, + const RecordData &Record, unsigned &Idx); + + /// Raad the type locations for the given TInfo. + void ReadTypeLoc(ModuleFile &F, const RecordData &Record, unsigned &Idx, + TypeLoc TL); + + /// Resolve a type ID into a type, potentially building a new + /// type. + QualType GetType(serialization::TypeID ID); + + /// Resolve a local type ID within a given AST file into a type. + QualType getLocalType(ModuleFile &F, unsigned LocalID); + + /// Map a local type ID within a given AST file into a global type ID. + serialization::TypeID getGlobalTypeID(ModuleFile &F, unsigned LocalID) const; + + /// Read a type from the current position in the given record, which + /// was read from the given AST file. + QualType readType(ModuleFile &F, const RecordData &Record, unsigned &Idx) { + if (Idx >= Record.size()) + return {}; + + return getLocalType(F, Record[Idx++]); + } + + /// Map from a local declaration ID within a given module to a + /// global declaration ID. + serialization::DeclID getGlobalDeclID(ModuleFile &F, + serialization::LocalDeclID LocalID) const; + + /// Returns true if global DeclID \p ID originated from module \p M. + bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; + + /// Retrieve the module file that owns the given declaration, or NULL + /// 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); + + /// Resolve a declaration ID into a declaration, potentially + /// building a new declaration. + Decl *GetDecl(serialization::DeclID ID); + Decl *GetExternalDecl(uint32_t ID) override; + + /// Resolve a declaration ID into a declaration. Return 0 if it's not + /// been loaded yet. + Decl *GetExistingDecl(serialization::DeclID ID); + + /// Reads a declaration with the given local ID in the given module. + Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) { + return GetDecl(getGlobalDeclID(F, LocalID)); + } + + /// Reads a declaration with the given local ID in the given module. + /// + /// \returns The requested declaration, casted to the given return type. + template<typename T> + T *GetLocalDeclAs(ModuleFile &F, uint32_t LocalID) { + return cast_or_null<T>(GetLocalDecl(F, LocalID)); + } + + /// Map a global declaration ID into the declaration ID used to + /// refer to this declaration within the given module fule. + /// + /// \returns the global ID of the given declaration as known in the given + /// module file. + serialization::DeclID + mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + serialization::DeclID GlobalID); + + /// Reads a declaration ID from the given position in a record in the + /// given module. + /// + /// \returns The declaration ID read from the record, adjusted to a global ID. + serialization::DeclID ReadDeclID(ModuleFile &F, const RecordData &Record, + unsigned &Idx); + + /// Reads a declaration from the given position in a record in the + /// given module. + Decl *ReadDecl(ModuleFile &F, const RecordData &R, unsigned &I) { + return GetDecl(ReadDeclID(F, R, I)); + } + + /// Reads a declaration from the given position in a record in the + /// given module. + /// + /// \returns The declaration read from this location, casted to the given + /// result type. + template<typename T> + T *ReadDeclAs(ModuleFile &F, const RecordData &R, unsigned &I) { + return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I))); + } + + /// If any redeclarations of \p D have been imported since it was + /// last checked, this digs out those redeclarations and adds them to the + /// redeclaration chain for \p D. + void CompleteRedeclChain(const Decl *D) override; + + CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; + + /// Resolve the offset of a statement into a statement. + /// + /// This operation will read a new statement from the external + /// source each time it is called, and is meant to be used via a + /// LazyOffsetPtr (which is used by Decls for the body of functions, etc). + Stmt *GetExternalDeclStmt(uint64_t Offset) override; + + /// 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); + + /// Finds all the visible declarations with a given name. + /// The current implementation of this method just loads the entire + /// lookup table as unmaterialized references. + bool FindExternalVisibleDeclsByName(const DeclContext *DC, + DeclarationName Name) override; + + /// Read all of the declarations lexically stored in a + /// declaration context. + /// + /// \param DC The declaration context whose declarations will be + /// read. + /// + /// \param IsKindWeWant A predicate indicating which declaration kinds + /// we are interested in. + /// + /// \param Decls Vector that will contain the declarations loaded + /// from the external source. The caller is responsible for merging + /// these declarations with any declarations already stored in the + /// declaration context. + void + FindExternalLexicalDecls(const DeclContext *DC, + llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, + SmallVectorImpl<Decl *> &Decls) override; + + /// Get the decls that are contained in a file in the Offset/Length + /// range. \p Length can be 0 to indicate a point at \p Offset instead of + /// a range. + void FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length, + SmallVectorImpl<Decl *> &Decls) override; + + /// Notify ASTReader that we started deserialization of + /// a decl or type so until FinishedDeserializing is called there may be + /// decls that are initializing. Must be paired with FinishedDeserializing. + void StartedDeserializing() override; + + /// Notify ASTReader that we finished the deserialization of + /// a decl or type. Must be paired with StartedDeserializing. + void FinishedDeserializing() override; + + /// Function that will be invoked when we begin parsing a new + /// translation unit involving this external AST source. + /// + /// This function will provide all of the external definitions to + /// the ASTConsumer. + void StartTranslationUnit(ASTConsumer *Consumer) override; + + /// Print some statistics about AST usage. + void PrintStats() override; + + /// Dump information about the AST reader to standard error. + void dump(); + + /// Return the amount of memory used by memory buffers, breaking down + /// by heap-backed versus mmap'ed memory. + void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override; + + /// Initialize the semantic source with the Sema instance + /// being used to perform semantic analysis on the abstract syntax + /// tree. + void InitializeSema(Sema &S) override; + + /// Inform the semantic consumer that Sema is no longer available. + void ForgetSema() override { SemaObj = nullptr; } + + /// Retrieve the IdentifierInfo for the named identifier. + /// + /// This routine builds a new IdentifierInfo for the given identifier. If any + /// declarations with this name are visible from translation unit scope, their + /// declarations will be deserialized and introduced into the declaration + /// chain of the identifier. + IdentifierInfo *get(StringRef Name) override; + + /// Retrieve an iterator into the set of all identifiers + /// in all loaded AST files. + IdentifierIterator *getIdentifiers() override; + + /// Load the contents of the global method pool for a given + /// selector. + void ReadMethodPool(Selector Sel) override; + + /// Load the contents of the global method pool for a given + /// selector if necessary. + void updateOutOfDateSelector(Selector Sel) override; + + /// Load the set of namespaces that are known to the external source, + /// which will be used during typo correction. + void ReadKnownNamespaces( + SmallVectorImpl<NamespaceDecl *> &Namespaces) override; + + void ReadUndefinedButUsed( + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override; + + void ReadMismatchingDeleteExpressions(llvm::MapVector< + FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & + Exprs) override; + + void ReadTentativeDefinitions( + SmallVectorImpl<VarDecl *> &TentativeDefs) override; + + void ReadUnusedFileScopedDecls( + SmallVectorImpl<const DeclaratorDecl *> &Decls) override; + + void ReadDelegatingConstructors( + SmallVectorImpl<CXXConstructorDecl *> &Decls) override; + + void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override; + + void ReadUnusedLocalTypedefNameCandidates( + llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; + + void ReadReferencedSelectors( + SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) override; + + void ReadWeakUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WI) override; + + void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override; + + void ReadPendingInstantiations( + SmallVectorImpl<std::pair<ValueDecl *, + SourceLocation>> &Pending) override; + + void ReadLateParsedTemplates( + llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> + &LPTMap) override; + + /// Load a selector from disk, registering its ID if it exists. + void LoadSelector(Selector Sel); + + void SetIdentifierInfo(unsigned ID, IdentifierInfo *II); + void SetGloballyVisibleDecls(IdentifierInfo *II, + const SmallVectorImpl<uint32_t> &DeclIDs, + SmallVectorImpl<Decl *> *Decls = nullptr); + + /// Report a diagnostic. + DiagnosticBuilder Diag(unsigned DiagID) const; + + /// Report a diagnostic. + DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const; + + IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); + + IdentifierInfo *GetIdentifierInfo(ModuleFile &M, const RecordData &Record, + unsigned &Idx) { + return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++])); + } + + IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) override { + // Note that we are loading an identifier. + Deserializing AnIdentifier(this); + + return DecodeIdentifierInfo(ID); + } + + IdentifierInfo *getLocalIdentifier(ModuleFile &M, unsigned LocalID); + + serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M, + unsigned LocalID); + + void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo); + + /// Retrieve the macro with the given ID. + MacroInfo *getMacro(serialization::MacroID ID); + + /// Retrieve the global macro ID corresponding to the given local + /// ID within the given module file. + serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID); + + /// Read the source location entry with index ID. + bool ReadSLocEntry(int ID) override; + + /// Retrieve the module import location and module name for the + /// given source manager entry ID. + std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) override; + + /// Retrieve the global submodule ID given a module and its local ID + /// number. + serialization::SubmoduleID + getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID); + + /// Retrieve the submodule that corresponds to a global submodule ID. + /// + Module *getSubmodule(serialization::SubmoduleID GlobalID); + + /// Retrieve the module that corresponds to the given module ID. + /// + /// Note: overrides method in ExternalASTSource + Module *getModule(unsigned ID) override; + + bool DeclIsFromPCHWithObjectFile(const Decl *D) override; + + /// Retrieve the module file with a given local ID within the specified + /// ModuleFile. + ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID); + + /// Get an ID for the given module file. + unsigned getModuleFileID(ModuleFile *M); + + /// Return a descriptor for the corresponding module. + llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override; + + ExtKind hasExternalDefinitions(const Decl *D) override; + + /// Retrieve a selector from the given module with its local ID + /// number. + Selector getLocalSelector(ModuleFile &M, unsigned LocalID); + + Selector DecodeSelector(serialization::SelectorID Idx); + + Selector GetExternalSelector(serialization::SelectorID ID) override; + uint32_t GetNumExternalSelectors() override; + + Selector ReadSelector(ModuleFile &M, const RecordData &Record, unsigned &Idx) { + return getLocalSelector(M, Record[Idx++]); + } + + /// Retrieve the global selector ID that corresponds to this + /// the local selector ID in a given module. + serialization::SelectorID getGlobalSelectorID(ModuleFile &F, + unsigned LocalID) const; + + /// Read a declaration name. + DeclarationName ReadDeclarationName(ModuleFile &F, + const RecordData &Record, unsigned &Idx); + void ReadDeclarationNameLoc(ModuleFile &F, + DeclarationNameLoc &DNLoc, DeclarationName Name, + const RecordData &Record, unsigned &Idx); + void ReadDeclarationNameInfo(ModuleFile &F, DeclarationNameInfo &NameInfo, + const RecordData &Record, unsigned &Idx); + + void ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info, + const RecordData &Record, unsigned &Idx); + + NestedNameSpecifier *ReadNestedNameSpecifier(ModuleFile &F, + const RecordData &Record, + unsigned &Idx); + + NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(ModuleFile &F, + const RecordData &Record, + unsigned &Idx); + + /// Read a template name. + TemplateName ReadTemplateName(ModuleFile &F, const RecordData &Record, + unsigned &Idx); + + /// Read a template argument. + TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record, + unsigned &Idx, + bool Canonicalize = false); + + /// Read a template parameter list. + TemplateParameterList *ReadTemplateParameterList(ModuleFile &F, + const RecordData &Record, + unsigned &Idx); + + /// Read a template argument array. + void ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, + ModuleFile &F, const RecordData &Record, + unsigned &Idx, bool Canonicalize = false); + + /// Read a UnresolvedSet structure. + void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, + const RecordData &Record, unsigned &Idx); + + /// Read a C++ base specifier. + CXXBaseSpecifier ReadCXXBaseSpecifier(ModuleFile &F, + const RecordData &Record,unsigned &Idx); + + /// Read a CXXCtorInitializer array. + CXXCtorInitializer ** + ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, + unsigned &Idx); + + /// Read the contents of a CXXCtorInitializer array. + CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; + + /// Read a source location from raw form and return it in its + /// originating module file's source location space. + SourceLocation ReadUntranslatedSourceLocation(uint32_t Raw) const { + return SourceLocation::getFromRawEncoding((Raw >> 1) | (Raw << 31)); + } + + /// Read a source location from raw form. + SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, uint32_t Raw) const { + SourceLocation Loc = ReadUntranslatedSourceLocation(Raw); + return TranslateSourceLocation(ModuleFile, Loc); + } + + /// Translate a source location from another module file's source + /// location space into ours. + SourceLocation TranslateSourceLocation(ModuleFile &ModuleFile, + SourceLocation Loc) const { + if (!ModuleFile.ModuleOffsetMap.empty()) + ReadModuleOffsetMap(ModuleFile); + assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != + ModuleFile.SLocRemap.end() && + "Cannot find offset to remap."); + int Remap = ModuleFile.SLocRemap.find(Loc.getOffset())->second; + return Loc.getLocWithOffset(Remap); + } + + /// Read a source location. + SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, + const RecordDataImpl &Record, + unsigned &Idx) { + return ReadSourceLocation(ModuleFile, Record[Idx++]); + } + + /// Read a source range. + SourceRange ReadSourceRange(ModuleFile &F, + const RecordData &Record, unsigned &Idx); + + /// Read an integral value + llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx); + + /// Read a signed integral value + llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx); + + /// Read a floating-point value + llvm::APFloat ReadAPFloat(const RecordData &Record, + const llvm::fltSemantics &Sem, unsigned &Idx); + + // Read a string + static std::string ReadString(const RecordData &Record, unsigned &Idx); + + // Skip a string + static void SkipString(const RecordData &Record, unsigned &Idx) { + Idx += Record[Idx] + 1; + } + + // Read a path + std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx); + + // Skip a path + static void SkipPath(const RecordData &Record, unsigned &Idx) { + SkipString(Record, Idx); + } + + /// Read a version tuple. + static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); + + CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record, + unsigned &Idx); + + /// Reads one attribute from the current stream position. + Attr *ReadAttr(ModuleFile &M, const RecordData &Record, unsigned &Idx); + + /// Reads attributes from the current stream position. + void ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs); + + /// Reads a statement. + Stmt *ReadStmt(ModuleFile &F); + + /// Reads an expression. + Expr *ReadExpr(ModuleFile &F); + + /// Reads a sub-statement operand during statement reading. + Stmt *ReadSubStmt() { + assert(ReadingKind == Read_Stmt && + "Should be called only during statement reading!"); + // Subexpressions are stored from last to first, so the next Stmt we need + // is at the back of the stack. + assert(!StmtStack.empty() && "Read too many sub-statements!"); + return StmtStack.pop_back_val(); + } + + /// Reads a sub-expression operand during statement reading. + Expr *ReadSubExpr(); + + /// Reads a token out of a record. + Token ReadToken(ModuleFile &M, const RecordDataImpl &Record, unsigned &Idx); + + /// Reads the macro record located at the given offset. + MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset); + + /// Determine the global preprocessed entity ID that corresponds to + /// the given local ID within the given module. + serialization::PreprocessedEntityID + getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const; + + /// Add a macro to deserialize its macro directive history. + /// + /// \param II The name of the macro. + /// \param M The module file. + /// \param MacroDirectivesOffset Offset of the serialized macro directive + /// history. + void addPendingMacro(IdentifierInfo *II, ModuleFile *M, + uint64_t MacroDirectivesOffset); + + /// Read the set of macros defined by this external macro source. + void ReadDefinedMacros() override; + + /// Update an out-of-date identifier. + void updateOutOfDateIdentifier(IdentifierInfo &II) override; + + /// Note that this identifier is up-to-date. + void markIdentifierUpToDate(IdentifierInfo *II); + + /// Load all external visible decls in the given DeclContext. + void completeVisibleDeclsMap(const DeclContext *DC) override; + + /// Retrieve the AST context that this AST reader supplements. + ASTContext &getContext() { + assert(ContextObj && "requested AST context when not loading AST"); + return *ContextObj; + } + + // Contains the IDs for declarations that were requested before we have + // access to a Sema object. + SmallVector<uint64_t, 16> PreloadedDeclIDs; + + /// Retrieve the semantic analysis object used to analyze the + /// translation unit in which the precompiled header is being + /// imported. + Sema *getSema() { return SemaObj; } + + /// Get the identifier resolver used for name lookup / updates + /// in the translation unit scope. We have one of these even if we don't + /// have a Sema object. + IdentifierResolver &getIdResolver(); + + /// Retrieve the identifier table associated with the + /// preprocessor. + IdentifierTable &getIdentifierTable(); + + /// Record that the given ID maps to the given switch-case + /// statement. + void RecordSwitchCaseID(SwitchCase *SC, unsigned ID); + + /// Retrieve the switch-case statement with the given ID. + SwitchCase *getSwitchCaseWithID(unsigned ID); + + void ClearSwitchCaseIDs(); + + /// Cursors for comments blocks. + SmallVector<std::pair<llvm::BitstreamCursor, + serialization::ModuleFile *>, 8> CommentsCursors; + + /// Loads comments ranges. + void ReadComments() override; + + /// Visit all the input files of the given module file. + void visitInputFiles(serialization::ModuleFile &MF, + bool IncludeSystem, bool Complain, + llvm::function_ref<void(const serialization::InputFile &IF, + bool isSystem)> Visitor); + + /// 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); + + bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; } +}; + +/// An object for streaming information from a record. +class ASTRecordReader { + using ModuleFile = serialization::ModuleFile; + + ASTReader *Reader; + ModuleFile *F; + unsigned Idx = 0; + ASTReader::RecordData Record; + + using RecordData = ASTReader::RecordData; + using RecordDataImpl = ASTReader::RecordDataImpl; + +public: + /// Construct an ASTRecordReader that uses the default encoding scheme. + ASTRecordReader(ASTReader &Reader, ModuleFile &F) : Reader(&Reader), F(&F) {} + + /// Reads a record with id AbbrevID from Cursor, resetting the + /// internal state. + unsigned readRecord(llvm::BitstreamCursor &Cursor, unsigned AbbrevID); + + /// Is this a module file for a module (rather than a PCH or similar). + bool isModule() const { return F->isModule(); } + + /// Retrieve the AST context that this AST reader supplements. + ASTContext &getContext() { return Reader->getContext(); } + + /// The current position in this record. + unsigned getIdx() const { return Idx; } + + /// The length of this record. + size_t size() const { return Record.size(); } + + /// An arbitrary index in this record. + const uint64_t &operator[](size_t N) { return Record[N]; } + + /// The last element in this record. + const uint64_t &back() const { return Record.back(); } + + /// Returns the current value in this record, and advances to the + /// next value. + const uint64_t &readInt() { return Record[Idx++]; } + + /// Returns the current value in this record, without advancing. + const uint64_t &peekInt() { return Record[Idx]; } + + /// Skips the specified number of values. + void skipInts(unsigned N) { Idx += N; } + + /// Retrieve the global submodule ID its local ID number. + serialization::SubmoduleID + getGlobalSubmoduleID(unsigned LocalID) { + return Reader->getGlobalSubmoduleID(*F, LocalID); + } + + /// Retrieve the submodule that corresponds to a global submodule ID. + Module *getSubmodule(serialization::SubmoduleID GlobalID) { + return Reader->getSubmodule(GlobalID); + } + + /// Read the record that describes the lexical contents of a DC. + bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) { + return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset, + DC); + } + + /// Read the record that describes the visible contents of a DC. + bool readVisibleDeclContextStorage(uint64_t Offset, + serialization::DeclID ID) { + return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset, + ID); + } + + void readExceptionSpec(SmallVectorImpl<QualType> &ExceptionStorage, + FunctionProtoType::ExceptionSpecInfo &ESI) { + return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, Record, Idx); + } + + /// Get the global offset corresponding to a local offset. + uint64_t getGlobalBitOffset(uint32_t LocalOffset) { + return Reader->getGlobalBitOffset(*F, LocalOffset); + } + + /// Reads a statement. + Stmt *readStmt() { return Reader->ReadStmt(*F); } + + /// Reads an expression. + Expr *readExpr() { return Reader->ReadExpr(*F); } + + /// Reads a sub-statement operand during statement reading. + Stmt *readSubStmt() { return Reader->ReadSubStmt(); } + + /// Reads a sub-expression operand during statement reading. + Expr *readSubExpr() { return Reader->ReadSubExpr(); } + + /// Reads a declaration with the given local ID in the given module. + /// + /// \returns The requested declaration, casted to the given return type. + template<typename T> + T *GetLocalDeclAs(uint32_t LocalID) { + return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); + } + + /// Reads a TemplateArgumentLocInfo appropriate for the + /// given TemplateArgument kind, advancing Idx. + TemplateArgumentLocInfo + getTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) { + return Reader->GetTemplateArgumentLocInfo(*F, Kind, Record, Idx); + } + + /// Reads a TemplateArgumentLoc, advancing Idx. + TemplateArgumentLoc + readTemplateArgumentLoc() { + return Reader->ReadTemplateArgumentLoc(*F, Record, Idx); + } + + const ASTTemplateArgumentListInfo* + readASTTemplateArgumentListInfo() { + return Reader->ReadASTTemplateArgumentListInfo(*F, Record, Idx); + } + + /// Reads a declarator info from the given record, advancing Idx. + TypeSourceInfo *getTypeSourceInfo() { + return Reader->GetTypeSourceInfo(*F, Record, Idx); + } + + /// Reads the location information for a type. + void readTypeLoc(TypeLoc TL) { + return Reader->ReadTypeLoc(*F, Record, Idx, TL); + } + + /// Map a local type ID within a given AST file to a global type ID. + serialization::TypeID getGlobalTypeID(unsigned LocalID) const { + return Reader->getGlobalTypeID(*F, LocalID); + } + + /// Read a type from the current position in the record. + QualType readType() { + return Reader->readType(*F, Record, Idx); + } + + /// Reads a declaration ID from the given position in this record. + /// + /// \returns The declaration ID read from the record, adjusted to a global ID. + serialization::DeclID readDeclID() { + return Reader->ReadDeclID(*F, Record, Idx); + } + + /// Reads a declaration from the given position in a record in the + /// given module, advancing Idx. + Decl *readDecl() { + return Reader->ReadDecl(*F, Record, Idx); + } + + /// Reads a declaration from the given position in the record, + /// advancing Idx. + /// + /// \returns The declaration read from this location, casted to the given + /// result type. + template<typename T> + T *readDeclAs() { + return Reader->ReadDeclAs<T>(*F, Record, Idx); + } + + IdentifierInfo *getIdentifierInfo() { + return Reader->GetIdentifierInfo(*F, Record, Idx); + } + + /// Read a selector from the Record, advancing Idx. + Selector readSelector() { + return Reader->ReadSelector(*F, Record, Idx); + } + + /// Read a declaration name, advancing Idx. + DeclarationName readDeclarationName() { + return Reader->ReadDeclarationName(*F, Record, Idx); + } + void readDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) { + return Reader->ReadDeclarationNameLoc(*F, DNLoc, Name, Record, Idx); + } + void readDeclarationNameInfo(DeclarationNameInfo &NameInfo) { + return Reader->ReadDeclarationNameInfo(*F, NameInfo, Record, Idx); + } + + void readQualifierInfo(QualifierInfo &Info) { + return Reader->ReadQualifierInfo(*F, Info, Record, Idx); + } + + NestedNameSpecifier *readNestedNameSpecifier() { + return Reader->ReadNestedNameSpecifier(*F, Record, Idx); + } + + NestedNameSpecifierLoc readNestedNameSpecifierLoc() { + return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx); + } + + /// Read a template name, advancing Idx. + TemplateName readTemplateName() { + return Reader->ReadTemplateName(*F, Record, Idx); + } + + /// Read a template argument, advancing Idx. + TemplateArgument readTemplateArgument(bool Canonicalize = false) { + return Reader->ReadTemplateArgument(*F, Record, Idx, Canonicalize); + } + + /// Read a template parameter list, advancing Idx. + TemplateParameterList *readTemplateParameterList() { + return Reader->ReadTemplateParameterList(*F, Record, Idx); + } + + /// Read a template argument array, advancing Idx. + void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, + bool Canonicalize = false) { + return Reader->ReadTemplateArgumentList(TemplArgs, *F, Record, Idx, + Canonicalize); + } + + /// Read a UnresolvedSet structure, advancing Idx. + void readUnresolvedSet(LazyASTUnresolvedSet &Set) { + return Reader->ReadUnresolvedSet(*F, Set, Record, Idx); + } + + /// Read a C++ base specifier, advancing Idx. + CXXBaseSpecifier readCXXBaseSpecifier() { + return Reader->ReadCXXBaseSpecifier(*F, Record, Idx); + } + + /// Read a CXXCtorInitializer array, advancing Idx. + CXXCtorInitializer **readCXXCtorInitializers() { + return Reader->ReadCXXCtorInitializers(*F, Record, Idx); + } + + CXXTemporary *readCXXTemporary() { + return Reader->ReadCXXTemporary(*F, Record, Idx); + } + + /// Read a source location, advancing Idx. + SourceLocation readSourceLocation() { + return Reader->ReadSourceLocation(*F, Record, Idx); + } + + /// Read a source range, advancing Idx. + SourceRange readSourceRange() { + return Reader->ReadSourceRange(*F, Record, Idx); + } + + /// Read an integral value, advancing Idx. + llvm::APInt readAPInt() { + return Reader->ReadAPInt(Record, Idx); + } + + /// Read a signed integral value, advancing Idx. + llvm::APSInt readAPSInt() { + return Reader->ReadAPSInt(Record, Idx); + } + + /// Read a floating-point value, advancing Idx. + llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem) { + return Reader->ReadAPFloat(Record, Sem,Idx); + } + + /// Read a string, advancing Idx. + std::string readString() { + return Reader->ReadString(Record, Idx); + } + + /// Read a path, advancing Idx. + std::string readPath() { + return Reader->ReadPath(*F, Record, Idx); + } + + /// Read a version tuple, advancing Idx. + VersionTuple readVersionTuple() { + return ASTReader::ReadVersionTuple(Record, Idx); + } + + /// Reads one attribute from the current stream position, advancing Idx. + Attr *readAttr() { + return Reader->ReadAttr(*F, Record, Idx); + } + + /// Reads attributes from the current stream position, advancing Idx. + void readAttributes(AttrVec &Attrs) { + return Reader->ReadAttributes(*this, Attrs); + } + + /// Reads a token out of a record, advancing Idx. + Token readToken() { + return Reader->ReadToken(*F, Record, Idx); + } + + void recordSwitchCaseID(SwitchCase *SC, unsigned ID) { + Reader->RecordSwitchCaseID(SC, ID); + } + + /// Retrieve the switch-case statement with the given ID. + SwitchCase *getSwitchCaseWithID(unsigned ID) { + return Reader->getSwitchCaseWithID(ID); + } +}; + +/// Helper class that saves the current stream position and +/// then restores it when destroyed. +struct SavedStreamPosition { + explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) + : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} + + ~SavedStreamPosition() { + Cursor.JumpToBit(Offset); + } + +private: + llvm::BitstreamCursor &Cursor; + uint64_t Offset; +}; + +inline void PCHValidator::Error(const char *Msg) { + Reader.Error(Msg); +} + +class OMPClauseReader : public OMPClauseVisitor<OMPClauseReader> { + ASTRecordReader &Record; + ASTContext &Context; + +public: + OMPClauseReader(ASTRecordReader &Record) + : Record(Record), Context(Record.getContext()) {} + +#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C); + OPENMP_CLAUSE(flush, OMPFlushClause) +#include "clang/Basic/OpenMPKinds.def" + OMPClause *readClause(); + void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); + void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); +}; + +} // namespace clang + +#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H diff --git a/clang-r353983/include/clang/Serialization/ASTWriter.h b/clang-r353983/include/clang/Serialization/ASTWriter.h new file mode 100644 index 00000000..2d12f6ae --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ASTWriter.h @@ -0,0 +1,1011 @@ +//===- ASTWriter.h - AST File Writer ----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTWriter class, which writes an AST file +// containing a serialized representation of a translation unit. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H +#define LLVM_CLANG_SERIALIZATION_ASTWRITER_H + +#include "clang/AST/ASTMutationListener.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclarationName.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Sema/SemaConsumer.h" +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ASTDeserializationListener.h" +#include "clang/Serialization/PCHContainerOperations.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <ctime> +#include <memory> +#include <queue> +#include <string> +#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 FunctionDecl; +class HeaderSearch; +class HeaderSearchOptions; +class IdentifierResolver; +class LangOptions; +class MacroDefinitionRecord; +class MacroInfo; +class MemoryBufferCache; +class Module; +class ModuleFileExtension; +class ModuleFileExtensionWriter; +class NamedDecl; +class NestedNameSpecifier; +class ObjCInterfaceDecl; +class PreprocessingRecord; +class Preprocessor; +struct QualifierInfo; +class RecordDecl; +class Sema; +class SourceManager; +class Stmt; +struct StoredDeclsList; +class SwitchCase; +class TemplateParameterList; +class Token; +class TypeSourceInfo; + +/// Writes an AST file containing the contents of a translation unit. +/// +/// The ASTWriter class produces a bitstream containing the serialized +/// representation of a given abstract syntax tree and its supporting +/// data structures. This bitstream can be de-serialized via an +/// instance of the ASTReader class. +class ASTWriter : public ASTDeserializationListener, + public ASTMutationListener { +public: + friend class ASTDeclWriter; + friend class ASTRecordWriter; + friend class ASTStmtWriter; + friend class ASTTypeWriter; + + using RecordData = SmallVector<uint64_t, 64>; + using RecordDataImpl = SmallVectorImpl<uint64_t>; + using RecordDataRef = ArrayRef<uint64_t>; + +private: + /// Map that provides the ID numbers of each type within the + /// output stream, plus those deserialized from a chained PCH. + /// + /// The ID numbers of types are consecutive (in order of discovery) + /// and start at 1. 0 is reserved for NULL. When types are actually + /// stored in the stream, the ID number is shifted by 2 bits to + /// allow for the const/volatile qualifiers. + /// + /// Keys in the map never have const/volatile qualifiers. + using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx, + serialization::UnsafeQualTypeDenseMapInfo>; + + /// The bitstream writer used to emit this precompiled header. + llvm::BitstreamWriter &Stream; + + /// The buffer associated with the bitstream. + const SmallVectorImpl<char> &Buffer; + + /// The PCM manager which manages memory buffers for pcm files. + MemoryBufferCache &PCMCache; + + /// The ASTContext we're writing. + ASTContext *Context = nullptr; + + /// The preprocessor we're writing. + Preprocessor *PP = nullptr; + + /// The reader of existing AST files, if we're chaining. + ASTReader *Chain = nullptr; + + /// The module we're currently writing, if any. + Module *WritingModule = nullptr; + + /// The base directory for any relative paths we emit. + std::string BaseDirectory; + + /// Indicates whether timestamps should be written to the produced + /// module file. This is the case for files implicitly written to the + /// module cache, where we need the timestamps to determine if the module + /// file is up to date, but not otherwise. + bool IncludeTimestamps; + + /// Indicates when the AST writing is actively performing + /// serialization, rather than just queueing updates. + bool WritingAST = false; + + /// Indicates that we are done serializing the collection of decls + /// and types to emit. + bool DoneWritingDeclsAndTypes = false; + + /// Indicates that the AST contained compiler errors. + bool ASTHasCompilerErrors = false; + + /// Mapping from input file entries to the index into the + /// offset table where information about that input file is stored. + llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs; + + /// Stores a declaration or a type to be written to the AST file. + class DeclOrType { + public: + DeclOrType(Decl *D) : Stored(D), IsType(false) {} + DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) {} + + bool isType() const { return IsType; } + bool isDecl() const { return !IsType; } + + QualType getType() const { + assert(isType() && "Not a type!"); + return QualType::getFromOpaquePtr(Stored); + } + + Decl *getDecl() const { + assert(isDecl() && "Not a decl!"); + return static_cast<Decl *>(Stored); + } + + private: + void *Stored; + bool IsType; + }; + + /// The declarations and types to emit. + std::queue<DeclOrType> DeclTypesToEmit; + + /// The first ID number we can use for our own declarations. + serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS; + + /// The decl ID that will be assigned to the next new decl. + serialization::DeclID NextDeclID = FirstDeclID; + + /// Map that provides the ID numbers of each declaration within + /// the output stream, as well as those deserialized from a chained PCH. + /// + /// The ID numbers of declarations are consecutive (in order of + /// discovery) and start at 2. 1 is reserved for the translation + /// unit, while 0 is reserved for NULL. + llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs; + + /// Offset of each declaration in the bitstream, indexed by + /// the declaration's ID. + std::vector<serialization::DeclOffset> DeclOffsets; + + /// Sorted (by file offset) vector of pairs of file offset/DeclID. + using LocDeclIDsTy = + SmallVector<std::pair<unsigned, serialization::DeclID>, 64>; + struct DeclIDInFileInfo { + LocDeclIDsTy DeclIDs; + + /// Set when the DeclIDs vectors from all files are joined, this + /// indicates the index that this particular vector has in the global one. + unsigned FirstDeclIndex; + }; + using FileDeclIDsTy = llvm::DenseMap<FileID, DeclIDInFileInfo *>; + + /// Map from file SLocEntries to info about the file-level declarations + /// that it contains. + FileDeclIDsTy FileDeclIDs; + + void associateDeclWithFile(const Decl *D, serialization::DeclID); + + /// The first ID number we can use for our own types. + serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; + + /// The type ID that will be assigned to the next new type. + serialization::TypeID NextTypeID = FirstTypeID; + + /// Map that provides the ID numbers of each type within the + /// output stream, plus those deserialized from a chained PCH. + /// + /// The ID numbers of types are consecutive (in order of discovery) + /// and start at 1. 0 is reserved for NULL. When types are actually + /// stored in the stream, the ID number is shifted by 2 bits to + /// allow for the const/volatile qualifiers. + /// + /// Keys in the map never have const/volatile qualifiers. + TypeIdxMap TypeIdxs; + + /// Offset of each type in the bitstream, indexed by + /// the type's ID. + std::vector<uint32_t> TypeOffsets; + + /// The first ID number we can use for our own identifiers. + serialization::IdentID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS; + + /// The identifier ID that will be assigned to the next new identifier. + serialization::IdentID NextIdentID = FirstIdentID; + + /// Map that provides the ID numbers of each identifier in + /// the output stream. + /// + /// The ID numbers for identifiers are consecutive (in order of + /// discovery), starting at 1. An ID of zero refers to a NULL + /// IdentifierInfo. + llvm::MapVector<const IdentifierInfo *, serialization::IdentID> IdentifierIDs; + + /// The first ID number we can use for our own macros. + serialization::MacroID FirstMacroID = serialization::NUM_PREDEF_MACRO_IDS; + + /// The identifier ID that will be assigned to the next new identifier. + serialization::MacroID NextMacroID = FirstMacroID; + + /// Map that provides the ID numbers of each macro. + llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs; + + struct MacroInfoToEmitData { + const IdentifierInfo *Name; + MacroInfo *MI; + serialization::MacroID ID; + }; + + /// The macro infos to emit. + std::vector<MacroInfoToEmitData> MacroInfosToEmit; + + llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap; + + /// @name FlushStmt Caches + /// @{ + + /// Set of parent Stmts for the currently serializing sub-stmt. + llvm::DenseSet<Stmt *> ParentStmts; + + /// Offsets of sub-stmts already serialized. The offset points + /// just after the stmt record. + llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries; + + /// @} + + /// Offsets of each of the identifier IDs into the identifier + /// table. + std::vector<uint32_t> IdentifierOffsets; + + /// The first ID number we can use for our own submodules. + serialization::SubmoduleID FirstSubmoduleID = + serialization::NUM_PREDEF_SUBMODULE_IDS; + + /// The submodule ID that will be assigned to the next new submodule. + serialization::SubmoduleID NextSubmoduleID = FirstSubmoduleID; + + /// The first ID number we can use for our own selectors. + serialization::SelectorID FirstSelectorID = + serialization::NUM_PREDEF_SELECTOR_IDS; + + /// The selector ID that will be assigned to the next new selector. + serialization::SelectorID NextSelectorID = FirstSelectorID; + + /// Map that provides the ID numbers of each Selector. + llvm::MapVector<Selector, serialization::SelectorID> SelectorIDs; + + /// Offset of each selector within the method pool/selector + /// table, indexed by the Selector ID (-1). + std::vector<uint32_t> SelectorOffsets; + + /// Mapping from macro definitions (as they occur in the preprocessing + /// record) to the macro IDs. + llvm::DenseMap<const MacroDefinitionRecord *, + serialization::PreprocessedEntityID> MacroDefinitions; + + /// Cache of indices of anonymous declarations within their lexical + /// contexts. + llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers; + + /// An update to a Decl. + class DeclUpdate { + /// A DeclUpdateKind. + unsigned Kind; + union { + const Decl *Dcl; + void *Type; + unsigned Loc; + unsigned Val; + Module *Mod; + const Attr *Attribute; + }; + + public: + DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {} + DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {} + DeclUpdate(unsigned Kind, QualType Type) + : Kind(Kind), Type(Type.getAsOpaquePtr()) {} + DeclUpdate(unsigned Kind, SourceLocation Loc) + : Kind(Kind), Loc(Loc.getRawEncoding()) {} + DeclUpdate(unsigned Kind, unsigned Val) : Kind(Kind), Val(Val) {} + DeclUpdate(unsigned Kind, Module *M) : Kind(Kind), Mod(M) {} + DeclUpdate(unsigned Kind, const Attr *Attribute) + : Kind(Kind), Attribute(Attribute) {} + + unsigned getKind() const { return Kind; } + const Decl *getDecl() const { return Dcl; } + QualType getType() const { return QualType::getFromOpaquePtr(Type); } + + SourceLocation getLoc() const { + return SourceLocation::getFromRawEncoding(Loc); + } + + unsigned getNumber() const { return Val; } + Module *getModule() const { return Mod; } + const Attr *getAttr() const { return Attribute; } + }; + + using UpdateRecord = SmallVector<DeclUpdate, 1>; + using DeclUpdateMap = llvm::MapVector<const Decl *, UpdateRecord>; + + /// Mapping from declarations that came from a chained PCH to the + /// record containing modifications to them. + DeclUpdateMap DeclUpdates; + + using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>; + + /// Map of first declarations from a chained PCH that point to the + /// most recent declarations in another PCH. + FirstLatestDeclMap FirstLatestDecls; + + /// Declarations encountered that might be external + /// definitions. + /// + /// We keep track of external definitions and other 'interesting' declarations + /// as we are emitting declarations to the AST file. The AST file contains a + /// separate record for these declarations, which are provided to the AST + /// consumer by the AST reader. This is behavior is required to properly cope with, + /// e.g., tentative variable definitions that occur within + /// headers. The declarations themselves are stored as declaration + /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS + /// record. + SmallVector<uint64_t, 16> EagerlyDeserializedDecls; + SmallVector<uint64_t, 16> ModularCodegenDecls; + + /// DeclContexts that have received extensions since their serialized + /// form. + /// + /// For namespaces, when we're chaining and encountering a namespace, we check + /// if its primary namespace comes from the chain. If it does, we add the + /// primary to this set, so that we can write out lexical content updates for + /// it. + llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts; + + /// Keeps track of declarations that we must emit, even though we're + /// not guaranteed to be able to find them by walking the AST starting at the + /// translation unit. + SmallVector<const Decl *, 16> DeclsToEmitEvenIfUnreferenced; + + /// The set of Objective-C class that have categories we + /// should serialize. + llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories; + + /// The set of declarations that may have redeclaration chains that + /// need to be serialized. + llvm::SmallVector<const Decl *, 16> Redeclarations; + + /// A cache of the first local declaration for "interesting" + /// redeclaration chains. + llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache; + + /// Mapping from SwitchCase statements to IDs. + llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs; + + /// The number of statements written to the AST file. + unsigned NumStatements = 0; + + /// The number of macros written to the AST file. + unsigned NumMacros = 0; + + /// The number of lexical declcontexts written to the AST + /// file. + unsigned NumLexicalDeclContexts = 0; + + /// The number of visible declcontexts written to the AST + /// file. + unsigned NumVisibleDeclContexts = 0; + + /// A mapping from each known submodule to its ID number, which will + /// be a positive integer. + llvm::DenseMap<Module *, unsigned> SubmoduleIDs; + + /// A list of the module file extension writers. + std::vector<std::unique_ptr<ModuleFileExtensionWriter>> + ModuleFileExtensionWriters; + + /// Retrieve or create a submodule ID for this module. + unsigned getSubmoduleID(Module *Mod); + + /// Write the given subexpression to the bitstream. + void WriteSubStmt(Stmt *S); + + void WriteBlockInfoBlock(); + void WriteControlBlock(Preprocessor &PP, ASTContext &Context, + StringRef isysroot, const std::string &OutputFile); + + /// Write out the signature and diagnostic options, and return the signature. + ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP, + ASTContext &Context); + + /// Calculate hash of the pcm content. + static ASTFileSignature createSignature(StringRef Bytes); + + void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, + bool Modules); + void WriteSourceManagerBlock(SourceManager &SourceMgr, + const Preprocessor &PP); + void WritePreprocessor(const Preprocessor &PP, bool IsModule); + void WriteHeaderSearch(const HeaderSearch &HS); + void WritePreprocessorDetail(PreprocessingRecord &PPRec); + void WriteSubmodules(Module *WritingModule); + + void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, + bool isModule); + + unsigned TypeExtQualAbbrev = 0; + unsigned TypeFunctionProtoAbbrev = 0; + void WriteTypeAbbrevs(); + void WriteType(QualType T); + + bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC); + bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC); + + void GenerateNameLookupTable(const DeclContext *DC, + llvm::SmallVectorImpl<char> &LookupTable); + uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); + uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); + void WriteTypeDeclOffsets(); + void WriteFileDeclIDsMap(); + void WriteComments(); + void WriteSelectors(Sema &SemaRef); + void WriteReferencedSelectorsPool(Sema &SemaRef); + void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, + bool IsModule); + void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord); + void WriteDeclContextVisibleUpdate(const DeclContext *DC); + void WriteFPPragmaOptions(const FPOptions &Opts); + void WriteOpenCLExtensions(Sema &SemaRef); + void WriteOpenCLExtensionTypes(Sema &SemaRef); + void WriteOpenCLExtensionDecls(Sema &SemaRef); + void WriteCUDAPragmas(Sema &SemaRef); + void WriteObjCCategories(); + void WriteLateParsedTemplates(Sema &SemaRef); + void WriteOptimizePragmaOptions(Sema &SemaRef); + void WriteMSStructPragmaOptions(Sema &SemaRef); + void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef); + void WritePackPragmaOptions(Sema &SemaRef); + void WriteModuleFileExtension(Sema &SemaRef, + ModuleFileExtensionWriter &Writer); + + unsigned DeclParmVarAbbrev = 0; + unsigned DeclContextLexicalAbbrev = 0; + unsigned DeclContextVisibleLookupAbbrev = 0; + unsigned UpdateVisibleAbbrev = 0; + unsigned DeclRecordAbbrev = 0; + unsigned DeclTypedefAbbrev = 0; + unsigned DeclVarAbbrev = 0; + unsigned DeclFieldAbbrev = 0; + unsigned DeclEnumAbbrev = 0; + unsigned DeclObjCIvarAbbrev = 0; + unsigned DeclCXXMethodAbbrev = 0; + + unsigned DeclRefExprAbbrev = 0; + unsigned CharacterLiteralAbbrev = 0; + unsigned IntegerLiteralAbbrev = 0; + unsigned ExprImplicitCastAbbrev = 0; + + void WriteDeclAbbrevs(); + void WriteDecl(ASTContext &Context, Decl *D); + + ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot, + const std::string &OutputFile, + Module *WritingModule); + +public: + /// Create a new precompiled header writer that outputs to + /// the given bitstream. + ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer, + MemoryBufferCache &PCMCache, + ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + bool IncludeTimestamps = true); + ~ASTWriter() override; + + const LangOptions &getLangOpts() const; + + /// Get a timestamp for output into the AST file. The actual timestamp + /// of the specified file may be ignored if we have been instructed to not + /// include timestamps in the output file. + time_t getTimestampForOutput(const FileEntry *E) const; + + /// Write a precompiled header for the given semantic analysis. + /// + /// \param SemaRef a reference to the semantic analysis object that processed + /// the AST to be written into the precompiled header. + /// + /// \param WritingModule The module that we are writing. If null, we are + /// writing a precompiled header. + /// + /// \param isysroot if non-empty, write a relocatable file whose headers + /// are relative to the given system root. If we're writing a module, its + /// build directory will be used in preference to this if both are available. + /// + /// \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, + Module *WritingModule, StringRef isysroot, + bool hasErrors = false); + + /// Emit a token. + void AddToken(const Token &Tok, RecordDataImpl &Record); + + /// Emit a source location. + void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record); + + /// Emit a source range. + void AddSourceRange(SourceRange Range, RecordDataImpl &Record); + + /// Emit a reference to an identifier. + void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); + + /// Get the unique number used to refer to the given selector. + serialization::SelectorID getSelectorRef(Selector Sel); + + /// Get the unique number used to refer to the given identifier. + serialization::IdentID getIdentifierRef(const IdentifierInfo *II); + + /// Get the unique number used to refer to the given macro. + serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name); + + /// Determine the ID of an already-emitted macro. + serialization::MacroID getMacroID(MacroInfo *MI); + + uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name); + + /// Emit a reference to a type. + void AddTypeRef(QualType T, RecordDataImpl &Record); + + /// Force a type to be emitted and get its ID. + serialization::TypeID GetOrCreateTypeID(QualType T); + + /// Determine the type ID of an already-emitted type. + serialization::TypeID getTypeID(QualType T) const; + + /// Find the first local declaration of a given local redeclarable + /// decl. + const Decl *getFirstLocalDecl(const Decl *D); + + /// Is this a local declaration (that is, one that will be written to + /// our AST file)? This is the case for declarations that are neither imported + /// from another AST file nor predefined. + bool IsLocalDecl(const Decl *D) { + if (D->isFromASTFile()) + return false; + auto I = DeclIDs.find(D); + return (I == DeclIDs.end() || + I->second >= serialization::NUM_PREDEF_DECL_IDS); + }; + + /// Emit a reference to a declaration. + void AddDeclRef(const Decl *D, RecordDataImpl &Record); + + /// Force a declaration to be emitted and get its ID. + serialization::DeclID GetDeclRef(const Decl *D); + + /// Determine the declaration ID of an already-emitted + /// declaration. + serialization::DeclID getDeclID(const Decl *D); + + unsigned getAnonymousDeclarationNumber(const NamedDecl *D); + + /// Add a string to the given record. + void AddString(StringRef Str, RecordDataImpl &Record); + + /// Convert a path from this build process into one that is appropriate + /// for emission in the module file. + bool PreparePathForOutput(SmallVectorImpl<char> &Path); + + /// Add a path to the given record. + void AddPath(StringRef Path, RecordDataImpl &Record); + + /// Emit the current record with the given path as a blob. + void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record, + StringRef Path); + + /// Add a version tuple to the given record + void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record); + + /// Retrieve or create a submodule ID for this module, or return 0 if + /// the submodule is neither local (a submodle of the currently-written module) + /// nor from an imported module. + unsigned getLocalOrImportedSubmoduleID(Module *Mod); + + /// Note that the identifier II occurs at the given offset + /// within the identifier table. + void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset); + + /// Note that the selector Sel occurs at the given offset + /// within the method pool/selector table. + void SetSelectorOffset(Selector Sel, uint32_t Offset); + + /// Record an ID for the given switch-case statement. + unsigned RecordSwitchCaseID(SwitchCase *S); + + /// Retrieve the ID for the given switch-case statement. + unsigned getSwitchCaseID(SwitchCase *S); + + void ClearSwitchCaseIDs(); + + unsigned getTypeExtQualAbbrev() const { + return TypeExtQualAbbrev; + } + + unsigned getTypeFunctionProtoAbbrev() const { + return TypeFunctionProtoAbbrev; + } + + unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; } + unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; } + unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; } + unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; } + unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; } + unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; } + unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; } + unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; } + + unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; } + unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; } + unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; } + unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; } + + bool hasChain() const { return Chain; } + ASTReader *getChain() const { return Chain; } + +private: + // ASTDeserializationListener implementation + void ReaderInitialized(ASTReader *Reader) override; + void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; + void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; + void TypeRead(serialization::TypeIdx Idx, QualType T) override; + void SelectorRead(serialization::SelectorID ID, Selector Sel) override; + void MacroDefinitionRead(serialization::PreprocessedEntityID ID, + MacroDefinitionRecord *MD) override; + void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override; + + // ASTMutationListener implementation. + void CompletedTagDefinition(const TagDecl *D) override; + void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override; + void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override; + void AddedCXXTemplateSpecialization( + const ClassTemplateDecl *TD, + const ClassTemplateSpecializationDecl *D) override; + void AddedCXXTemplateSpecialization( + const VarTemplateDecl *TD, + const VarTemplateSpecializationDecl *D) override; + void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, + const FunctionDecl *D) override; + void ResolvedExceptionSpec(const FunctionDecl *FD) override; + void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; + void ResolvedOperatorDelete(const CXXDestructorDecl *DD, + const FunctionDecl *Delete, + Expr *ThisArg) override; + void CompletedImplicitDefinition(const FunctionDecl *D) override; + void InstantiationRequested(const ValueDecl *D) override; + void VariableDefinitionInstantiated(const VarDecl *D) override; + void FunctionDefinitionInstantiated(const FunctionDecl *D) override; + void DefaultArgumentInstantiated(const ParmVarDecl *D) override; + void DefaultMemberInitializerInstantiated(const FieldDecl *D) override; + void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, + const ObjCInterfaceDecl *IFD) override; + void DeclarationMarkedUsed(const Decl *D) override; + void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; + void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) override; + void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; + void AddedAttributeToRecord(const Attr *Attr, + const RecordDecl *Record) override; +}; + +/// An object for streaming information to a record. +class ASTRecordWriter { + ASTWriter *Writer; + ASTWriter::RecordDataImpl *Record; + + /// Statements that we've encountered while serializing a + /// declaration or type. + SmallVector<Stmt *, 16> StmtsToEmit; + + /// Indices of record elements that describe offsets within the + /// bitcode. These will be converted to offsets relative to the current + /// record when emitted. + SmallVector<unsigned, 8> OffsetIndices; + + /// Flush all of the statements and expressions that have + /// been added to the queue via AddStmt(). + void FlushStmts(); + void FlushSubStmts(); + + void PrepareToEmit(uint64_t MyOffset) { + // Convert offsets into relative form. + for (unsigned I : OffsetIndices) { + auto &StoredOffset = (*Record)[I]; + assert(StoredOffset < MyOffset && "invalid offset"); + if (StoredOffset) + StoredOffset = MyOffset - StoredOffset; + } + OffsetIndices.clear(); + } + +public: + /// Construct a ASTRecordWriter that uses the default encoding scheme. + ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) + : Writer(&Writer), Record(&Record) {} + + /// Construct a ASTRecordWriter that uses the same encoding scheme as another + /// ASTRecordWriter. + ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record) + : Writer(Parent.Writer), Record(&Record) {} + + /// Copying an ASTRecordWriter is almost certainly a bug. + ASTRecordWriter(const ASTRecordWriter &) = delete; + ASTRecordWriter &operator=(const ASTRecordWriter &) = delete; + + /// Extract the underlying record storage. + ASTWriter::RecordDataImpl &getRecordData() const { return *Record; } + + /// Minimal vector-like interface. + /// @{ + void push_back(uint64_t N) { Record->push_back(N); } + template<typename InputIterator> + void append(InputIterator begin, InputIterator end) { + Record->append(begin, end); + } + bool empty() const { return Record->empty(); } + size_t size() const { return Record->size(); } + uint64_t &operator[](size_t N) { return (*Record)[N]; } + /// @} + + /// Emit the record to the stream, followed by its substatements, and + /// return its offset. + // FIXME: Allow record producers to suggest Abbrevs. + uint64_t Emit(unsigned Code, unsigned Abbrev = 0) { + uint64_t Offset = Writer->Stream.GetCurrentBitNo(); + PrepareToEmit(Offset); + Writer->Stream.EmitRecord(Code, *Record, Abbrev); + FlushStmts(); + return Offset; + } + + /// Emit the record to the stream, preceded by its substatements. + uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) { + FlushSubStmts(); + PrepareToEmit(Writer->Stream.GetCurrentBitNo()); + Writer->Stream.EmitRecord(Code, *Record, Abbrev); + return Writer->Stream.GetCurrentBitNo(); + } + + /// Add a bit offset into the record. This will be converted into an + /// offset relative to the current record when emitted. + void AddOffset(uint64_t BitOffset) { + OffsetIndices.push_back(Record->size()); + Record->push_back(BitOffset); + } + + /// Add the given statement or expression to the queue of + /// statements to emit. + /// + /// This routine should be used when emitting types and declarations + /// that have expressions as part of their formulation. Once the + /// type or declaration has been written, Emit() will write + /// the corresponding statements just after the record. + void AddStmt(Stmt *S) { + StmtsToEmit.push_back(S); + } + + /// 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); + } + + /// Emit a source range. + void AddSourceRange(SourceRange Range) { + return Writer->AddSourceRange(Range, *Record); + } + + /// Emit an integral value. + void AddAPInt(const llvm::APInt &Value); + + /// Emit a signed integral value. + void AddAPSInt(const llvm::APSInt &Value); + + /// Emit a floating-point value. + void AddAPFloat(const llvm::APFloat &Value); + + /// Emit a reference to an identifier. + void AddIdentifierRef(const IdentifierInfo *II) { + return Writer->AddIdentifierRef(II, *Record); + } + + /// Emit a Selector (which is a smart pointer reference). + void AddSelectorRef(Selector S); + + /// Emit a CXXTemporary. + void AddCXXTemporary(const CXXTemporary *Temp); + + /// Emit a C++ base specifier. + void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base); + + /// Emit a set of C++ base specifiers. + void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases); + + /// Emit a reference to a type. + void AddTypeRef(QualType T) { + return Writer->AddTypeRef(T, *Record); + } + + /// Emits a reference to a declarator info. + void AddTypeSourceInfo(TypeSourceInfo *TInfo); + + /// Emits source location information for a type. Does not emit the type. + void AddTypeLoc(TypeLoc TL); + + /// Emits a template argument location info. + void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, + const TemplateArgumentLocInfo &Arg); + + /// Emits a template argument location. + void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg); + + /// Emits an AST template argument list info. + void AddASTTemplateArgumentListInfo( + const ASTTemplateArgumentListInfo *ASTTemplArgList); + + /// Emit a reference to a declaration. + void AddDeclRef(const Decl *D) { + return Writer->AddDeclRef(D, *Record); + } + + /// Emit a declaration name. + void AddDeclarationName(DeclarationName Name); + + void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, + DeclarationName Name); + void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo); + + void AddQualifierInfo(const QualifierInfo &Info); + + /// Emit a nested name specifier. + void AddNestedNameSpecifier(NestedNameSpecifier *NNS); + + /// Emit a nested name specifier with source-location information. + void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); + + /// Emit a template name. + void AddTemplateName(TemplateName Name); + + /// Emit a template argument. + void AddTemplateArgument(const TemplateArgument &Arg); + + /// Emit a template parameter list. + void AddTemplateParameterList(const TemplateParameterList *TemplateParams); + + /// Emit a template argument list. + void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs); + + /// Emit a UnresolvedSet structure. + void AddUnresolvedSet(const ASTUnresolvedSet &Set); + + /// Emit a CXXCtorInitializer array. + void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits); + + void AddCXXDefinitionData(const CXXRecordDecl *D); + + /// Emit a string. + void AddString(StringRef Str) { + return Writer->AddString(Str, *Record); + } + + /// Emit a path. + void AddPath(StringRef Path) { + return Writer->AddPath(Path, *Record); + } + + /// Emit a version tuple. + void AddVersionTuple(const VersionTuple &Version) { + return Writer->AddVersionTuple(Version, *Record); + } + + // Emit an attribute. + void AddAttr(const Attr *A); + + /// Emit a list of attributes. + void AddAttributes(ArrayRef<const Attr*> Attrs); +}; + +/// AST and semantic-analysis consumer that generates a +/// precompiled header from the parsed source code. +class PCHGenerator : public SemaConsumer { + const Preprocessor &PP; + std::string OutputFile; + std::string isysroot; + Sema *SemaPtr; + std::shared_ptr<PCHBuffer> Buffer; + llvm::BitstreamWriter Stream; + ASTWriter Writer; + bool AllowASTWithErrors; + +protected: + ASTWriter &getWriter() { return Writer; } + const ASTWriter &getWriter() const { return Writer; } + SmallVectorImpl<char> &getPCH() const { return Buffer->Data; } + +public: + PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, + std::shared_ptr<PCHBuffer> Buffer, + ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + bool AllowASTWithErrors = false, bool IncludeTimestamps = true); + ~PCHGenerator() override; + + void InitializeSema(Sema &S) override { SemaPtr = &S; } + void HandleTranslationUnit(ASTContext &Ctx) override; + ASTMutationListener *GetASTMutationListener() override; + ASTDeserializationListener *GetASTDeserializationListener() override; + bool hasEmittedPCH() const { return Buffer->IsComplete; } +}; + +class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> { + ASTRecordWriter &Record; + +public: + OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} +#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); + OPENMP_CLAUSE(flush, OMPFlushClause) +#include "clang/Basic/OpenMPKinds.def" + void writeClause(OMPClause *C); + void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); + void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); +}; + +} // namespace clang + +#endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H diff --git a/clang-r353983/include/clang/Serialization/AttrPCHRead.inc b/clang-r353983/include/clang/Serialization/AttrPCHRead.inc new file mode 100644 index 00000000..7c6f09ff --- /dev/null +++ b/clang-r353983/include/clang/Serialization/AttrPCHRead.inc @@ -0,0 +1,2701 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* Attribute deserialization code *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + + switch (Kind) { + case attr::AArch64VectorPcs: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AArch64VectorPcsAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AMDGPUFlatWorkGroupSize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned min = Record.readInt(); + unsigned max = Record.readInt(); + New = new (Context) AMDGPUFlatWorkGroupSizeAttr(Range, Context, min, max, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AMDGPUNumSGPR: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned numSGPR = Record.readInt(); + New = new (Context) AMDGPUNumSGPRAttr(Range, Context, numSGPR, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AMDGPUNumVGPR: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned numVGPR = Record.readInt(); + New = new (Context) AMDGPUNumVGPRAttr(Range, Context, numVGPR, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AMDGPUWavesPerEU: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned min = Record.readInt(); + unsigned max = Record.readInt(); + New = new (Context) AMDGPUWavesPerEUAttr(Range, Context, min, max, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ARMInterrupt: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ARMInterruptAttr::InterruptType interrupt(static_cast<ARMInterruptAttr::InterruptType>(Record.readInt())); + New = new (Context) ARMInterruptAttr(Range, Context, interrupt, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AVRInterrupt: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AVRInterruptAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AVRSignal: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AVRSignalAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AbiTag: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned tagsSize = Record.readInt(); + SmallVector<StringRef, 4> tags; + tags.reserve(tagsSize); + SmallVector<std::string, 4> tagsStorage; + tagsStorage.reserve(tagsSize); + for (unsigned i = 0; i != tagsSize; ++i) + tagsStorage.push_back(Record.readString()); + for (unsigned i = 0; i != tagsSize; ++i) + tags.push_back(tagsStorage[i]); + New = new (Context) AbiTagAttr(Range, Context, tags.data(), tagsSize, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::AcquireCapability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) AcquireCapabilityAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AcquiredAfter: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) AcquiredAfterAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AcquiredBefore: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) AcquiredBeforeAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AddressSpace: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + int addressSpace = Record.readInt(); + New = new (Context) AddressSpaceAttr(Range, Context, addressSpace, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::Alias: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string aliasee= Record.readString(); + New = new (Context) AliasAttr(Range, Context, aliasee, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::AlignMac68k: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AlignMac68kAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AlignValue: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * alignment = Record.readExpr(); + New = new (Context) AlignValueAttr(Range, Context, alignment, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::Aligned: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + bool isalignmentExpr = Record.readInt(); + void *alignmentPtr; + if (isalignmentExpr) + alignmentPtr = Record.readExpr(); + else + alignmentPtr = Record.getTypeSourceInfo(); + New = new (Context) AlignedAttr(Range, Context, isalignmentExpr, alignmentPtr, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AllocAlign: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ParamIdx paramIndex = ParamIdx::deserialize(Record.readInt()); + New = new (Context) AllocAlignAttr(Range, Context, paramIndex, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AllocSize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ParamIdx elemSizeParam = ParamIdx::deserialize(Record.readInt()); + ParamIdx numElemsParam = ParamIdx::deserialize(Record.readInt()); + New = new (Context) AllocSizeAttr(Range, Context, elemSizeParam, numElemsParam, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AlwaysDestroy: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AlwaysDestroyAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AlwaysInline: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AlwaysInlineAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AnalyzerNoReturn: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AnalyzerNoReturnAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Annotate: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string annotation= Record.readString(); + New = new (Context) AnnotateAttr(Range, Context, annotation, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AnyX86Interrupt: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AnyX86InterruptAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AnyX86NoCallerSavedRegisters: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AnyX86NoCallerSavedRegistersAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AnyX86NoCfCheck: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) AnyX86NoCfCheckAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ArcWeakrefUnavailable: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ArcWeakrefUnavailableAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ArgumentWithTypeTag: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * argumentKind = Record.getIdentifierInfo(); + ParamIdx argumentIdx = ParamIdx::deserialize(Record.readInt()); + ParamIdx typeTagIdx = ParamIdx::deserialize(Record.readInt()); + bool isPointer = Record.readInt(); + New = new (Context) ArgumentWithTypeTagAttr(Range, Context, argumentKind, argumentIdx, typeTagIdx, isPointer, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Artificial: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ArtificialAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AsmLabel: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string label= Record.readString(); + New = new (Context) AsmLabelAttr(Range, Context, label, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AssertCapability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) AssertCapabilityAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AssertExclusiveLock: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) AssertExclusiveLockAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AssertSharedLock: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) AssertSharedLockAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::AssumeAligned: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * alignment = Record.readExpr(); + Expr * offset = Record.readExpr(); + New = new (Context) AssumeAlignedAttr(Range, Context, alignment, offset, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Availability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * platform = Record.getIdentifierInfo(); + VersionTuple introduced= Record.readVersionTuple(); + VersionTuple deprecated= Record.readVersionTuple(); + VersionTuple obsoleted= Record.readVersionTuple(); + bool unavailable = Record.readInt(); + std::string message= Record.readString(); + bool strict = Record.readInt(); + std::string replacement= Record.readString(); + int priority = Record.readInt(); + New = new (Context) AvailabilityAttr(Range, Context, platform, introduced, deprecated, obsoleted, unavailable, message, strict, replacement, priority, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Blocks: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + BlocksAttr::BlockType type(static_cast<BlocksAttr::BlockType>(Record.readInt())); + New = new (Context) BlocksAttr(Range, Context, type, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::C11NoReturn: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) C11NoReturnAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CDecl: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CDeclAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CFAuditedTransfer: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CFAuditedTransferAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CFConsumed: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CFConsumedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CFReturnsNotRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CFReturnsNotRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CFReturnsRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CFReturnsRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CFUnknownTransfer: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CFUnknownTransferAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CPUDispatch: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned cpusSize = Record.readInt(); + SmallVector<IdentifierInfo *, 4> cpus; + cpus.reserve(cpusSize); + for (unsigned i = 0; i != cpusSize; ++i) + cpus.push_back(Record.getIdentifierInfo()); + New = new (Context) CPUDispatchAttr(Range, Context, cpus.data(), cpusSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CPUSpecific: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned cpusSize = Record.readInt(); + SmallVector<IdentifierInfo *, 4> cpus; + cpus.reserve(cpusSize); + for (unsigned i = 0; i != cpusSize; ++i) + cpus.push_back(Record.getIdentifierInfo()); + New = new (Context) CPUSpecificAttr(Range, Context, cpus.data(), cpusSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDAConstant: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CUDAConstantAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDADevice: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CUDADeviceAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDAGlobal: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CUDAGlobalAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDAHost: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CUDAHostAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDAInvalidTarget: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CUDAInvalidTargetAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDALaunchBounds: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * maxThreads = Record.readExpr(); + Expr * minBlocks = Record.readExpr(); + New = new (Context) CUDALaunchBoundsAttr(Range, Context, maxThreads, minBlocks, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CUDAShared: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CUDASharedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CXX11NoReturn: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CXX11NoReturnAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CallableWhen: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned callableStatesSize = Record.readInt(); + SmallVector<CallableWhenAttr::ConsumedState, 4> callableStates; + callableStates.reserve(callableStatesSize); + for (unsigned i = callableStatesSize; i; --i) + callableStates.push_back(static_cast<CallableWhenAttr::ConsumedState>(Record.readInt())); + New = new (Context) CallableWhenAttr(Range, Context, callableStates.data(), callableStatesSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Callback: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned encodingSize = Record.readInt(); + SmallVector<int, 4> encoding; + encoding.reserve(encodingSize); + for (unsigned i = 0; i != encodingSize; ++i) + encoding.push_back(Record.readInt()); + New = new (Context) CallbackAttr(Range, Context, encoding.data(), encodingSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Capability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) CapabilityAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CapturedRecord: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CapturedRecordAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CarriesDependency: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CarriesDependencyAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Cleanup: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + FunctionDecl * functionDecl = Record.GetLocalDeclAs<FunctionDecl >(Record.readInt()); + New = new (Context) CleanupAttr(Range, Context, functionDecl, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::CodeSeg: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) CodeSegAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Cold: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ColdAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Common: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) CommonAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Const: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ConstAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Constructor: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + int priority = Record.readInt(); + New = new (Context) ConstructorAttr(Range, Context, priority, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Consumable: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ConsumableAttr::ConsumedState defaultState(static_cast<ConsumableAttr::ConsumedState>(Record.readInt())); + New = new (Context) ConsumableAttr(Range, Context, defaultState, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ConsumableAutoCast: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ConsumableAutoCastAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ConsumableSetOnRead: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ConsumableSetOnReadAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Convergent: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ConvergentAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::DLLExport: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) DLLExportAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::DLLExportStaticLocal: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) DLLExportStaticLocalAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::DLLImport: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) DLLImportAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::DLLImportStaticLocal: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) DLLImportStaticLocalAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Deprecated: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string message= Record.readString(); + std::string replacement= Record.readString(); + New = new (Context) DeprecatedAttr(Range, Context, message, replacement, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Destructor: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + int priority = Record.readInt(); + New = new (Context) DestructorAttr(Range, Context, priority, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::DiagnoseIf: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * cond = Record.readExpr(); + std::string message= Record.readString(); + DiagnoseIfAttr::DiagnosticType diagnosticType(static_cast<DiagnoseIfAttr::DiagnosticType>(Record.readInt())); + bool argDependent = Record.readInt(); + NamedDecl * parent = Record.GetLocalDeclAs<NamedDecl >(Record.readInt()); + New = new (Context) DiagnoseIfAttr(Range, Context, cond, message, diagnosticType, argDependent, parent, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::DisableTailCalls: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) DisableTailCallsAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::EmptyBases: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) EmptyBasesAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::EnableIf: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * cond = Record.readExpr(); + std::string message= Record.readString(); + New = new (Context) EnableIfAttr(Range, Context, cond, message, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::EnumExtensibility: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + EnumExtensibilityAttr::Kind extensibility(static_cast<EnumExtensibilityAttr::Kind>(Record.readInt())); + New = new (Context) EnumExtensibilityAttr(Range, Context, extensibility, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ExcludeFromExplicitInstantiation: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ExcludeFromExplicitInstantiationAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ExclusiveTrylockFunction: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * successValue = Record.readExpr(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) ExclusiveTrylockFunctionAttr(Range, Context, successValue, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ExternalSourceSymbol: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string language= Record.readString(); + std::string definedIn= Record.readString(); + bool generatedDeclaration = Record.readInt(); + New = new (Context) ExternalSourceSymbolAttr(Range, Context, language, definedIn, generatedDeclaration, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::FallThrough: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) FallThroughAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::FastCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) FastCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Final: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) FinalAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::FlagEnum: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) FlagEnumAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Flatten: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) FlattenAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Format: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * type = Record.getIdentifierInfo(); + int formatIdx = Record.readInt(); + int firstArg = Record.readInt(); + New = new (Context) FormatAttr(Range, Context, type, formatIdx, firstArg, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::FormatArg: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ParamIdx formatIdx = ParamIdx::deserialize(Record.readInt()); + New = new (Context) FormatArgAttr(Range, Context, formatIdx, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::FortifyStdLib: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + int type = Record.readInt(); + int flag = Record.readInt(); + New = new (Context) FortifyStdLibAttr(Range, Context, type, flag, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::GNUInline: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) GNUInlineAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::GuardedBy: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * arg = Record.readExpr(); + New = new (Context) GuardedByAttr(Range, Context, arg, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::GuardedVar: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) GuardedVarAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Hot: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) HotAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::IBAction: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) IBActionAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::IBOutlet: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) IBOutletAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::IBOutletCollection: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + TypeSourceInfo * interface_ = Record.getTypeSourceInfo(); + New = new (Context) IBOutletCollectionAttr(Range, Context, interface_, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::IFunc: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string resolver= Record.readString(); + New = new (Context) IFuncAttr(Range, Context, resolver, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::InitPriority: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned priority = Record.readInt(); + New = new (Context) InitPriorityAttr(Range, Context, priority, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::InitSeg: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string section= Record.readString(); + New = new (Context) InitSegAttr(Range, Context, section, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::IntelOclBicc: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) IntelOclBiccAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::InternalLinkage: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) InternalLinkageAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::LTOVisibilityPublic: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) LTOVisibilityPublicAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::LayoutVersion: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned version = Record.readInt(); + New = new (Context) LayoutVersionAttr(Range, Context, version, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::LifetimeBound: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) LifetimeBoundAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::LockReturned: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * arg = Record.readExpr(); + New = new (Context) LockReturnedAttr(Range, Context, arg, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::LocksExcluded: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) LocksExcludedAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::LoopHint: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + LoopHintAttr::OptionType option(static_cast<LoopHintAttr::OptionType>(Record.readInt())); + LoopHintAttr::LoopHintState state(static_cast<LoopHintAttr::LoopHintState>(Record.readInt())); + Expr * value = Record.readExpr(); + New = new (Context) LoopHintAttr(Range, Context, option, state, value, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::MSABI: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MSABIAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MSInheritance: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + bool bestCase = Record.readInt(); + New = new (Context) MSInheritanceAttr(Range, Context, bestCase, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MSNoVTable: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MSNoVTableAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MSP430Interrupt: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned number = Record.readInt(); + New = new (Context) MSP430InterruptAttr(Range, Context, number, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MSStruct: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MSStructAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MSVtorDisp: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned vdm = Record.readInt(); + New = new (Context) MSVtorDispAttr(Range, Context, vdm, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MaxFieldAlignment: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned alignment = Record.readInt(); + New = new (Context) MaxFieldAlignmentAttr(Range, Context, alignment, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MayAlias: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MayAliasAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MicroMips: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MicroMipsAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MinSize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MinSizeAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MinVectorWidth: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned vectorWidth = Record.readInt(); + New = new (Context) MinVectorWidthAttr(Range, Context, vectorWidth, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Mips16: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) Mips16Attr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MipsInterrupt: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + MipsInterruptAttr::InterruptType interrupt(static_cast<MipsInterruptAttr::InterruptType>(Record.readInt())); + New = new (Context) MipsInterruptAttr(Range, Context, interrupt, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MipsLongCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MipsLongCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::MipsShortCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) MipsShortCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Mode: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * mode = Record.getIdentifierInfo(); + New = new (Context) ModeAttr(Range, Context, mode, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::NSConsumed: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NSConsumedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NSConsumesSelf: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NSConsumesSelfAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NSReturnsAutoreleased: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NSReturnsAutoreleasedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NSReturnsNotRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NSReturnsNotRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NSReturnsRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NSReturnsRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Naked: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NakedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoAlias: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoAliasAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoCommon: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoCommonAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoDebug: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoDebugAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoDeref: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoDerefAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::NoDestroy: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoDestroyAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoDuplicate: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoDuplicateAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoEscape: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoEscapeAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::NoInline: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoInlineAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoInstrumentFunction: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoInstrumentFunctionAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoMicroMips: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoMicroMipsAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoMips16: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoMips16Attr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoReturn: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoReturnAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoSanitize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned sanitizersSize = Record.readInt(); + SmallVector<StringRef, 4> sanitizers; + sanitizers.reserve(sanitizersSize); + SmallVector<std::string, 4> sanitizersStorage; + sanitizersStorage.reserve(sanitizersSize); + for (unsigned i = 0; i != sanitizersSize; ++i) + sanitizersStorage.push_back(Record.readString()); + for (unsigned i = 0; i != sanitizersSize; ++i) + sanitizers.push_back(sanitizersStorage[i]); + New = new (Context) NoSanitizeAttr(Range, Context, sanitizers.data(), sanitizersSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoSpeculativeLoadHardening: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoSpeculativeLoadHardeningAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoSplitStack: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoSplitStackAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoStackProtector: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoStackProtectorAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoThreadSafetyAnalysis: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoThreadSafetyAnalysisAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NoThrow: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NoThrowAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NonNull: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<ParamIdx, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(ParamIdx::deserialize(Record.readInt())); + New = new (Context) NonNullAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::NotTailCalled: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) NotTailCalledAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OMPCaptureKind: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned captureKind = Record.readInt(); + New = new (Context) OMPCaptureKindAttr(Range, Context, captureKind, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OMPCaptureNoInit: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OMPCaptureNoInitAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OMPDeclareSimdDecl: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + OMPDeclareSimdDeclAttr::BranchStateTy branchState(static_cast<OMPDeclareSimdDeclAttr::BranchStateTy>(Record.readInt())); + Expr * simdlen = Record.readExpr(); + unsigned uniformsSize = Record.readInt(); + SmallVector<Expr *, 4> uniforms; + uniforms.reserve(uniformsSize); + for (unsigned i = 0; i != uniformsSize; ++i) + uniforms.push_back(Record.readExpr()); + unsigned alignedsSize = Record.readInt(); + SmallVector<Expr *, 4> aligneds; + aligneds.reserve(alignedsSize); + for (unsigned i = 0; i != alignedsSize; ++i) + aligneds.push_back(Record.readExpr()); + unsigned alignmentsSize = Record.readInt(); + SmallVector<Expr *, 4> alignments; + alignments.reserve(alignmentsSize); + for (unsigned i = 0; i != alignmentsSize; ++i) + alignments.push_back(Record.readExpr()); + unsigned linearsSize = Record.readInt(); + SmallVector<Expr *, 4> linears; + linears.reserve(linearsSize); + for (unsigned i = 0; i != linearsSize; ++i) + linears.push_back(Record.readExpr()); + unsigned modifiersSize = Record.readInt(); + SmallVector<unsigned, 4> modifiers; + modifiers.reserve(modifiersSize); + for (unsigned i = 0; i != modifiersSize; ++i) + modifiers.push_back(Record.readInt()); + unsigned stepsSize = Record.readInt(); + SmallVector<Expr *, 4> steps; + steps.reserve(stepsSize); + for (unsigned i = 0; i != stepsSize; ++i) + steps.push_back(Record.readExpr()); + New = new (Context) OMPDeclareSimdDeclAttr(Range, Context, branchState, simdlen, uniforms.data(), uniformsSize, aligneds.data(), alignedsSize, alignments.data(), alignmentsSize, linears.data(), linearsSize, modifiers.data(), modifiersSize, steps.data(), stepsSize, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OMPDeclareTargetDecl: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + OMPDeclareTargetDeclAttr::MapTypeTy mapType(static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt())); + New = new (Context) OMPDeclareTargetDeclAttr(Range, Context, mapType, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OMPReferencedVar: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * ref = Record.readExpr(); + New = new (Context) OMPReferencedVarAttr(Range, Context, ref, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OMPThreadPrivateDecl: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OMPThreadPrivateDeclAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OSConsumed: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OSConsumedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OSConsumesThis: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OSConsumesThisAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OSReturnsNotRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OSReturnsNotRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OSReturnsRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OSReturnsRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OSReturnsRetainedOnNonZero: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OSReturnsRetainedOnNonZeroAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OSReturnsRetainedOnZero: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OSReturnsRetainedOnZeroAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCBoxable: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCBoxableAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCBridge: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * bridgedType = Record.getIdentifierInfo(); + New = new (Context) ObjCBridgeAttr(Range, Context, bridgedType, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCBridgeMutable: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * bridgedType = Record.getIdentifierInfo(); + New = new (Context) ObjCBridgeMutableAttr(Range, Context, bridgedType, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCBridgeRelated: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * relatedClass = Record.getIdentifierInfo(); + IdentifierInfo * classMethod = Record.getIdentifierInfo(); + IdentifierInfo * instanceMethod = Record.getIdentifierInfo(); + New = new (Context) ObjCBridgeRelatedAttr(Range, Context, relatedClass, classMethod, instanceMethod, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCDesignatedInitializer: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCDesignatedInitializerAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCException: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCExceptionAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCExplicitProtocolImpl: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCExplicitProtocolImplAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCExternallyRetained: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCExternallyRetainedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCGC: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * kind = Record.getIdentifierInfo(); + New = new (Context) ObjCGCAttr(Range, Context, kind, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCIndependentClass: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCIndependentClassAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCInertUnsafeUnretained: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCInertUnsafeUnretainedAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCKindOf: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCKindOfAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCMethodFamily: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ObjCMethodFamilyAttr::FamilyKind family(static_cast<ObjCMethodFamilyAttr::FamilyKind>(Record.readInt())); + New = new (Context) ObjCMethodFamilyAttr(Range, Context, family, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCNSObject: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCNSObjectAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCNonLazyClass: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCNonLazyClassAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCOwnership: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * kind = Record.getIdentifierInfo(); + New = new (Context) ObjCOwnershipAttr(Range, Context, kind, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCPreciseLifetime: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCPreciseLifetimeAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCRequiresPropertyDefs: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCRequiresPropertyDefsAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCRequiresSuper: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCRequiresSuperAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCReturnsInnerPointer: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCReturnsInnerPointerAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCRootClass: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCRootClassAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCRuntimeName: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string metadataName= Record.readString(); + New = new (Context) ObjCRuntimeNameAttr(Range, Context, metadataName, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCRuntimeVisible: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCRuntimeVisibleAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ObjCSubclassingRestricted: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ObjCSubclassingRestrictedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLAccess: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLAccessAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLConstantAddressSpace: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLConstantAddressSpaceAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLGenericAddressSpace: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLGenericAddressSpaceAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLGlobalAddressSpace: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLGlobalAddressSpaceAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLIntelReqdSubGroupSize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned subGroupSize = Record.readInt(); + New = new (Context) OpenCLIntelReqdSubGroupSizeAttr(Range, Context, subGroupSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLKernel: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLKernelAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLLocalAddressSpace: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLLocalAddressSpaceAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLPrivateAddressSpace: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OpenCLPrivateAddressSpaceAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::OpenCLUnrollHint: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned unrollHint = Record.readInt(); + New = new (Context) OpenCLUnrollHintAttr(Range, Context, unrollHint, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::OptimizeNone: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OptimizeNoneAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Overloadable: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OverloadableAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::Override: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) OverrideAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Ownership: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * module = Record.getIdentifierInfo(); + unsigned argsSize = Record.readInt(); + SmallVector<ParamIdx, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(ParamIdx::deserialize(Record.readInt())); + New = new (Context) OwnershipAttr(Range, Context, module, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Packed: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) PackedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ParamTypestate: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ParamTypestateAttr::ConsumedState paramState(static_cast<ParamTypestateAttr::ConsumedState>(Record.readInt())); + New = new (Context) ParamTypestateAttr(Range, Context, paramState, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Pascal: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) PascalAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PassObjectSize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + int type = Record.readInt(); + New = new (Context) PassObjectSizeAttr(Range, Context, type, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Pcs: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + PcsAttr::PCSType pCS(static_cast<PcsAttr::PCSType>(Record.readInt())); + New = new (Context) PcsAttr(Range, Context, pCS, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PragmaClangBSSSection: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) PragmaClangBSSSectionAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PragmaClangDataSection: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) PragmaClangDataSectionAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PragmaClangRodataSection: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) PragmaClangRodataSectionAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PragmaClangTextSection: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) PragmaClangTextSectionAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PreserveAll: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) PreserveAllAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PreserveMost: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) PreserveMostAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PtGuardedBy: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * arg = Record.readExpr(); + New = new (Context) PtGuardedByAttr(Range, Context, arg, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::PtGuardedVar: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) PtGuardedVarAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Ptr32: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) Ptr32Attr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::Ptr64: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) Ptr64Attr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::Pure: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) PureAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::RISCVInterrupt: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + RISCVInterruptAttr::InterruptType interrupt(static_cast<RISCVInterruptAttr::InterruptType>(Record.readInt())); + New = new (Context) RISCVInterruptAttr(Range, Context, interrupt, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::RegCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) RegCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Reinitializes: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ReinitializesAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ReleaseCapability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) ReleaseCapabilityAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::RenderScriptKernel: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) RenderScriptKernelAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ReqdWorkGroupSize: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned xDim = Record.readInt(); + unsigned yDim = Record.readInt(); + unsigned zDim = Record.readInt(); + New = new (Context) ReqdWorkGroupSizeAttr(Range, Context, xDim, yDim, zDim, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::RequireConstantInit: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) RequireConstantInitAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::RequiresCapability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) RequiresCapabilityAttr(Range, Context, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Restrict: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) RestrictAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ReturnTypestate: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + ReturnTypestateAttr::ConsumedState state(static_cast<ReturnTypestateAttr::ConsumedState>(Record.readInt())); + New = new (Context) ReturnTypestateAttr(Range, Context, state, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ReturnsNonNull: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ReturnsNonNullAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ReturnsTwice: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ReturnsTwiceAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SPtr: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SPtrAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::ScopedLockable: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ScopedLockableAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Section: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string name= Record.readString(); + New = new (Context) SectionAttr(Range, Context, name, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SelectAny: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SelectAnyAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Sentinel: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + int sentinel = Record.readInt(); + int nullPos = Record.readInt(); + New = new (Context) SentinelAttr(Range, Context, sentinel, nullPos, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SetTypestate: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + SetTypestateAttr::ConsumedState newState(static_cast<SetTypestateAttr::ConsumedState>(Record.readInt())); + New = new (Context) SetTypestateAttr(Range, Context, newState, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SharedTrylockFunction: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * successValue = Record.readExpr(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) SharedTrylockFunctionAttr(Range, Context, successValue, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SpeculativeLoadHardening: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SpeculativeLoadHardeningAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::StdCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) StdCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Suppress: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned diagnosticIdentifiersSize = Record.readInt(); + SmallVector<StringRef, 4> diagnosticIdentifiers; + diagnosticIdentifiers.reserve(diagnosticIdentifiersSize); + SmallVector<std::string, 4> diagnosticIdentifiersStorage; + diagnosticIdentifiersStorage.reserve(diagnosticIdentifiersSize); + for (unsigned i = 0; i != diagnosticIdentifiersSize; ++i) + diagnosticIdentifiersStorage.push_back(Record.readString()); + for (unsigned i = 0; i != diagnosticIdentifiersSize; ++i) + diagnosticIdentifiers.push_back(diagnosticIdentifiersStorage[i]); + New = new (Context) SuppressAttr(Range, Context, diagnosticIdentifiers.data(), diagnosticIdentifiersSize, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::SwiftCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SwiftCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SwiftContext: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SwiftContextAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SwiftErrorResult: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SwiftErrorResultAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SwiftIndirectResult: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SwiftIndirectResultAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::SysVABI: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) SysVABIAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::TLSModel: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string model= Record.readString(); + New = new (Context) TLSModelAttr(Range, Context, model, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Target: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string featuresStr= Record.readString(); + New = new (Context) TargetAttr(Range, Context, featuresStr, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::TestTypestate: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + TestTypestateAttr::ConsumedState testState(static_cast<TestTypestateAttr::ConsumedState>(Record.readInt())); + New = new (Context) TestTypestateAttr(Range, Context, testState, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::ThisCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ThisCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Thread: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) ThreadAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::TransparentUnion: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) TransparentUnionAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::TrivialABI: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) TrivialABIAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::TryAcquireCapability: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + Expr * successValue = Record.readExpr(); + unsigned argsSize = Record.readInt(); + SmallVector<Expr *, 4> args; + args.reserve(argsSize); + for (unsigned i = 0; i != argsSize; ++i) + args.push_back(Record.readExpr()); + New = new (Context) TryAcquireCapabilityAttr(Range, Context, successValue, args.data(), argsSize, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::TypeNonNull: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) TypeNonNullAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::TypeNullUnspecified: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) TypeNullUnspecifiedAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::TypeNullable: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) TypeNullableAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::TypeTagForDatatype: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + IdentifierInfo * argumentKind = Record.getIdentifierInfo(); + TypeSourceInfo * matchingCType = Record.getTypeSourceInfo(); + bool layoutCompatible = Record.readInt(); + bool mustBeNull = Record.readInt(); + New = new (Context) TypeTagForDatatypeAttr(Range, Context, argumentKind, matchingCType, layoutCompatible, mustBeNull, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::TypeVisibility: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + TypeVisibilityAttr::VisibilityType visibility(static_cast<TypeVisibilityAttr::VisibilityType>(Record.readInt())); + New = new (Context) TypeVisibilityAttr(Range, Context, visibility, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::UPtr: { + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) UPtrAttr(Range, Context, Spelling); + New->setImplicit(isImplicit); + break; + } + case attr::Unavailable: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string message= Record.readString(); + UnavailableAttr::ImplicitReason implicitReason(static_cast<UnavailableAttr::ImplicitReason>(Record.readInt())); + New = new (Context) UnavailableAttr(Range, Context, message, implicitReason, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Uninitialized: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) UninitializedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Unused: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) UnusedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Used: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) UsedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Uuid: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string guid= Record.readString(); + New = new (Context) UuidAttr(Range, Context, guid, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::VecReturn: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) VecReturnAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::VecTypeHint: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + TypeSourceInfo * typeHint = Record.getTypeSourceInfo(); + New = new (Context) VecTypeHintAttr(Range, Context, typeHint, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::VectorCall: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) VectorCallAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Visibility: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + VisibilityAttr::VisibilityType visibility(static_cast<VisibilityAttr::VisibilityType>(Record.readInt())); + New = new (Context) VisibilityAttr(Range, Context, visibility, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WarnUnused: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) WarnUnusedAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WarnUnusedResult: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) WarnUnusedResultAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::Weak: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) WeakAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WeakImport: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) WeakImportAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WeakRef: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string aliasee= Record.readString(); + New = new (Context) WeakRefAttr(Range, Context, aliasee, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WebAssemblyImportModule: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string importModule= Record.readString(); + New = new (Context) WebAssemblyImportModuleAttr(Range, Context, importModule, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WebAssemblyImportName: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + std::string importName= Record.readString(); + New = new (Context) WebAssemblyImportNameAttr(Range, Context, importName, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::WorkGroupSizeHint: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned xDim = Record.readInt(); + unsigned yDim = Record.readInt(); + unsigned zDim = Record.readInt(); + New = new (Context) WorkGroupSizeHintAttr(Range, Context, xDim, yDim, zDim, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::X86ForceAlignArgPointer: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) X86ForceAlignArgPointerAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::XRayInstrument: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + New = new (Context) XRayInstrumentAttr(Range, Context, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + case attr::XRayLogArgs: { + bool isInherited = Record.readInt(); + bool isImplicit = Record.readInt(); + unsigned Spelling = Record.readInt(); + unsigned argumentCount = Record.readInt(); + New = new (Context) XRayLogArgsAttr(Range, Context, argumentCount, Spelling); + cast<InheritableAttr>(New)->setInherited(isInherited); + New->setImplicit(isImplicit); + break; + } + } diff --git a/clang-r353983/include/clang/Serialization/AttrPCHWrite.inc b/clang-r353983/include/clang/Serialization/AttrPCHWrite.inc new file mode 100644 index 00000000..09a9af01 --- /dev/null +++ b/clang-r353983/include/clang/Serialization/AttrPCHWrite.inc @@ -0,0 +1,2096 @@ +/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ +|* *| +|* Attribute serialization code *| +|* *| +|* Automatically generated file, do not edit! *| +|* *| +\*===----------------------------------------------------------------------===*/ + + switch (A->getKind()) { + case attr::AArch64VectorPcs: { + const auto *SA = cast<AArch64VectorPcsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AMDGPUFlatWorkGroupSize: { + const auto *SA = cast<AMDGPUFlatWorkGroupSizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getMin()); + Record.push_back(SA->getMax()); + break; + } + case attr::AMDGPUNumSGPR: { + const auto *SA = cast<AMDGPUNumSGPRAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getNumSGPR()); + break; + } + case attr::AMDGPUNumVGPR: { + const auto *SA = cast<AMDGPUNumVGPRAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getNumVGPR()); + break; + } + case attr::AMDGPUWavesPerEU: { + const auto *SA = cast<AMDGPUWavesPerEUAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getMin()); + Record.push_back(SA->getMax()); + break; + } + case attr::ARMInterrupt: { + const auto *SA = cast<ARMInterruptAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getInterrupt()); + break; + } + case attr::AVRInterrupt: { + const auto *SA = cast<AVRInterruptAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AVRSignal: { + const auto *SA = cast<AVRSignalAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AbiTag: { + const auto *SA = cast<AbiTagAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->tags_size()); + for (auto &Val : SA->tags()) + Record.AddString(Val); + break; + } + case attr::AcquireCapability: { + const auto *SA = cast<AcquireCapabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::AcquiredAfter: { + const auto *SA = cast<AcquiredAfterAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::AcquiredBefore: { + const auto *SA = cast<AcquiredBeforeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::AddressSpace: { + const auto *SA = cast<AddressSpaceAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getAddressSpace()); + break; + } + case attr::Alias: { + const auto *SA = cast<AliasAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getAliasee()); + break; + } + case attr::AlignMac68k: { + const auto *SA = cast<AlignMac68kAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AlignValue: { + const auto *SA = cast<AlignValueAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getAlignment()); + break; + } + case attr::Aligned: { + const auto *SA = cast<AlignedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->isAlignmentExpr()); + if (SA->isAlignmentExpr()) + Record.AddStmt(SA->getAlignmentExpr()); + else + Record.AddTypeSourceInfo(SA->getAlignmentType()); + break; + } + case attr::AllocAlign: { + const auto *SA = cast<AllocAlignAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getParamIndex().serialize()); + break; + } + case attr::AllocSize: { + const auto *SA = cast<AllocSizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getElemSizeParam().serialize()); + Record.push_back(SA->getNumElemsParam().serialize()); + break; + } + case attr::AlwaysDestroy: { + const auto *SA = cast<AlwaysDestroyAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AlwaysInline: { + const auto *SA = cast<AlwaysInlineAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AnalyzerNoReturn: { + const auto *SA = cast<AnalyzerNoReturnAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Annotate: { + const auto *SA = cast<AnnotateAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getAnnotation()); + break; + } + case attr::AnyX86Interrupt: { + const auto *SA = cast<AnyX86InterruptAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AnyX86NoCallerSavedRegisters: { + const auto *SA = cast<AnyX86NoCallerSavedRegistersAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AnyX86NoCfCheck: { + const auto *SA = cast<AnyX86NoCfCheckAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ArcWeakrefUnavailable: { + const auto *SA = cast<ArcWeakrefUnavailableAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ArgumentWithTypeTag: { + const auto *SA = cast<ArgumentWithTypeTagAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getArgumentKind()); + Record.push_back(SA->getArgumentIdx().serialize()); + Record.push_back(SA->getTypeTagIdx().serialize()); + Record.push_back(SA->getIsPointer()); + break; + } + case attr::Artificial: { + const auto *SA = cast<ArtificialAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::AsmLabel: { + const auto *SA = cast<AsmLabelAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getLabel()); + break; + } + case attr::AssertCapability: { + const auto *SA = cast<AssertCapabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::AssertExclusiveLock: { + const auto *SA = cast<AssertExclusiveLockAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::AssertSharedLock: { + const auto *SA = cast<AssertSharedLockAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::AssumeAligned: { + const auto *SA = cast<AssumeAlignedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getAlignment()); + Record.AddStmt(SA->getOffset()); + break; + } + case attr::Availability: { + const auto *SA = cast<AvailabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getPlatform()); + Record.AddVersionTuple(SA->getIntroduced()); + Record.AddVersionTuple(SA->getDeprecated()); + Record.AddVersionTuple(SA->getObsoleted()); + Record.push_back(SA->getUnavailable()); + Record.AddString(SA->getMessage()); + Record.push_back(SA->getStrict()); + Record.AddString(SA->getReplacement()); + Record.push_back(SA->getPriority()); + break; + } + case attr::Blocks: { + const auto *SA = cast<BlocksAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getType()); + break; + } + case attr::C11NoReturn: { + const auto *SA = cast<C11NoReturnAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CDecl: { + const auto *SA = cast<CDeclAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CFAuditedTransfer: { + const auto *SA = cast<CFAuditedTransferAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CFConsumed: { + const auto *SA = cast<CFConsumedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CFReturnsNotRetained: { + const auto *SA = cast<CFReturnsNotRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CFReturnsRetained: { + const auto *SA = cast<CFReturnsRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CFUnknownTransfer: { + const auto *SA = cast<CFUnknownTransferAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CPUDispatch: { + const auto *SA = cast<CPUDispatchAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->cpus_size()); + for (auto &Val : SA->cpus()) + Record.AddIdentifierRef(Val); + break; + } + case attr::CPUSpecific: { + const auto *SA = cast<CPUSpecificAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->cpus_size()); + for (auto &Val : SA->cpus()) + Record.AddIdentifierRef(Val); + break; + } + case attr::CUDAConstant: { + const auto *SA = cast<CUDAConstantAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CUDADevice: { + const auto *SA = cast<CUDADeviceAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CUDAGlobal: { + const auto *SA = cast<CUDAGlobalAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CUDAHost: { + const auto *SA = cast<CUDAHostAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CUDAInvalidTarget: { + const auto *SA = cast<CUDAInvalidTargetAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CUDALaunchBounds: { + const auto *SA = cast<CUDALaunchBoundsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getMaxThreads()); + Record.AddStmt(SA->getMinBlocks()); + break; + } + case attr::CUDAShared: { + const auto *SA = cast<CUDASharedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CXX11NoReturn: { + const auto *SA = cast<CXX11NoReturnAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CallableWhen: { + const auto *SA = cast<CallableWhenAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->callableStates_size()); + for (CallableWhenAttr::callableStates_iterator i = SA->callableStates_begin(), e = SA->callableStates_end(); i != e; ++i) + Record.push_back((*i)); + break; + } + case attr::Callback: { + const auto *SA = cast<CallbackAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->encoding_size()); + for (auto &Val : SA->encoding()) + Record.push_back(Val); + break; + } + case attr::Capability: { + const auto *SA = cast<CapabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::CapturedRecord: { + const auto *SA = cast<CapturedRecordAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::CarriesDependency: { + const auto *SA = cast<CarriesDependencyAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Cleanup: { + const auto *SA = cast<CleanupAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddDeclRef(SA->getFunctionDecl()); + break; + } + case attr::CodeSeg: { + const auto *SA = cast<CodeSegAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::Cold: { + const auto *SA = cast<ColdAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Common: { + const auto *SA = cast<CommonAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Const: { + const auto *SA = cast<ConstAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Constructor: { + const auto *SA = cast<ConstructorAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getPriority()); + break; + } + case attr::Consumable: { + const auto *SA = cast<ConsumableAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getDefaultState()); + break; + } + case attr::ConsumableAutoCast: { + const auto *SA = cast<ConsumableAutoCastAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ConsumableSetOnRead: { + const auto *SA = cast<ConsumableSetOnReadAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Convergent: { + const auto *SA = cast<ConvergentAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::DLLExport: { + const auto *SA = cast<DLLExportAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::DLLExportStaticLocal: { + const auto *SA = cast<DLLExportStaticLocalAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::DLLImport: { + const auto *SA = cast<DLLImportAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::DLLImportStaticLocal: { + const auto *SA = cast<DLLImportStaticLocalAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Deprecated: { + const auto *SA = cast<DeprecatedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getMessage()); + Record.AddString(SA->getReplacement()); + break; + } + case attr::Destructor: { + const auto *SA = cast<DestructorAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getPriority()); + break; + } + case attr::DiagnoseIf: { + const auto *SA = cast<DiagnoseIfAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getCond()); + Record.AddString(SA->getMessage()); +Record.push_back(SA->getDiagnosticType()); + Record.push_back(SA->getArgDependent()); + Record.AddDeclRef(SA->getParent()); + break; + } + case attr::DisableTailCalls: { + const auto *SA = cast<DisableTailCallsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::EmptyBases: { + const auto *SA = cast<EmptyBasesAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::EnableIf: { + const auto *SA = cast<EnableIfAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getCond()); + Record.AddString(SA->getMessage()); + break; + } + case attr::EnumExtensibility: { + const auto *SA = cast<EnumExtensibilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getExtensibility()); + break; + } + case attr::ExcludeFromExplicitInstantiation: { + const auto *SA = cast<ExcludeFromExplicitInstantiationAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ExclusiveTrylockFunction: { + const auto *SA = cast<ExclusiveTrylockFunctionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getSuccessValue()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::ExternalSourceSymbol: { + const auto *SA = cast<ExternalSourceSymbolAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getLanguage()); + Record.AddString(SA->getDefinedIn()); + Record.push_back(SA->getGeneratedDeclaration()); + break; + } + case attr::FallThrough: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::FastCall: { + const auto *SA = cast<FastCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Final: { + const auto *SA = cast<FinalAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::FlagEnum: { + const auto *SA = cast<FlagEnumAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Flatten: { + const auto *SA = cast<FlattenAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Format: { + const auto *SA = cast<FormatAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getType()); + Record.push_back(SA->getFormatIdx()); + Record.push_back(SA->getFirstArg()); + break; + } + case attr::FormatArg: { + const auto *SA = cast<FormatArgAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getFormatIdx().serialize()); + break; + } + case attr::FortifyStdLib: { + const auto *SA = cast<FortifyStdLibAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getType()); + Record.push_back(SA->getFlag()); + break; + } + case attr::GNUInline: { + const auto *SA = cast<GNUInlineAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::GuardedBy: { + const auto *SA = cast<GuardedByAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getArg()); + break; + } + case attr::GuardedVar: { + const auto *SA = cast<GuardedVarAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Hot: { + const auto *SA = cast<HotAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::IBAction: { + const auto *SA = cast<IBActionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::IBOutlet: { + const auto *SA = cast<IBOutletAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::IBOutletCollection: { + const auto *SA = cast<IBOutletCollectionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddTypeSourceInfo(SA->getInterfaceLoc()); + break; + } + case attr::IFunc: { + const auto *SA = cast<IFuncAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getResolver()); + break; + } + case attr::InitPriority: { + const auto *SA = cast<InitPriorityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getPriority()); + break; + } + case attr::InitSeg: { + const auto *SA = cast<InitSegAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getSection()); + break; + } + case attr::IntelOclBicc: { + const auto *SA = cast<IntelOclBiccAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::InternalLinkage: { + const auto *SA = cast<InternalLinkageAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::LTOVisibilityPublic: { + const auto *SA = cast<LTOVisibilityPublicAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::LayoutVersion: { + const auto *SA = cast<LayoutVersionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getVersion()); + break; + } + case attr::LifetimeBound: { + const auto *SA = cast<LifetimeBoundAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::LockReturned: { + const auto *SA = cast<LockReturnedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getArg()); + break; + } + case attr::LocksExcluded: { + const auto *SA = cast<LocksExcludedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::LoopHint: { + const auto *SA = cast<LoopHintAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getOption()); +Record.push_back(SA->getState()); + Record.AddStmt(SA->getValue()); + break; + } + case attr::MSABI: { + const auto *SA = cast<MSABIAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MSInheritance: { + const auto *SA = cast<MSInheritanceAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getBestCase()); + break; + } + case attr::MSNoVTable: { + const auto *SA = cast<MSNoVTableAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MSP430Interrupt: { + const auto *SA = cast<MSP430InterruptAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getNumber()); + break; + } + case attr::MSStruct: { + const auto *SA = cast<MSStructAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MSVtorDisp: { + const auto *SA = cast<MSVtorDispAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getVdm()); + break; + } + case attr::MaxFieldAlignment: { + const auto *SA = cast<MaxFieldAlignmentAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getAlignment()); + break; + } + case attr::MayAlias: { + const auto *SA = cast<MayAliasAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MicroMips: { + const auto *SA = cast<MicroMipsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MinSize: { + const auto *SA = cast<MinSizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MinVectorWidth: { + const auto *SA = cast<MinVectorWidthAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getVectorWidth()); + break; + } + case attr::Mips16: { + const auto *SA = cast<Mips16Attr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MipsInterrupt: { + const auto *SA = cast<MipsInterruptAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getInterrupt()); + break; + } + case attr::MipsLongCall: { + const auto *SA = cast<MipsLongCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::MipsShortCall: { + const auto *SA = cast<MipsShortCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Mode: { + const auto *SA = cast<ModeAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getMode()); + break; + } + case attr::NSConsumed: { + const auto *SA = cast<NSConsumedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NSConsumesSelf: { + const auto *SA = cast<NSConsumesSelfAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NSReturnsAutoreleased: { + const auto *SA = cast<NSReturnsAutoreleasedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NSReturnsNotRetained: { + const auto *SA = cast<NSReturnsNotRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NSReturnsRetained: { + const auto *SA = cast<NSReturnsRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Naked: { + const auto *SA = cast<NakedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoAlias: { + const auto *SA = cast<NoAliasAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoCommon: { + const auto *SA = cast<NoCommonAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoDebug: { + const auto *SA = cast<NoDebugAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoDeref: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoDestroy: { + const auto *SA = cast<NoDestroyAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoDuplicate: { + const auto *SA = cast<NoDuplicateAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoEscape: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoInline: { + const auto *SA = cast<NoInlineAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoInstrumentFunction: { + const auto *SA = cast<NoInstrumentFunctionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoMicroMips: { + const auto *SA = cast<NoMicroMipsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoMips16: { + const auto *SA = cast<NoMips16Attr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoReturn: { + const auto *SA = cast<NoReturnAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoSanitize: { + const auto *SA = cast<NoSanitizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->sanitizers_size()); + for (auto &Val : SA->sanitizers()) + Record.AddString(Val); + break; + } + case attr::NoSpeculativeLoadHardening: { + const auto *SA = cast<NoSpeculativeLoadHardeningAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoSplitStack: { + const auto *SA = cast<NoSplitStackAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoStackProtector: { + const auto *SA = cast<NoStackProtectorAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoThreadSafetyAnalysis: { + const auto *SA = cast<NoThreadSafetyAnalysisAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NoThrow: { + const auto *SA = cast<NoThrowAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::NonNull: { + const auto *SA = cast<NonNullAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.push_back(Val.serialize()); + break; + } + case attr::NotTailCalled: { + const auto *SA = cast<NotTailCalledAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OMPCaptureKind: { + const auto *SA = cast<OMPCaptureKindAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getCaptureKind()); + break; + } + case attr::OMPCaptureNoInit: { + const auto *SA = cast<OMPCaptureNoInitAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OMPDeclareSimdDecl: { + const auto *SA = cast<OMPDeclareSimdDeclAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getBranchState()); + Record.AddStmt(SA->getSimdlen()); + Record.push_back(SA->uniforms_size()); + for (auto &Val : SA->uniforms()) + Record.AddStmt(Val); + Record.push_back(SA->aligneds_size()); + for (auto &Val : SA->aligneds()) + Record.AddStmt(Val); + Record.push_back(SA->alignments_size()); + for (auto &Val : SA->alignments()) + Record.AddStmt(Val); + Record.push_back(SA->linears_size()); + for (auto &Val : SA->linears()) + Record.AddStmt(Val); + Record.push_back(SA->modifiers_size()); + for (auto &Val : SA->modifiers()) + Record.push_back(Val); + Record.push_back(SA->steps_size()); + for (auto &Val : SA->steps()) + Record.AddStmt(Val); + break; + } + case attr::OMPDeclareTargetDecl: { + const auto *SA = cast<OMPDeclareTargetDeclAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getMapType()); + break; + } + case attr::OMPReferencedVar: { + const auto *SA = cast<OMPReferencedVarAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getRef()); + break; + } + case attr::OMPThreadPrivateDecl: { + const auto *SA = cast<OMPThreadPrivateDeclAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OSConsumed: { + const auto *SA = cast<OSConsumedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OSConsumesThis: { + const auto *SA = cast<OSConsumesThisAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OSReturnsNotRetained: { + const auto *SA = cast<OSReturnsNotRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OSReturnsRetained: { + const auto *SA = cast<OSReturnsRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OSReturnsRetainedOnNonZero: { + const auto *SA = cast<OSReturnsRetainedOnNonZeroAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OSReturnsRetainedOnZero: { + const auto *SA = cast<OSReturnsRetainedOnZeroAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCBoxable: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCBridge: { + const auto *SA = cast<ObjCBridgeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getBridgedType()); + break; + } + case attr::ObjCBridgeMutable: { + const auto *SA = cast<ObjCBridgeMutableAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getBridgedType()); + break; + } + case attr::ObjCBridgeRelated: { + const auto *SA = cast<ObjCBridgeRelatedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getRelatedClass()); + Record.AddIdentifierRef(SA->getClassMethod()); + Record.AddIdentifierRef(SA->getInstanceMethod()); + break; + } + case attr::ObjCDesignatedInitializer: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCException: { + const auto *SA = cast<ObjCExceptionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCExplicitProtocolImpl: { + const auto *SA = cast<ObjCExplicitProtocolImplAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCExternallyRetained: { + const auto *SA = cast<ObjCExternallyRetainedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCGC: { + const auto *SA = cast<ObjCGCAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getKind()); + break; + } + case attr::ObjCIndependentClass: { + const auto *SA = cast<ObjCIndependentClassAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCInertUnsafeUnretained: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCKindOf: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCMethodFamily: { + const auto *SA = cast<ObjCMethodFamilyAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getFamily()); + break; + } + case attr::ObjCNSObject: { + const auto *SA = cast<ObjCNSObjectAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCNonLazyClass: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCOwnership: { + const auto *SA = cast<ObjCOwnershipAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getKind()); + break; + } + case attr::ObjCPreciseLifetime: { + const auto *SA = cast<ObjCPreciseLifetimeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCRequiresPropertyDefs: { + const auto *SA = cast<ObjCRequiresPropertyDefsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCRequiresSuper: { + const auto *SA = cast<ObjCRequiresSuperAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCReturnsInnerPointer: { + const auto *SA = cast<ObjCReturnsInnerPointerAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCRootClass: { + const auto *SA = cast<ObjCRootClassAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCRuntimeName: { + const auto *SA = cast<ObjCRuntimeNameAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getMetadataName()); + break; + } + case attr::ObjCRuntimeVisible: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ObjCSubclassingRestricted: { + const auto *SA = cast<ObjCSubclassingRestrictedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLAccess: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLConstantAddressSpace: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLGenericAddressSpace: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLGlobalAddressSpace: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLIntelReqdSubGroupSize: { + const auto *SA = cast<OpenCLIntelReqdSubGroupSizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getSubGroupSize()); + break; + } + case attr::OpenCLKernel: { + const auto *SA = cast<OpenCLKernelAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLLocalAddressSpace: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLPrivateAddressSpace: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::OpenCLUnrollHint: { + const auto *SA = cast<OpenCLUnrollHintAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getUnrollHint()); + break; + } + case attr::OptimizeNone: { + const auto *SA = cast<OptimizeNoneAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Overloadable: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Override: { + const auto *SA = cast<OverrideAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Ownership: { + const auto *SA = cast<OwnershipAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getModule()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.push_back(Val.serialize()); + break; + } + case attr::Packed: { + const auto *SA = cast<PackedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ParamTypestate: { + const auto *SA = cast<ParamTypestateAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getParamState()); + break; + } + case attr::Pascal: { + const auto *SA = cast<PascalAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::PassObjectSize: { + const auto *SA = cast<PassObjectSizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getType()); + break; + } + case attr::Pcs: { + const auto *SA = cast<PcsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getPCS()); + break; + } + case attr::PragmaClangBSSSection: { + const auto *SA = cast<PragmaClangBSSSectionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::PragmaClangDataSection: { + const auto *SA = cast<PragmaClangDataSectionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::PragmaClangRodataSection: { + const auto *SA = cast<PragmaClangRodataSectionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::PragmaClangTextSection: { + const auto *SA = cast<PragmaClangTextSectionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::PreserveAll: { + const auto *SA = cast<PreserveAllAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::PreserveMost: { + const auto *SA = cast<PreserveMostAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::PtGuardedBy: { + const auto *SA = cast<PtGuardedByAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getArg()); + break; + } + case attr::PtGuardedVar: { + const auto *SA = cast<PtGuardedVarAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Ptr32: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Ptr64: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Pure: { + const auto *SA = cast<PureAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::RISCVInterrupt: { + const auto *SA = cast<RISCVInterruptAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getInterrupt()); + break; + } + case attr::RegCall: { + const auto *SA = cast<RegCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Reinitializes: { + const auto *SA = cast<ReinitializesAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ReleaseCapability: { + const auto *SA = cast<ReleaseCapabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::RenderScriptKernel: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ReqdWorkGroupSize: { + const auto *SA = cast<ReqdWorkGroupSizeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getXDim()); + Record.push_back(SA->getYDim()); + Record.push_back(SA->getZDim()); + break; + } + case attr::RequireConstantInit: { + const auto *SA = cast<RequireConstantInitAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::RequiresCapability: { + const auto *SA = cast<RequiresCapabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::Restrict: { + const auto *SA = cast<RestrictAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ReturnTypestate: { + const auto *SA = cast<ReturnTypestateAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getState()); + break; + } + case attr::ReturnsNonNull: { + const auto *SA = cast<ReturnsNonNullAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ReturnsTwice: { + const auto *SA = cast<ReturnsTwiceAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::SPtr: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::ScopedLockable: { + const auto *SA = cast<ScopedLockableAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Section: { + const auto *SA = cast<SectionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getName()); + break; + } + case attr::SelectAny: { + const auto *SA = cast<SelectAnyAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Sentinel: { + const auto *SA = cast<SentinelAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getSentinel()); + Record.push_back(SA->getNullPos()); + break; + } + case attr::SetTypestate: { + const auto *SA = cast<SetTypestateAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getNewState()); + break; + } + case attr::SharedTrylockFunction: { + const auto *SA = cast<SharedTrylockFunctionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getSuccessValue()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::SpeculativeLoadHardening: { + const auto *SA = cast<SpeculativeLoadHardeningAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::StdCall: { + const auto *SA = cast<StdCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Suppress: { + const auto *SA = cast<SuppressAttr>(A); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->diagnosticIdentifiers_size()); + for (auto &Val : SA->diagnosticIdentifiers()) + Record.AddString(Val); + break; + } + case attr::SwiftCall: { + const auto *SA = cast<SwiftCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::SwiftContext: { + const auto *SA = cast<SwiftContextAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::SwiftErrorResult: { + const auto *SA = cast<SwiftErrorResultAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::SwiftIndirectResult: { + const auto *SA = cast<SwiftIndirectResultAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::SysVABI: { + const auto *SA = cast<SysVABIAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TLSModel: { + const auto *SA = cast<TLSModelAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getModel()); + break; + } + case attr::Target: { + const auto *SA = cast<TargetAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getFeaturesStr()); + break; + } + case attr::TestTypestate: { + const auto *SA = cast<TestTypestateAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getTestState()); + break; + } + case attr::ThisCall: { + const auto *SA = cast<ThisCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Thread: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TransparentUnion: { + const auto *SA = cast<TransparentUnionAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TrivialABI: { + const auto *SA = cast<TrivialABIAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TryAcquireCapability: { + const auto *SA = cast<TryAcquireCapabilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddStmt(SA->getSuccessValue()); + Record.push_back(SA->args_size()); + for (auto &Val : SA->args()) + Record.AddStmt(Val); + break; + } + case attr::TypeNonNull: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TypeNullUnspecified: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TypeNullable: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::TypeTagForDatatype: { + const auto *SA = cast<TypeTagForDatatypeAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddIdentifierRef(SA->getArgumentKind()); + Record.AddTypeSourceInfo(SA->getMatchingCTypeLoc()); + Record.push_back(SA->getLayoutCompatible()); + Record.push_back(SA->getMustBeNull()); + break; + } + case attr::TypeVisibility: { + const auto *SA = cast<TypeVisibilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getVisibility()); + break; + } + case attr::UPtr: { + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Unavailable: { + const auto *SA = cast<UnavailableAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getMessage()); +Record.push_back(SA->getImplicitReason()); + break; + } + case attr::Uninitialized: { + const auto *SA = cast<UninitializedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Unused: { + const auto *SA = cast<UnusedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Used: { + const auto *SA = cast<UsedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Uuid: { + const auto *SA = cast<UuidAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getGuid()); + break; + } + case attr::VecReturn: { + const auto *SA = cast<VecReturnAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::VecTypeHint: { + const auto *SA = cast<VecTypeHintAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddTypeSourceInfo(SA->getTypeHintLoc()); + break; + } + case attr::VectorCall: { + const auto *SA = cast<VectorCallAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Visibility: { + const auto *SA = cast<VisibilityAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); +Record.push_back(SA->getVisibility()); + break; + } + case attr::WarnUnused: { + const auto *SA = cast<WarnUnusedAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::WarnUnusedResult: { + const auto *SA = cast<WarnUnusedResultAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::Weak: { + const auto *SA = cast<WeakAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::WeakImport: { + const auto *SA = cast<WeakImportAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::WeakRef: { + const auto *SA = cast<WeakRefAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getAliasee()); + break; + } + case attr::WebAssemblyImportModule: { + const auto *SA = cast<WebAssemblyImportModuleAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getImportModule()); + break; + } + case attr::WebAssemblyImportName: { + const auto *SA = cast<WebAssemblyImportNameAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.AddString(SA->getImportName()); + break; + } + case attr::WorkGroupSizeHint: { + const auto *SA = cast<WorkGroupSizeHintAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getXDim()); + Record.push_back(SA->getYDim()); + Record.push_back(SA->getZDim()); + break; + } + case attr::X86ForceAlignArgPointer: { + const auto *SA = cast<X86ForceAlignArgPointerAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::XRayInstrument: { + const auto *SA = cast<XRayInstrumentAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + break; + } + case attr::XRayLogArgs: { + const auto *SA = cast<XRayLogArgsAttr>(A); + Record.push_back(SA->isInherited()); + Record.push_back(A->isImplicit()); + Record.push_back(A->getSpellingListIndex()); + Record.push_back(SA->getArgumentCount()); + break; + } + } diff --git a/clang-r353983/include/clang/Serialization/ContinuousRangeMap.h b/clang-r353983/include/clang/Serialization/ContinuousRangeMap.h new file mode 100644 index 00000000..ce5748b2 --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ContinuousRangeMap.h @@ -0,0 +1,141 @@ +//===- ContinuousRangeMap.h - Map with int range as key ---------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the ContinuousRangeMap class, which is a highly +// specialized container used by serialization. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H +#define LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include <algorithm> +#include <cassert> +#include <utility> + +namespace clang { + +/// A map from continuous integer ranges to some value, with a very +/// specialized interface. +/// +/// CRM maps from integer ranges to values. The ranges are continuous, i.e. +/// where one ends, the next one begins. So if the map contains the stops I0-3, +/// the first range is from I0 to I1, the second from I1 to I2, the third from +/// I2 to I3 and the last from I3 to infinity. +/// +/// Ranges must be inserted in order. Inserting a new stop I4 into the map will +/// shrink the fourth range to I3 to I4 and add the new range I4 to inf. +template <typename Int, typename V, unsigned InitialCapacity> +class ContinuousRangeMap { +public: + using value_type = std::pair<Int, V>; + using reference = value_type &; + using const_reference = const value_type &; + using pointer = value_type *; + using const_pointer = const value_type *; + +private: + using Representation = SmallVector<value_type, InitialCapacity>; + + Representation Rep; + + struct Compare { + bool operator ()(const_reference L, Int R) const { + return L.first < R; + } + bool operator ()(Int L, const_reference R) const { + return L < R.first; + } + bool operator ()(Int L, Int R) const { + return L < R; + } + bool operator ()(const_reference L, const_reference R) const { + return L.first < R.first; + } + }; + +public: + void insert(const value_type &Val) { + if (!Rep.empty() && Rep.back() == Val) + return; + + assert((Rep.empty() || Rep.back().first < Val.first) && + "Must insert keys in order."); + Rep.push_back(Val); + } + + void insertOrReplace(const value_type &Val) { + iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare()); + if (I != Rep.end() && I->first == Val.first) { + I->second = Val.second; + return; + } + + Rep.insert(I, Val); + } + + using iterator = typename Representation::iterator; + using const_iterator = typename Representation::const_iterator; + + iterator begin() { return Rep.begin(); } + iterator end() { return Rep.end(); } + const_iterator begin() const { return Rep.begin(); } + const_iterator end() const { return Rep.end(); } + + iterator find(Int K) { + iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare()); + // I points to the first entry with a key > K, which is the range that + // follows the one containing K. + if (I == Rep.begin()) + return Rep.end(); + --I; + return I; + } + const_iterator find(Int K) const { + return const_cast<ContinuousRangeMap*>(this)->find(K); + } + + reference back() { return Rep.back(); } + const_reference back() const { return Rep.back(); } + + /// An object that helps properly build a continuous range map + /// from a set of values. + class Builder { + ContinuousRangeMap &Self; + + public: + explicit Builder(ContinuousRangeMap &Self) : Self(Self) {} + Builder(const Builder&) = delete; + Builder &operator=(const Builder&) = delete; + + ~Builder() { + llvm::sort(Self.Rep, Compare()); + std::unique(Self.Rep.begin(), Self.Rep.end(), + [](const_reference A, const_reference B) { + // FIXME: we should not allow any duplicate keys, but there are a lot of + // duplicate 0 -> 0 mappings to remove first. + assert((A == B || A.first != B.first) && + "ContinuousRangeMap::Builder given non-unique keys"); + return A == B; + }); + } + + void insert(const value_type &Val) { + Self.Rep.push_back(Val); + } + }; + + friend class Builder; +}; + +} // namespace clang + +#endif // LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H diff --git a/clang-r353983/include/clang/Serialization/GlobalModuleIndex.h b/clang-r353983/include/clang/Serialization/GlobalModuleIndex.h new file mode 100644 index 00000000..2f9a70df --- /dev/null +++ b/clang-r353983/include/clang/Serialization/GlobalModuleIndex.h @@ -0,0 +1,203 @@ +//===--- GlobalModuleIndex.h - Global Module Index --------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the GlobalModuleIndex class, which manages a global index +// containing all of the identifiers known to the various modules within a given +// subdirectory of the module cache. It is used to improve the performance of +// queries such as "do any modules know about this identifier?" +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H +#define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include <memory> +#include <utility> + +namespace llvm { +class BitstreamCursor; +class MemoryBuffer; +} + +namespace clang { + +class DirectoryEntry; +class FileEntry; +class FileManager; +class IdentifierIterator; +class PCHContainerOperations; +class PCHContainerReader; + +namespace serialization { + class ModuleFile; +} + +/// A global index for a set of module files, providing information about +/// the identifiers within those module files. +/// +/// The global index is an aid for name lookup into modules, offering a central +/// place where one can look for identifiers determine which +/// module files contain any information about that identifier. This +/// allows the client to restrict the search to only those module files known +/// to have a information about that identifier, improving performance. Moreover, +/// the global module index may know about module files that have not been +/// imported, and can be queried to determine which modules the current +/// translation could or should load to fix a problem. +class GlobalModuleIndex { + using ModuleFile = serialization::ModuleFile; + + /// Buffer containing the index file, which is lazily accessed so long + /// as the global module index is live. + std::unique_ptr<llvm::MemoryBuffer> Buffer; + + /// The hash table. + /// + /// This pointer actually points to a IdentifierIndexTable object, + /// but that type is only accessible within the implementation of + /// GlobalModuleIndex. + void *IdentifierIndex; + + /// Information about a given module file. + struct ModuleInfo { + ModuleInfo() : File(), Size(), ModTime() { } + + /// The module file, once it has been resolved. + ModuleFile *File; + + /// The module file name. + std::string FileName; + + /// Size of the module file at the time the global index was built. + off_t Size; + + /// Modification time of the module file at the time the global + /// index was built. + time_t ModTime; + + /// The module IDs on which this module directly depends. + /// FIXME: We don't really need a vector here. + llvm::SmallVector<unsigned, 4> Dependencies; + }; + + /// A mapping from module IDs to information about each module. + /// + /// This vector may have gaps, if module files have been removed or have + /// been updated since the index was built. A gap is indicated by an empty + /// file name. + llvm::SmallVector<ModuleInfo, 16> Modules; + + /// Lazily-populated mapping from module files to their + /// corresponding index into the \c Modules vector. + llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile; + + /// The set of modules that have not yet been resolved. + /// + /// The string is just the name of the module itself, which maps to the + /// module ID. + llvm::StringMap<unsigned> UnresolvedModules; + + /// The number of identifier lookups we performed. + unsigned NumIdentifierLookups; + + /// The number of identifier lookup hits, where we recognize the + /// identifier. + unsigned NumIdentifierLookupHits; + + /// Internal constructor. Use \c readIndex() to read an index. + explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer, + llvm::BitstreamCursor Cursor); + + GlobalModuleIndex(const GlobalModuleIndex &) = delete; + GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete; + +public: + ~GlobalModuleIndex(); + + /// An error code returned when trying to read an index. + enum ErrorCode { + /// No error occurred. + EC_None, + /// No index was found. + EC_NotFound, + /// Some other process is currently building the index; it is not + /// available yet. + EC_Building, + /// There was an unspecified I/O error reading or writing the index. + EC_IOError + }; + + /// Read a global index file for the given directory. + /// + /// \param Path The path to the specific module cache where the module files + /// for the intended configuration reside. + /// + /// \returns A pair containing the global module index (if it exists) and + /// the error code. + static std::pair<GlobalModuleIndex *, ErrorCode> + readIndex(llvm::StringRef Path); + + /// Returns an iterator for identifiers stored in the index table. + /// + /// 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, + llvm::SmallVectorImpl<ModuleFile *> &Dependencies); + + /// A set of module files in which we found a result. + typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet; + + /// Look for all of the module files with information about the given + /// identifier, e.g., a global function, variable, or type with that name. + /// + /// \param Name The identifier to look for. + /// + /// \param Hits Will be populated with the set of module files that have + /// information about this name. + /// + /// \returns true if the identifier is known to the index, false otherwise. + bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits); + + /// Note that the given module file has been loaded. + /// + /// \returns false if the global module index has information about this + /// module file, and true otherwise. + bool loadedModuleFile(ModuleFile *File); + + /// Print statistics to standard error. + void printStats(); + + /// Print debugging view to standard error. + void dump(); + + /// Write a global index into the given + /// + /// \param FileMgr The file manager to use to load module files. + /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and + /// creating modules. + /// \param Path The path to the directory containing module files, into + /// which the global index will be written. + static ErrorCode writeIndex(FileManager &FileMgr, + const PCHContainerReader &PCHContainerRdr, + llvm::StringRef Path); +}; +} + +#endif diff --git a/clang-r353983/include/clang/Serialization/Module.h b/clang-r353983/include/clang/Serialization/Module.h new file mode 100644 index 00000000..45f82d47 --- /dev/null +++ b/clang-r353983/include/clang/Serialization/Module.h @@ -0,0 +1,489 @@ +//===- Module.h - Module description ----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the Module class, which describes a module that has +// been loaded from an AST file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H +#define LLVM_CLANG_SERIALIZATION_MODULE_H + +#include "clang/Basic/Module.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/ModuleFileExtension.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/Endian.h" +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> +#include <vector> + +namespace clang { + +class FileEntry; + +namespace serialization { + +/// Specifies the kind of module that has been loaded. +enum ModuleKind { + /// File is an implicitly-loaded module. + MK_ImplicitModule, + + /// File is an explicitly-loaded module. + MK_ExplicitModule, + + /// File is a PCH file treated as such. + MK_PCH, + + /// File is a PCH file treated as the preamble. + MK_Preamble, + + /// File is a PCH file treated as the actual main file. + MK_MainFile, + + /// File is from a prebuilt module path. + MK_PrebuiltModule +}; + +/// 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. +class InputFile { + enum { + Overridden = 1, + OutOfDate = 2, + NotFound = 3 + }; + llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val; + +public: + InputFile() = default; + + InputFile(const FileEntry *File, + bool isOverridden = false, bool isOutOfDate = false) { + assert(!(isOverridden && isOutOfDate) && + "an overridden cannot be out-of-date"); + unsigned intVal = 0; + if (isOverridden) + intVal = Overridden; + else if (isOutOfDate) + intVal = OutOfDate; + Val.setPointerAndInt(File, intVal); + } + + static InputFile getNotFound() { + InputFile File; + File.Val.setInt(NotFound); + return File; + } + + const FileEntry *getFile() const { return Val.getPointer(); } + bool isOverridden() const { return Val.getInt() == Overridden; } + bool isOutOfDate() const { return Val.getInt() == OutOfDate; } + bool isNotFound() const { return Val.getInt() == NotFound; } +}; + +/// Information about a module that has been loaded by the ASTReader. +/// +/// Each instance of the Module class corresponds to a single AST file, which +/// may be a precompiled header, precompiled preamble, a module, or an AST file +/// of some sort loaded as the main file, all of which are specific formulations +/// of the general notion of a "module". A module may depend on any number of +/// other modules. +class ModuleFile { +public: + ModuleFile(ModuleKind Kind, unsigned Generation) + : Kind(Kind), Generation(Generation) {} + ~ModuleFile(); + + // === General information === + + /// The index of this module in the list of modules. + unsigned Index = 0; + + /// The type of this module. + ModuleKind Kind; + + /// The file name of the module file. + std::string FileName; + + /// The name of the module. + std::string ModuleName; + + /// The base directory of the module. + std::string BaseDirectory; + + std::string getTimestampFilename() const { + return FileName + ".timestamp"; + } + + /// The original source file name that was used to build the + /// primary AST file, which may have been modified for + /// relocatable-pch support. + std::string OriginalSourceFileName; + + /// The actual original source file name that was used to + /// build this AST file. + std::string ActualOriginalSourceFileName; + + /// The file ID for the original source file that was used to + /// 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 timestamps are included in this module file. + bool HasTimestamps = false; + + /// Whether the PCH has a corresponding object file. + bool PCHHasObjectFile = false; + + /// The file entry for the module file. + const FileEntry *File = nullptr; + + /// The signature of the module file, which may be used instead of the size + /// and modification time to identify this particular file. + ASTFileSignature Signature; + + /// Whether this module has been directly imported by the + /// user. + bool DirectlyImported = false; + + /// The generation of which this module file is a part. + unsigned Generation; + + /// The memory buffer that stores the data associated with + /// this AST file, owned by the PCMCache in the ModuleManager. + llvm::MemoryBuffer *Buffer; + + /// The size of this file, in bits. + uint64_t SizeInBits = 0; + + /// The global bit offset (or base) of this module + uint64_t GlobalBitOffset = 0; + + /// The serialized bitstream data for this file. + StringRef Data; + + /// The main bitstream cursor for the main block. + llvm::BitstreamCursor Stream; + + /// The source location where the module was explicitly or implicitly + /// imported in the local translation unit. + /// + /// If module A depends on and imports module B, both modules will have the + /// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a + /// source location inside module A). + /// + /// WARNING: This is largely useless. It doesn't tell you when a module was + /// made visible, just when the first submodule of that module was imported. + SourceLocation DirectImportLoc; + + /// The source location where this module was first imported. + SourceLocation ImportLoc; + + /// The first source location in this module. + SourceLocation FirstLoc; + + /// The list of extension readers that are attached to this module + /// file. + std::vector<std::unique_ptr<ModuleFileExtensionReader>> ExtensionReaders; + + /// The module offset map data for this file. If non-empty, the various + /// ContinuousRangeMaps described below have not yet been populated. + StringRef ModuleOffsetMap; + + // === Input Files === + + /// 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. + const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr; + + /// The input files that have been loaded from this AST file. + std::vector<InputFile> InputFilesLoaded; + + // All user input files reside at the index range [0, NumUserInputFiles), and + // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()). + unsigned NumUserInputFiles = 0; + + /// If non-zero, specifies the time when we last validated input + /// files. Zero means we never validated them. + /// + /// The time is specified in seconds since the start of the Epoch. + uint64_t InputFilesValidationTimestamp = 0; + + // === Source Locations === + + /// Cursor used to read source location entries. + llvm::BitstreamCursor SLocEntryCursor; + + /// The number of source location entries in this AST file. + unsigned LocalNumSLocEntries = 0; + + /// The base ID in the source manager's view of this module. + int SLocEntryBaseID = 0; + + /// The base offset in the source manager's view of this module. + unsigned SLocEntryBaseOffset = 0; + + /// Offsets for all of the source location entries in the + /// 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<uint32_t, int, 2> SLocRemap; + + // === Identifiers === + + /// The number of identifiers in this AST file. + unsigned LocalNumIdentifiers = 0; + + /// Offsets into the identifier table data. + /// + /// This array is indexed by the identifier ID (-1), and provides + /// the offset into IdentifierTableData where the string data is + /// stored. + const uint32_t *IdentifierOffsets = nullptr; + + /// Base identifier ID for identifiers local to this module. + serialization::IdentID BaseIdentifierID = 0; + + /// Remapping table for identifier IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap; + + /// Actual data for the on-disk hash table of identifiers. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for identifiers actually lives. + const char *IdentifierTableData = nullptr; + + /// A pointer to an on-disk hash table of opaque type + /// IdentifierHashTable. + void *IdentifierLookupTable = nullptr; + + /// Offsets of identifiers that we're going to preload within + /// IdentifierTableData. + std::vector<unsigned> PreloadIdentifierOffsets; + + // === Macros === + + /// The cursor to the start of the preprocessor block, which stores + /// all of the macro definitions. + llvm::BitstreamCursor MacroCursor; + + /// The number of macros in this AST file. + unsigned LocalNumMacros = 0; + + /// Offsets of macros in the preprocessor block. + /// + /// This array is indexed by the macro ID (-1), and provides + /// the offset into the preprocessor block where macro definitions are + /// stored. + const uint32_t *MacroOffsets = nullptr; + + /// Base macro ID for macros local to this module. + serialization::MacroID BaseMacroID = 0; + + /// Remapping table for macro IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> MacroRemap; + + /// The offset of the start of the set of defined macros. + uint64_t MacroStartOffset = 0; + + // === Detailed PreprocessingRecord === + + /// The cursor to the start of the (optional) detailed preprocessing + /// record block. + llvm::BitstreamCursor PreprocessorDetailCursor; + + /// The offset of the start of the preprocessor detail cursor. + uint64_t PreprocessorDetailStartOffset = 0; + + /// Base preprocessed entity ID for preprocessed entities local to + /// this module. + serialization::PreprocessedEntityID BasePreprocessedEntityID = 0; + + /// Remapping table for preprocessed entity IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap; + + const PPEntityOffset *PreprocessedEntityOffsets = nullptr; + unsigned NumPreprocessedEntities = 0; + + /// Base ID for preprocessed skipped ranges local to this module. + unsigned BasePreprocessedSkippedRangeID = 0; + + const PPSkippedRange *PreprocessedSkippedRangeOffsets = nullptr; + unsigned NumPreprocessedSkippedRanges = 0; + + // === Header search information === + + /// The number of local HeaderFileInfo structures. + unsigned LocalNumHeaderFileInfos = 0; + + /// Actual data for the on-disk hash table of header file + /// information. + /// + /// This pointer points into a memory buffer, where the on-disk hash + /// table for header file information actually lives. + const char *HeaderFileInfoTableData = nullptr; + + /// The on-disk hash table that contains information about each of + /// the header files. + void *HeaderFileInfoTable = nullptr; + + // === Submodule information === + + /// The number of submodules in this module. + unsigned LocalNumSubmodules = 0; + + /// Base submodule ID for submodules local to this module. + serialization::SubmoduleID BaseSubmoduleID = 0; + + /// Remapping table for submodule IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap; + + // === Selectors === + + /// The number of selectors new to this file. + /// + /// This is the number of entries in SelectorOffsets. + unsigned LocalNumSelectors = 0; + + /// Offsets into the selector lookup table's data array + /// where each selector resides. + const uint32_t *SelectorOffsets = nullptr; + + /// Base selector ID for selectors local to this module. + serialization::SelectorID BaseSelectorID = 0; + + /// Remapping table for selector IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> SelectorRemap; + + /// A pointer to the character data that comprises the selector table + /// + /// The SelectorOffsets table refers into this memory. + const unsigned char *SelectorLookupTableData = nullptr; + + /// A pointer to an on-disk hash table of opaque type + /// ASTSelectorLookupTable. + /// + /// This hash table provides the IDs of all selectors, and the associated + /// instance and factory methods. + void *SelectorLookupTable = nullptr; + + // === Declarations === + + /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It + /// has read all the abbreviations at the start of the block and is ready to + /// jump around with these in context. + llvm::BitstreamCursor DeclsCursor; + + /// The number of declarations in this AST file. + unsigned LocalNumDecls = 0; + + /// Offset of each declaration within the bitstream, indexed + /// by the declaration ID (-1). + const DeclOffset *DeclOffsets = nullptr; + + /// Base declaration ID for declarations local to this module. + serialization::DeclID BaseDeclID = 0; + + /// Remapping table for declaration IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> DeclRemap; + + /// Mapping from the module files that this module file depends on + /// to the base declaration ID for that module as it is understood within this + /// module. + /// + /// This is effectively a reverse global-to-local mapping for declaration + /// IDs, so that we can interpret a true global ID (for this translation unit) + /// as a local ID (for this module file). + llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs; + + /// Array of file-level DeclIDs sorted by file. + const serialization::DeclID *FileSortedDecls = nullptr; + unsigned NumFileSortedDecls = 0; + + /// Array of category list location information within this + /// module file, sorted by the definition ID. + const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr; + + /// The number of redeclaration info entries in ObjCCategoriesMap. + unsigned LocalNumObjCCategoriesInMap = 0; + + /// The Objective-C category lists for categories known to this + /// module. + SmallVector<uint64_t, 1> ObjCCategories; + + // === Types === + + /// The number of types in this AST file. + unsigned LocalNumTypes = 0; + + /// Offset of each type within the bitstream, indexed by the + /// type ID, or the representation of a Type*. + const uint32_t *TypeOffsets = nullptr; + + /// Base type ID for types local to this module as represented in + /// the global type ID space. + serialization::TypeID BaseTypeIndex = 0; + + /// Remapping table for type IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> TypeRemap; + + // === Miscellaneous === + + /// Diagnostic IDs and their mappings that the user changed. + SmallVector<uint64_t, 8> PragmaDiagMappings; + + /// List of modules which depend on this module + llvm::SetVector<ModuleFile *> ImportedBy; + + /// List of modules which this module depends on + llvm::SetVector<ModuleFile *> Imports; + + /// Determine whether this module was directly imported at + /// any point during translation. + bool isDirectlyImported() const { return DirectlyImported; } + + /// Is this a module file for a module (rather than a PCH or similar). + bool isModule() const { + return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule || + Kind == MK_PrebuiltModule; + } + + /// Dump debugging output for this module. + void dump(); +}; + +} // namespace serialization + +} // namespace clang + +#endif // LLVM_CLANG_SERIALIZATION_MODULE_H diff --git a/clang-r353983/include/clang/Serialization/ModuleFileExtension.h b/clang-r353983/include/clang/Serialization/ModuleFileExtension.h new file mode 100644 index 00000000..63562c0d --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ModuleFileExtension.h @@ -0,0 +1,148 @@ +//===-- ModuleFileExtension.h - Module File Extensions ----------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H +#define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H + +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include <memory> +#include <string> + +namespace llvm { +class BitstreamCursor; +class BitstreamWriter; +class hash_code; +class raw_ostream; +} + +namespace clang { + +class ASTReader; +class ASTWriter; +class Sema; + +namespace serialization { + class ModuleFile; +} // end namespace serialization + +/// Metadata for a module file extension. +struct ModuleFileExtensionMetadata { + /// The name used to identify this particular extension block within + /// the resulting module file. It should be unique to the particular + /// extension, because this name will be used to match the name of + /// an extension block to the appropriate reader. + std::string BlockName; + + /// The major version of the extension data. + unsigned MajorVersion; + + /// The minor version of the extension data. + unsigned MinorVersion; + + /// A string containing additional user information that will be + /// stored with the metadata. + std::string UserInfo; +}; + +class ModuleFileExtensionReader; +class ModuleFileExtensionWriter; + +/// An abstract superclass that describes a custom extension to the +/// module/precompiled header file format. +/// +/// A module file extension can introduce additional information into +/// compiled module files (.pcm) and precompiled headers (.pch) via a +/// custom writer that can then be accessed via a custom reader when +/// the module file or precompiled header is loaded. +class ModuleFileExtension { +public: + virtual ~ModuleFileExtension(); + + /// Retrieves the metadata for this module file extension. + virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0; + + /// Hash information about the presence of this extension into the + /// module hash code. + /// + /// 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 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; + + /// Create a new module file extension writer, which will be + /// responsible for writing the extension contents into a particular + /// module file. + virtual std::unique_ptr<ModuleFileExtensionWriter> + createExtensionWriter(ASTWriter &Writer) = 0; + + /// Create a new module file extension reader, given the + /// metadata read from the block and the cursor into the extension + /// block. + /// + /// May return null to indicate that an extension block with the + /// given metadata cannot be read. + virtual std::unique_ptr<ModuleFileExtensionReader> + createExtensionReader(const ModuleFileExtensionMetadata &Metadata, + ASTReader &Reader, serialization::ModuleFile &Mod, + const llvm::BitstreamCursor &Stream) = 0; +}; + +/// Abstract base class that writes a module file extension block into +/// a module file. +class ModuleFileExtensionWriter { + ModuleFileExtension *Extension; + +protected: + ModuleFileExtensionWriter(ModuleFileExtension *Extension) + : Extension(Extension) { } + +public: + virtual ~ModuleFileExtensionWriter(); + + /// Retrieve the module file extension with which this writer is + /// associated. + ModuleFileExtension *getExtension() const { return Extension; } + + /// Write the contents of the extension block into the given bitstream. + /// + /// Responsible for writing the contents of the extension into the + /// given stream. All of the contents should be written into custom + /// records with IDs >= FIRST_EXTENSION_RECORD_ID. + virtual void writeExtensionContents(Sema &SemaRef, + llvm::BitstreamWriter &Stream) = 0; +}; + +/// Abstract base class that reads a module file extension block from +/// a module file. +/// +/// Subclasses +class ModuleFileExtensionReader { + ModuleFileExtension *Extension; + +protected: + ModuleFileExtensionReader(ModuleFileExtension *Extension) + : Extension(Extension) { } + +public: + /// Retrieve the module file extension with which this reader is + /// associated. + ModuleFileExtension *getExtension() const { return Extension; } + + virtual ~ModuleFileExtensionReader(); +}; + +} // end namespace clang + +#endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H diff --git a/clang-r353983/include/clang/Serialization/ModuleManager.h b/clang-r353983/include/clang/Serialization/ModuleManager.h new file mode 100644 index 00000000..7bd7dc29 --- /dev/null +++ b/clang-r353983/include/clang/Serialization/ModuleManager.h @@ -0,0 +1,327 @@ +//===- ModuleManager.cpp - Module Manager -----------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the ModuleManager class, which manages a set of loaded +// modules for the ASTReader. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H +#define LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H + +#include "clang/Basic/LLVM.h" +#include "clang/Basic/Module.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Serialization/Module.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include <cstdint> +#include <ctime> +#include <memory> +#include <string> +#include <utility> + +namespace clang { + +class FileEntry; +class FileManager; +class GlobalModuleIndex; +class HeaderSearch; +class MemoryBufferCache; +class ModuleMap; +class PCHContainerReader; + +namespace serialization { + +/// Manages the set of modules loaded by an AST reader. +class ModuleManager { + /// The chain of AST files, in the order in which we started to load + /// them (this order isn't really useful for anything). + SmallVector<std::unique_ptr<ModuleFile>, 2> Chain; + + /// The chain of non-module PCH files. The first entry is the one named + /// by the user, the last one is the one that doesn't depend on anything + /// further. + SmallVector<ModuleFile *, 2> PCHChain; + + // The roots of the dependency DAG of AST files. This is used + // to implement short-circuiting logic when running DFS over the dependencies. + SmallVector<ModuleFile *, 2> Roots; + + /// All loaded modules, indexed by name. + llvm::DenseMap<const FileEntry *, ModuleFile *> Modules; + + /// FileManager that handles translating between filenames and + /// FileEntry *. + FileManager &FileMgr; + + /// Cache of PCM files. + IntrusiveRefCntPtr<MemoryBufferCache> PCMCache; + + /// Knows how to unwrap module containers. + const PCHContainerReader &PCHContainerRdr; + + /// Preprocessor's HeaderSearchInfo containing the module map. + const HeaderSearch &HeaderSearchInfo; + + /// A lookup of in-memory (virtual file) buffers + llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>> + InMemoryBuffers; + + /// The visitation order. + SmallVector<ModuleFile *, 4> VisitOrder; + + /// The list of module files that both we and the global module index + /// know about. + /// + /// Either the global index or the module manager may have modules that the + /// other does not know about, because the global index can be out-of-date + /// (in which case the module manager could have modules it does not) and + /// this particular translation unit might not have loaded all of the modules + /// known to the global index. + SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex; + + /// The global module index, if one is attached. + /// + /// The global module index will actually be owned by the ASTReader; this is + /// just an non-owning pointer. + GlobalModuleIndex *GlobalIndex = nullptr; + + /// State used by the "visit" operation to avoid malloc traffic in + /// calls to visit(). + struct VisitState { + explicit VisitState(unsigned N) : VisitNumber(N, 0) { + 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; + + /// The visit number of each module file, which indicates when + /// this module file was last visited. + SmallVector<unsigned, 4> VisitNumber; + + /// The next visit number to use to mark visited module files. + unsigned NextVisitNumber = 1; + + /// The next visit state. + VisitState *NextState = nullptr; + }; + + /// The first visit() state in the chain. + VisitState *FirstVisitState = nullptr; + + VisitState *allocateVisitState(); + void returnVisitState(VisitState *State); + +public: + using ModuleIterator = llvm::pointee_iterator< + SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>; + using ModuleConstIterator = llvm::pointee_iterator< + SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>; + using ModuleReverseIterator = llvm::pointee_iterator< + SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>; + using ModuleOffset = std::pair<uint32_t, StringRef>; + + explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, + const PCHContainerReader &PCHContainerRdr, + const HeaderSearch &HeaderSearchInfo); + ~ModuleManager(); + + /// Forward iterator to traverse all loaded modules. + ModuleIterator begin() { return Chain.begin(); } + + /// Forward iterator end-point to traverse all loaded modules + ModuleIterator end() { return Chain.end(); } + + /// Const forward iterator to traverse all loaded modules. + ModuleConstIterator begin() const { return Chain.begin(); } + + /// Const forward iterator end-point to traverse all loaded modules + ModuleConstIterator end() const { return Chain.end(); } + + /// Reverse iterator to traverse all loaded modules. + ModuleReverseIterator rbegin() { return Chain.rbegin(); } + + /// Reverse iterator end-point to traverse all loaded modules. + ModuleReverseIterator rend() { return Chain.rend(); } + + /// A range covering the PCH and preamble module files loaded. + llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator> + pch_modules() const { + return llvm::make_range(PCHChain.begin(), PCHChain.end()); + } + + /// Returns the primary module associated with the manager, that is, + /// the first module loaded + ModuleFile &getPrimaryModule() { return *Chain[0]; } + + /// Returns the primary module associated with the manager, that is, + /// the first module loaded. + ModuleFile &getPrimaryModule() const { return *Chain[0]; } + + /// Returns the module associated with the given index + ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; } + + /// Returns the module associated with the given file name. + ModuleFile *lookupByFileName(StringRef FileName) const; + + /// Returns the module associated with the given module name. + ModuleFile *lookupByModuleName(StringRef ModName) const; + + /// Returns the module associated with the given module file. + ModuleFile *lookup(const FileEntry *File) const; + + /// Returns the in-memory (virtual file) buffer with the given name + std::unique_ptr<llvm::MemoryBuffer> lookupBuffer(StringRef Name); + + /// Number of modules loaded + unsigned size() const { return Chain.size(); } + + /// The result of attempting to add a new module. + enum AddModuleResult { + /// The module file had already been loaded. + AlreadyLoaded, + + /// The module file was just loaded in response to this call. + NewlyLoaded, + + /// The module file is missing. + Missing, + + /// The module file is out-of-date. + OutOfDate + }; + + using ASTFileSignatureReader = ASTFileSignature (*)(StringRef); + + /// Attempts to create a new module and add it to the list of known + /// modules. + /// + /// \param FileName The file name of the module to be loaded. + /// + /// \param Type The kind of module being loaded. + /// + /// \param ImportLoc The location at which the module is imported. + /// + /// \param ImportedBy The module that is importing this module, or NULL if + /// this module is imported directly by the user. + /// + /// \param Generation The generation in which this module was loaded. + /// + /// \param ExpectedSize The expected size of the module file, used for + /// validation. This will be zero if unknown. + /// + /// \param ExpectedModTime The expected modification time of the module + /// file, used for validation. This will be zero if unknown. + /// + /// \param ExpectedSignature The expected signature of the module file, used + /// for validation. This will be zero if unknown. + /// + /// \param ReadSignature Reads the signature from an AST file without actually + /// loading it. + /// + /// \param Module A pointer to the module file if the module was successfully + /// loaded. + /// + /// \param ErrorStr Will be set to a non-empty string if any errors occurred + /// while trying to load the module. + /// + /// \return A pointer to the module that corresponds to this file name, + /// and a value indicating whether the module was loaded. + AddModuleResult addModule(StringRef FileName, ModuleKind Type, + SourceLocation ImportLoc, + ModuleFile *ImportedBy, unsigned Generation, + off_t ExpectedSize, time_t ExpectedModTime, + ASTFileSignature ExpectedSignature, + ASTFileSignatureReader ReadSignature, + ModuleFile *&Module, + std::string &ErrorStr); + + /// Remove the modules starting from First (to the end). + void removeModules(ModuleIterator First, + llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully, + ModuleMap *modMap); + + /// Add an in-memory buffer the list of known buffers + void addInMemoryBuffer(StringRef FileName, + std::unique_ptr<llvm::MemoryBuffer> Buffer); + + /// Set the global module index. + void setGlobalIndex(GlobalModuleIndex *Index); + + /// Notification from the AST reader that the given module file + /// has been "accepted", and will not (can not) be unloaded. + void moduleFileAccepted(ModuleFile *MF); + + /// Visit each of the modules. + /// + /// This routine visits each of the modules, starting with the + /// "root" modules that no other loaded modules depend on, and + /// proceeding to the leaf modules, visiting each module only once + /// during the traversal. + /// + /// This traversal is intended to support various "lookup" + /// operations that can find data in any of the loaded modules. + /// + /// \param Visitor A visitor function that will be invoked with each + /// module. The return value must be convertible to bool; when false, the + /// visitation continues to modules that the current module depends on. When + /// true, the visitation skips any modules that the current module depends on. + /// + /// \param ModuleFilesHit If non-NULL, contains the set of module files + /// that we know we need to visit because the global module index told us to. + /// Any module that is known to both the global module index and the module + /// manager that is *not* in this set can be skipped. + void visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, + llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr); + + /// Attempt to resolve the given module file name to a file entry. + /// + /// \param FileName The name of the module file. + /// + /// \param ExpectedSize The size that the module file is expected to have. + /// If the actual size differs, the resolver should return \c true. + /// + /// \param ExpectedModTime The modification time that the module file is + /// expected to have. If the actual modification time differs, the resolver + /// should return \c true. + /// + /// \param File Will be set to the file if there is one, or null + /// otherwise. + /// + /// \returns True if a file exists but does not meet the size/ + /// 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, + const FileEntry *&File); + + /// View the graphviz representation of the module graph. + void viewGraph(); + + MemoryBufferCache &getPCMCache() const { return *PCMCache; } +}; + +} // namespace serialization + +} // namespace clang + +#endif // LLVM_CLANG_SERIALIZATION_MODULEMANAGER_H diff --git a/clang-r353983/include/clang/Serialization/PCHContainerOperations.h b/clang-r353983/include/clang/Serialization/PCHContainerOperations.h new file mode 100644 index 00000000..33fc4a0a --- /dev/null +++ b/clang-r353983/include/clang/Serialization/PCHContainerOperations.h @@ -0,0 +1,116 @@ +//===--- Serialization/PCHContainerOperations.h - PCH Containers --*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_PCHCONTAINEROPERATIONS_H +#define LLVM_CLANG_SERIALIZATION_PCHCONTAINEROPERATIONS_H + +#include "clang/Basic/Module.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" +#include <memory> + +namespace llvm { +class raw_pwrite_stream; +} + +namespace clang { + +class ASTConsumer; +class CodeGenOptions; +class DiagnosticsEngine; +class CompilerInstance; + +struct PCHBuffer { + ASTFileSignature Signature; + llvm::SmallVector<char, 0> Data; + bool IsComplete; +}; + +/// This abstract interface provides operations for creating +/// containers for serialized ASTs (precompiled headers and clang +/// modules). +class PCHContainerWriter { +public: + virtual ~PCHContainerWriter() = 0; + virtual llvm::StringRef getFormat() const = 0; + + /// Return an ASTConsumer that can be chained with a + /// PCHGenerator that produces a wrapper file format containing a + /// serialized AST bitstream. + virtual std::unique_ptr<ASTConsumer> + CreatePCHContainerGenerator(CompilerInstance &CI, + const std::string &MainFileName, + const std::string &OutputFileName, + std::unique_ptr<llvm::raw_pwrite_stream> OS, + std::shared_ptr<PCHBuffer> Buffer) const = 0; +}; + +/// This abstract interface provides operations for unwrapping +/// containers for serialized ASTs (precompiled headers and clang +/// modules). +class PCHContainerReader { +public: + virtual ~PCHContainerReader() = 0; + /// Equivalent to the format passed to -fmodule-format= + virtual llvm::StringRef getFormat() const = 0; + + /// Returns the serialized AST inside the PCH container Buffer. + virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0; +}; + +/// Implements write operations for a raw pass-through PCH container. +class RawPCHContainerWriter : public PCHContainerWriter { + llvm::StringRef getFormat() const override { return "raw"; } + + /// Return an ASTConsumer that can be chained with a + /// PCHGenerator that writes the module to a flat file. + std::unique_ptr<ASTConsumer> + CreatePCHContainerGenerator(CompilerInstance &CI, + const std::string &MainFileName, + const std::string &OutputFileName, + std::unique_ptr<llvm::raw_pwrite_stream> OS, + std::shared_ptr<PCHBuffer> Buffer) const override; +}; + +/// Implements read operations for a raw pass-through PCH container. +class RawPCHContainerReader : public PCHContainerReader { + llvm::StringRef getFormat() const override { return "raw"; } + + /// Simply returns the buffer contained in Buffer. + llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override; +}; + +/// 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; +public: + /// Automatically registers a RawPCHContainerWriter and + /// RawPCHContainerReader. + PCHContainerOperations(); + void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) { + Writers[Writer->getFormat()] = std::move(Writer); + } + void registerReader(std::unique_ptr<PCHContainerReader> Reader) { + Readers[Reader->getFormat()] = std::move(Reader); + } + const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) { + return Writers[Format].get(); + } + const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) { + return Readers[Format].get(); + } + const PCHContainerReader &getRawReader() { + return *getReaderOrNull("raw"); + } +}; + +} + +#endif diff --git a/clang-r353983/include/clang/Serialization/SerializationDiagnostic.h b/clang-r353983/include/clang/Serialization/SerializationDiagnostic.h new file mode 100644 index 00000000..7fc93c11 --- /dev/null +++ b/clang-r353983/include/clang/Serialization/SerializationDiagnostic.h @@ -0,0 +1,14 @@ +//===--- SerializationDiagnostic.h - Serialization Diagnostics -*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H +#define LLVM_CLANG_SERIALIZATION_SERIALIZATIONDIAGNOSTIC_H + +#include "clang/Basic/DiagnosticSerialization.h" + +#endif |
