summaryrefslogtreecommitdiff
path: root/clang-r353983/include/clang/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/clang/Serialization')
-rw-r--r--clang-r353983/include/clang/Serialization/ASTBitCodes.h2142
-rw-r--r--clang-r353983/include/clang/Serialization/ASTDeserializationListener.h61
-rw-r--r--clang-r353983/include/clang/Serialization/ASTReader.h2698
-rw-r--r--clang-r353983/include/clang/Serialization/ASTWriter.h1011
-rw-r--r--clang-r353983/include/clang/Serialization/AttrPCHRead.inc2701
-rw-r--r--clang-r353983/include/clang/Serialization/AttrPCHWrite.inc2096
-rw-r--r--clang-r353983/include/clang/Serialization/ContinuousRangeMap.h141
-rw-r--r--clang-r353983/include/clang/Serialization/GlobalModuleIndex.h203
-rw-r--r--clang-r353983/include/clang/Serialization/Module.h489
-rw-r--r--clang-r353983/include/clang/Serialization/ModuleFileExtension.h148
-rw-r--r--clang-r353983/include/clang/Serialization/ModuleManager.h327
-rw-r--r--clang-r353983/include/clang/Serialization/PCHContainerOperations.h116
-rw-r--r--clang-r353983/include/clang/Serialization/SerializationDiagnostic.h14
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