summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/lib/Serialization
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 15:06:44 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 15:06:44 +0000
commitb64793999546ed8adebaeebd9d8345d18db8927d (patch)
tree4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/tools/clang/lib/Serialization
parentAdd support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff)
downloadwireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz
wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Serialization')
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTCommon.cpp445
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTCommon.h116
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTReader.cpp12563
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp4471
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h293
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp3418
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTWriter.cpp6955
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp2355
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp2368
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/CMakeLists.txt31
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp76
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp943
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/Module.cpp95
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ModuleFileExtension.cpp21
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/ModuleManager.cpp510
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/MultiOnDiskHashTable.h347
-rw-r--r--gnu/llvm/tools/clang/lib/Serialization/PCHContainerOperations.cpp69
17 files changed, 0 insertions, 35076 deletions
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTCommon.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTCommon.cpp
deleted file mode 100644
index ca826d83d47..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTCommon.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-//===--- ASTCommon.cpp - Common stuff for ASTReader/ASTWriter----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines common functions that both ASTReader and ASTWriter use.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTCommon.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Serialization/ASTDeserializationListener.h"
-#include "llvm/Support/DJB.h"
-
-using namespace clang;
-
-// Give ASTDeserializationListener's VTable a home.
-ASTDeserializationListener::~ASTDeserializationListener() { }
-
-serialization::TypeIdx
-serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
- unsigned ID = 0;
- switch (BT->getKind()) {
- case BuiltinType::Void:
- ID = PREDEF_TYPE_VOID_ID;
- break;
- case BuiltinType::Bool:
- ID = PREDEF_TYPE_BOOL_ID;
- break;
- case BuiltinType::Char_U:
- ID = PREDEF_TYPE_CHAR_U_ID;
- break;
- case BuiltinType::UChar:
- ID = PREDEF_TYPE_UCHAR_ID;
- break;
- case BuiltinType::UShort:
- ID = PREDEF_TYPE_USHORT_ID;
- break;
- case BuiltinType::UInt:
- ID = PREDEF_TYPE_UINT_ID;
- break;
- case BuiltinType::ULong:
- ID = PREDEF_TYPE_ULONG_ID;
- break;
- case BuiltinType::ULongLong:
- ID = PREDEF_TYPE_ULONGLONG_ID;
- break;
- case BuiltinType::UInt128:
- ID = PREDEF_TYPE_UINT128_ID;
- break;
- case BuiltinType::Char_S:
- ID = PREDEF_TYPE_CHAR_S_ID;
- break;
- case BuiltinType::SChar:
- ID = PREDEF_TYPE_SCHAR_ID;
- break;
- case BuiltinType::WChar_S:
- case BuiltinType::WChar_U:
- ID = PREDEF_TYPE_WCHAR_ID;
- break;
- case BuiltinType::Short:
- ID = PREDEF_TYPE_SHORT_ID;
- break;
- case BuiltinType::Int:
- ID = PREDEF_TYPE_INT_ID;
- break;
- case BuiltinType::Long:
- ID = PREDEF_TYPE_LONG_ID;
- break;
- case BuiltinType::LongLong:
- ID = PREDEF_TYPE_LONGLONG_ID;
- break;
- case BuiltinType::Int128:
- ID = PREDEF_TYPE_INT128_ID;
- break;
- case BuiltinType::Half:
- ID = PREDEF_TYPE_HALF_ID;
- break;
- case BuiltinType::Float:
- ID = PREDEF_TYPE_FLOAT_ID;
- break;
- case BuiltinType::Double:
- ID = PREDEF_TYPE_DOUBLE_ID;
- break;
- case BuiltinType::LongDouble:
- ID = PREDEF_TYPE_LONGDOUBLE_ID;
- break;
- case BuiltinType::ShortAccum:
- ID = PREDEF_TYPE_SHORT_ACCUM_ID;
- break;
- case BuiltinType::Accum:
- ID = PREDEF_TYPE_ACCUM_ID;
- break;
- case BuiltinType::LongAccum:
- ID = PREDEF_TYPE_LONG_ACCUM_ID;
- break;
- case BuiltinType::UShortAccum:
- ID = PREDEF_TYPE_USHORT_ACCUM_ID;
- break;
- case BuiltinType::UAccum:
- ID = PREDEF_TYPE_UACCUM_ID;
- break;
- case BuiltinType::ULongAccum:
- ID = PREDEF_TYPE_ULONG_ACCUM_ID;
- break;
- case BuiltinType::ShortFract:
- ID = PREDEF_TYPE_SHORT_FRACT_ID;
- break;
- case BuiltinType::Fract:
- ID = PREDEF_TYPE_FRACT_ID;
- break;
- case BuiltinType::LongFract:
- ID = PREDEF_TYPE_LONG_FRACT_ID;
- break;
- case BuiltinType::UShortFract:
- ID = PREDEF_TYPE_USHORT_FRACT_ID;
- break;
- case BuiltinType::UFract:
- ID = PREDEF_TYPE_UFRACT_ID;
- break;
- case BuiltinType::ULongFract:
- ID = PREDEF_TYPE_ULONG_FRACT_ID;
- break;
- case BuiltinType::SatShortAccum:
- ID = PREDEF_TYPE_SAT_SHORT_ACCUM_ID;
- break;
- case BuiltinType::SatAccum:
- ID = PREDEF_TYPE_SAT_ACCUM_ID;
- break;
- case BuiltinType::SatLongAccum:
- ID = PREDEF_TYPE_SAT_LONG_ACCUM_ID;
- break;
- case BuiltinType::SatUShortAccum:
- ID = PREDEF_TYPE_SAT_USHORT_ACCUM_ID;
- break;
- case BuiltinType::SatUAccum:
- ID = PREDEF_TYPE_SAT_UACCUM_ID;
- break;
- case BuiltinType::SatULongAccum:
- ID = PREDEF_TYPE_SAT_ULONG_ACCUM_ID;
- break;
- case BuiltinType::SatShortFract:
- ID = PREDEF_TYPE_SAT_SHORT_FRACT_ID;
- break;
- case BuiltinType::SatFract:
- ID = PREDEF_TYPE_SAT_FRACT_ID;
- break;
- case BuiltinType::SatLongFract:
- ID = PREDEF_TYPE_SAT_LONG_FRACT_ID;
- break;
- case BuiltinType::SatUShortFract:
- ID = PREDEF_TYPE_SAT_USHORT_FRACT_ID;
- break;
- case BuiltinType::SatUFract:
- ID = PREDEF_TYPE_SAT_UFRACT_ID;
- break;
- case BuiltinType::SatULongFract:
- ID = PREDEF_TYPE_SAT_ULONG_FRACT_ID;
- break;
- case BuiltinType::Float16:
- ID = PREDEF_TYPE_FLOAT16_ID;
- break;
- case BuiltinType::Float128:
- ID = PREDEF_TYPE_FLOAT128_ID;
- break;
- case BuiltinType::NullPtr:
- ID = PREDEF_TYPE_NULLPTR_ID;
- break;
- case BuiltinType::Char8:
- ID = PREDEF_TYPE_CHAR8_ID;
- break;
- case BuiltinType::Char16:
- ID = PREDEF_TYPE_CHAR16_ID;
- break;
- case BuiltinType::Char32:
- ID = PREDEF_TYPE_CHAR32_ID;
- break;
- case BuiltinType::Overload:
- ID = PREDEF_TYPE_OVERLOAD_ID;
- break;
- case BuiltinType::BoundMember:
- ID = PREDEF_TYPE_BOUND_MEMBER;
- break;
- case BuiltinType::PseudoObject:
- ID = PREDEF_TYPE_PSEUDO_OBJECT;
- break;
- case BuiltinType::Dependent:
- ID = PREDEF_TYPE_DEPENDENT_ID;
- break;
- case BuiltinType::UnknownAny:
- ID = PREDEF_TYPE_UNKNOWN_ANY;
- break;
- case BuiltinType::ARCUnbridgedCast:
- ID = PREDEF_TYPE_ARC_UNBRIDGED_CAST;
- break;
- case BuiltinType::ObjCId:
- ID = PREDEF_TYPE_OBJC_ID;
- break;
- case BuiltinType::ObjCClass:
- ID = PREDEF_TYPE_OBJC_CLASS;
- break;
- case BuiltinType::ObjCSel:
- ID = PREDEF_TYPE_OBJC_SEL;
- break;
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
- case BuiltinType::Id: \
- ID = PREDEF_TYPE_##Id##_ID; \
- break;
-#include "clang/Basic/OpenCLImageTypes.def"
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
- case BuiltinType::Id: \
- ID = PREDEF_TYPE_##Id##_ID; \
- break;
-#include "clang/Basic/OpenCLExtensionTypes.def"
- case BuiltinType::OCLSampler:
- ID = PREDEF_TYPE_SAMPLER_ID;
- break;
- case BuiltinType::OCLEvent:
- ID = PREDEF_TYPE_EVENT_ID;
- break;
- case BuiltinType::OCLClkEvent:
- ID = PREDEF_TYPE_CLK_EVENT_ID;
- break;
- case BuiltinType::OCLQueue:
- ID = PREDEF_TYPE_QUEUE_ID;
- break;
- case BuiltinType::OCLReserveID:
- ID = PREDEF_TYPE_RESERVE_ID_ID;
- break;
- case BuiltinType::BuiltinFn:
- ID = PREDEF_TYPE_BUILTIN_FN;
- break;
- case BuiltinType::OMPArraySection:
- ID = PREDEF_TYPE_OMP_ARRAY_SECTION;
- break;
- }
-
- return TypeIdx(ID);
-}
-
-unsigned serialization::ComputeHash(Selector Sel) {
- unsigned N = Sel.getNumArgs();
- if (N == 0)
- ++N;
- unsigned R = 5381;
- for (unsigned I = 0; I != N; ++I)
- if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
- R = llvm::djbHash(II->getName(), R);
- return R;
-}
-
-const DeclContext *
-serialization::getDefinitiveDeclContext(const DeclContext *DC) {
- switch (DC->getDeclKind()) {
- // These entities may have multiple definitions.
- case Decl::TranslationUnit:
- case Decl::ExternCContext:
- case Decl::Namespace:
- case Decl::LinkageSpec:
- case Decl::Export:
- return nullptr;
-
- // C/C++ tag types can only be defined in one place.
- case Decl::Enum:
- case Decl::Record:
- if (const TagDecl *Def = cast<TagDecl>(DC)->getDefinition())
- return Def;
- return nullptr;
-
- // FIXME: These can be defined in one place... except special member
- // functions and out-of-line definitions.
- case Decl::CXXRecord:
- case Decl::ClassTemplateSpecialization:
- case Decl::ClassTemplatePartialSpecialization:
- return nullptr;
-
- // Each function, method, and block declaration is its own DeclContext.
- case Decl::Function:
- case Decl::CXXMethod:
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- case Decl::CXXConversion:
- case Decl::ObjCMethod:
- case Decl::Block:
- case Decl::Captured:
- // Objective C categories, category implementations, and class
- // implementations can only be defined in one place.
- case Decl::ObjCCategory:
- case Decl::ObjCCategoryImpl:
- case Decl::ObjCImplementation:
- return DC;
-
- case Decl::ObjCProtocol:
- if (const ObjCProtocolDecl *Def
- = cast<ObjCProtocolDecl>(DC)->getDefinition())
- return Def;
- return nullptr;
-
- // FIXME: These are defined in one place, but properties in class extensions
- // end up being back-patched into the main interface. See
- // Sema::HandlePropertyInClassExtension for the offending code.
- case Decl::ObjCInterface:
- return nullptr;
-
- default:
- llvm_unreachable("Unhandled DeclContext in AST reader");
- }
-
- llvm_unreachable("Unhandled decl kind");
-}
-
-bool serialization::isRedeclarableDeclKind(unsigned Kind) {
- switch (static_cast<Decl::Kind>(Kind)) {
- case Decl::TranslationUnit:
- case Decl::ExternCContext:
- // Special case of a "merged" declaration.
- return true;
-
- case Decl::Namespace:
- case Decl::NamespaceAlias:
- case Decl::Typedef:
- case Decl::TypeAlias:
- case Decl::Enum:
- case Decl::Record:
- case Decl::CXXRecord:
- case Decl::ClassTemplateSpecialization:
- case Decl::ClassTemplatePartialSpecialization:
- case Decl::VarTemplateSpecialization:
- case Decl::VarTemplatePartialSpecialization:
- case Decl::Function:
- case Decl::CXXDeductionGuide:
- case Decl::CXXMethod:
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- case Decl::CXXConversion:
- case Decl::UsingShadow:
- case Decl::ConstructorUsingShadow:
- case Decl::Var:
- case Decl::FunctionTemplate:
- case Decl::ClassTemplate:
- case Decl::VarTemplate:
- case Decl::TypeAliasTemplate:
- case Decl::ObjCProtocol:
- case Decl::ObjCInterface:
- case Decl::Empty:
- return true;
-
- // Never redeclarable.
- case Decl::UsingDirective:
- case Decl::Label:
- case Decl::UnresolvedUsingTypename:
- case Decl::TemplateTypeParm:
- case Decl::EnumConstant:
- case Decl::UnresolvedUsingValue:
- case Decl::IndirectField:
- case Decl::Field:
- case Decl::MSProperty:
- case Decl::ObjCIvar:
- case Decl::ObjCAtDefsField:
- case Decl::NonTypeTemplateParm:
- case Decl::TemplateTemplateParm:
- case Decl::Using:
- case Decl::UsingPack:
- case Decl::ObjCMethod:
- case Decl::ObjCCategory:
- case Decl::ObjCCategoryImpl:
- case Decl::ObjCImplementation:
- case Decl::ObjCProperty:
- case Decl::ObjCCompatibleAlias:
- case Decl::LinkageSpec:
- case Decl::Export:
- case Decl::ObjCPropertyImpl:
- case Decl::PragmaComment:
- case Decl::PragmaDetectMismatch:
- case Decl::FileScopeAsm:
- case Decl::AccessSpec:
- case Decl::Friend:
- case Decl::FriendTemplate:
- case Decl::StaticAssert:
- case Decl::Block:
- case Decl::Captured:
- case Decl::ClassScopeFunctionSpecialization:
- case Decl::Import:
- case Decl::OMPThreadPrivate:
- case Decl::OMPRequires:
- case Decl::OMPCapturedExpr:
- case Decl::OMPDeclareReduction:
- case Decl::BuiltinTemplate:
- case Decl::Decomposition:
- case Decl::Binding:
- return false;
-
- // These indirectly derive from Redeclarable<T> but are not actually
- // redeclarable.
- case Decl::ImplicitParam:
- case Decl::ParmVar:
- case Decl::ObjCTypeParam:
- return false;
- }
-
- llvm_unreachable("Unhandled declaration kind");
-}
-
-bool serialization::needsAnonymousDeclarationNumber(const NamedDecl *D) {
- // Friend declarations in dependent contexts aren't anonymous in the usual
- // sense, but they cannot be found by name lookup in their semantic context
- // (or indeed in any context), so we treat them as anonymous.
- //
- // This doesn't apply to friend tag decls; Sema makes those available to name
- // lookup in the surrounding context.
- if (D->getFriendObjectKind() &&
- D->getLexicalDeclContext()->isDependentContext() && !isa<TagDecl>(D)) {
- // For function templates and class templates, the template is numbered and
- // not its pattern.
- if (auto *FD = dyn_cast<FunctionDecl>(D))
- return !FD->getDescribedFunctionTemplate();
- if (auto *RD = dyn_cast<CXXRecordDecl>(D))
- return !RD->getDescribedClassTemplate();
- return true;
- }
-
- // At block scope, we number everything that we need to deduplicate, since we
- // can't just use name matching to keep things lined up.
- // FIXME: This is only necessary for an inline function or a template or
- // similar.
- if (D->getLexicalDeclContext()->isFunctionOrMethod()) {
- if (auto *VD = dyn_cast<VarDecl>(D))
- return VD->isStaticLocal();
- // FIXME: What about CapturedDecls (and declarations nested within them)?
- return isa<TagDecl>(D) || isa<BlockDecl>(D);
- }
-
- // Otherwise, we only care about anonymous class members / block-scope decls.
- // FIXME: We need to handle lambdas and blocks within inline / templated
- // variables too.
- if (D->getDeclName() || !isa<CXXRecordDecl>(D->getLexicalDeclContext()))
- return false;
- return isa<TagDecl>(D) || isa<FieldDecl>(D);
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTCommon.h b/gnu/llvm/tools/clang/lib/Serialization/ASTCommon.h
deleted file mode 100644
index 12e26c1fc2b..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTCommon.h
+++ /dev/null
@@ -1,116 +0,0 @@
-//===- ASTCommon.h - Common stuff for ASTReader/ASTWriter -*- C++ -*-=========//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines common functions that both ASTReader and ASTWriter use.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTCOMMON_H
-#define LLVM_CLANG_LIB_SERIALIZATION_ASTCOMMON_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/Serialization/ASTBitCodes.h"
-
-namespace clang {
-
-namespace serialization {
-
-enum DeclUpdateKind {
- UPD_CXX_ADDED_IMPLICIT_MEMBER,
- UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
- UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
- UPD_CXX_ADDED_FUNCTION_DEFINITION,
- UPD_CXX_ADDED_VAR_DEFINITION,
- UPD_CXX_POINT_OF_INSTANTIATION,
- UPD_CXX_INSTANTIATED_CLASS_DEFINITION,
- UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT,
- UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER,
- UPD_CXX_RESOLVED_DTOR_DELETE,
- UPD_CXX_RESOLVED_EXCEPTION_SPEC,
- UPD_CXX_DEDUCED_RETURN_TYPE,
- UPD_DECL_MARKED_USED,
- UPD_MANGLING_NUMBER,
- UPD_STATIC_LOCAL_NUMBER,
- UPD_DECL_MARKED_OPENMP_THREADPRIVATE,
- UPD_DECL_MARKED_OPENMP_DECLARETARGET,
- UPD_DECL_EXPORTED,
- UPD_ADDED_ATTR_TO_RECORD
-};
-
-TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
-
-template <typename IdxForTypeTy>
-TypeID MakeTypeID(ASTContext &Context, QualType T, IdxForTypeTy IdxForType) {
- if (T.isNull())
- return PREDEF_TYPE_NULL_ID;
-
- unsigned FastQuals = T.getLocalFastQualifiers();
- T.removeLocalFastQualifiers();
-
- if (T.hasLocalNonFastQualifiers())
- return IdxForType(T).asTypeID(FastQuals);
-
- assert(!T.hasLocalQualifiers());
-
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
- return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
-
- if (T == Context.AutoDeductTy)
- return TypeIdx(PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
- if (T == Context.AutoRRefDeductTy)
- return TypeIdx(PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
-
- return IdxForType(T).asTypeID(FastQuals);
-}
-
-unsigned ComputeHash(Selector Sel);
-
-/// Retrieve the "definitive" declaration that provides all of the
-/// visible entries for the given declaration context, if there is one.
-///
-/// The "definitive" declaration is the only place where we need to look to
-/// find information about the declarations within the given declaration
-/// context. For example, C++ and Objective-C classes, C structs/unions, and
-/// Objective-C protocols, categories, and extensions are all defined in a
-/// single place in the source code, so they have definitive declarations
-/// associated with them. C++ namespaces, on the other hand, can have
-/// multiple definitions.
-const DeclContext *getDefinitiveDeclContext(const DeclContext *DC);
-
-/// Determine whether the given declaration kind is redeclarable.
-bool isRedeclarableDeclKind(unsigned Kind);
-
-/// Determine whether the given declaration needs an anonymous
-/// declaration number.
-bool needsAnonymousDeclarationNumber(const NamedDecl *D);
-
-/// Visit each declaration within \c DC that needs an anonymous
-/// declaration number and call \p Visit with the declaration and its number.
-template<typename Fn> void numberAnonymousDeclsWithin(const DeclContext *DC,
- Fn Visit) {
- unsigned Index = 0;
- for (Decl *LexicalD : DC->decls()) {
- // For a friend decl, we care about the declaration within it, if any.
- if (auto *FD = dyn_cast<FriendDecl>(LexicalD))
- LexicalD = FD->getFriendDecl();
-
- auto *ND = dyn_cast_or_null<NamedDecl>(LexicalD);
- if (!ND || !needsAnonymousDeclarationNumber(ND))
- continue;
-
- Visit(ND, Index++);
- }
-}
-
-} // namespace serialization
-
-} // namespace clang
-
-#endif
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTReader.cpp
deleted file mode 100644
index e0b2b24a0d3..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTReader.cpp
+++ /dev/null
@@ -1,12563 +0,0 @@
-//===- ASTReader.cpp - AST File Reader ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTReader class, which reads AST files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/ASTReader.h"
-#include "ASTCommon.h"
-#include "ASTReaderInternals.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTMutationListener.h"
-#include "clang/AST/ASTUnresolvedSet.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/ODRHash.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLoc.h"
-#include "clang/AST/TypeLocVisitor.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/CommentOptions.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/ObjCRuntime.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/PragmaKinds.h"
-#include "clang/Basic/Sanitizers.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/SourceManagerInternals.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Basic/Version.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/ModuleMap.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Lex/Token.h"
-#include "clang/Sema/ObjCMethodList.h"
-#include "clang/Sema/Scope.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Sema/Weak.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ASTDeserializationListener.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Serialization/GlobalModuleIndex.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/ModuleFileExtension.h"
-#include "clang/Serialization/ModuleManager.h"
-#include "clang/Serialization/PCHContainerOperations.h"
-#include "clang/Serialization/SerializationDiagnostic.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/FoldingSet.h"
-#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Compression.h"
-#include "llvm/Support/DJB.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/SaveAndRestore.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/VersionTuple.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <cstdio>
-#include <ctime>
-#include <iterator>
-#include <limits>
-#include <map>
-#include <memory>
-#include <string>
-#include <system_error>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-using namespace clang;
-using namespace clang::serialization;
-using namespace clang::serialization::reader;
-using llvm::BitstreamCursor;
-
-//===----------------------------------------------------------------------===//
-// ChainedASTReaderListener implementation
-//===----------------------------------------------------------------------===//
-
-bool
-ChainedASTReaderListener::ReadFullVersionInformation(StringRef FullVersion) {
- return First->ReadFullVersionInformation(FullVersion) ||
- Second->ReadFullVersionInformation(FullVersion);
-}
-
-void ChainedASTReaderListener::ReadModuleName(StringRef ModuleName) {
- First->ReadModuleName(ModuleName);
- Second->ReadModuleName(ModuleName);
-}
-
-void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) {
- First->ReadModuleMapFile(ModuleMapPath);
- Second->ReadModuleMapFile(ModuleMapPath);
-}
-
-bool
-ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
- bool Complain,
- bool AllowCompatibleDifferences) {
- return First->ReadLanguageOptions(LangOpts, Complain,
- AllowCompatibleDifferences) ||
- Second->ReadLanguageOptions(LangOpts, Complain,
- AllowCompatibleDifferences);
-}
-
-bool ChainedASTReaderListener::ReadTargetOptions(
- const TargetOptions &TargetOpts, bool Complain,
- bool AllowCompatibleDifferences) {
- return First->ReadTargetOptions(TargetOpts, Complain,
- AllowCompatibleDifferences) ||
- Second->ReadTargetOptions(TargetOpts, Complain,
- AllowCompatibleDifferences);
-}
-
-bool ChainedASTReaderListener::ReadDiagnosticOptions(
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
- return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
- Second->ReadDiagnosticOptions(DiagOpts, Complain);
-}
-
-bool
-ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts,
- bool Complain) {
- return First->ReadFileSystemOptions(FSOpts, Complain) ||
- Second->ReadFileSystemOptions(FSOpts, Complain);
-}
-
-bool ChainedASTReaderListener::ReadHeaderSearchOptions(
- const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath,
- bool Complain) {
- return First->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- Complain) ||
- Second->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- Complain);
-}
-
-bool ChainedASTReaderListener::ReadPreprocessorOptions(
- const PreprocessorOptions &PPOpts, bool Complain,
- std::string &SuggestedPredefines) {
- return First->ReadPreprocessorOptions(PPOpts, Complain,
- SuggestedPredefines) ||
- Second->ReadPreprocessorOptions(PPOpts, Complain, SuggestedPredefines);
-}
-
-void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M,
- unsigned Value) {
- First->ReadCounter(M, Value);
- Second->ReadCounter(M, Value);
-}
-
-bool ChainedASTReaderListener::needsInputFileVisitation() {
- return First->needsInputFileVisitation() ||
- Second->needsInputFileVisitation();
-}
-
-bool ChainedASTReaderListener::needsSystemInputFileVisitation() {
- return First->needsSystemInputFileVisitation() ||
- Second->needsSystemInputFileVisitation();
-}
-
-void ChainedASTReaderListener::visitModuleFile(StringRef Filename,
- ModuleKind Kind) {
- First->visitModuleFile(Filename, Kind);
- Second->visitModuleFile(Filename, Kind);
-}
-
-bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
- bool isSystem,
- bool isOverridden,
- bool isExplicitModule) {
- bool Continue = false;
- if (First->needsInputFileVisitation() &&
- (!isSystem || First->needsSystemInputFileVisitation()))
- Continue |= First->visitInputFile(Filename, isSystem, isOverridden,
- isExplicitModule);
- if (Second->needsInputFileVisitation() &&
- (!isSystem || Second->needsSystemInputFileVisitation()))
- Continue |= Second->visitInputFile(Filename, isSystem, isOverridden,
- isExplicitModule);
- return Continue;
-}
-
-void ChainedASTReaderListener::readModuleFileExtension(
- const ModuleFileExtensionMetadata &Metadata) {
- First->readModuleFileExtension(Metadata);
- Second->readModuleFileExtension(Metadata);
-}
-
-//===----------------------------------------------------------------------===//
-// PCH validator implementation
-//===----------------------------------------------------------------------===//
-
-ASTReaderListener::~ASTReaderListener() = default;
-
-/// Compare the given set of language options against an existing set of
-/// language options.
-///
-/// \param Diags If non-NULL, diagnostics will be emitted via this engine.
-/// \param AllowCompatibleDifferences If true, differences between compatible
-/// language options will be permitted.
-///
-/// \returns true if the languagae options mis-match, false otherwise.
-static bool checkLanguageOptions(const LangOptions &LangOpts,
- const LangOptions &ExistingLangOpts,
- DiagnosticsEngine *Diags,
- bool AllowCompatibleDifferences = true) {
-#define LANGOPT(Name, Bits, Default, Description) \
- if (ExistingLangOpts.Name != LangOpts.Name) { \
- if (Diags) \
- Diags->Report(diag::err_pch_langopt_mismatch) \
- << Description << LangOpts.Name << ExistingLangOpts.Name; \
- return true; \
- }
-
-#define VALUE_LANGOPT(Name, Bits, Default, Description) \
- if (ExistingLangOpts.Name != LangOpts.Name) { \
- if (Diags) \
- Diags->Report(diag::err_pch_langopt_value_mismatch) \
- << Description; \
- return true; \
- }
-
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) { \
- if (Diags) \
- Diags->Report(diag::err_pch_langopt_value_mismatch) \
- << Description; \
- return true; \
- }
-
-#define COMPATIBLE_LANGOPT(Name, Bits, Default, Description) \
- if (!AllowCompatibleDifferences) \
- LANGOPT(Name, Bits, Default, Description)
-
-#define COMPATIBLE_ENUM_LANGOPT(Name, Bits, Default, Description) \
- if (!AllowCompatibleDifferences) \
- ENUM_LANGOPT(Name, Bits, Default, Description)
-
-#define COMPATIBLE_VALUE_LANGOPT(Name, Bits, Default, Description) \
- if (!AllowCompatibleDifferences) \
- VALUE_LANGOPT(Name, Bits, Default, Description)
-
-#define BENIGN_LANGOPT(Name, Bits, Default, Description)
-#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
-#define BENIGN_VALUE_LANGOPT(Name, Type, Bits, Default, Description)
-#include "clang/Basic/LangOptions.def"
-
- if (ExistingLangOpts.ModuleFeatures != LangOpts.ModuleFeatures) {
- if (Diags)
- Diags->Report(diag::err_pch_langopt_value_mismatch) << "module features";
- return true;
- }
-
- if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {
- if (Diags)
- Diags->Report(diag::err_pch_langopt_value_mismatch)
- << "target Objective-C runtime";
- return true;
- }
-
- if (ExistingLangOpts.CommentOpts.BlockCommandNames !=
- LangOpts.CommentOpts.BlockCommandNames) {
- if (Diags)
- Diags->Report(diag::err_pch_langopt_value_mismatch)
- << "block command names";
- return true;
- }
-
- // Sanitizer feature mismatches are treated as compatible differences. If
- // compatible differences aren't allowed, we still only want to check for
- // mismatches of non-modular sanitizers (the only ones which can affect AST
- // generation).
- if (!AllowCompatibleDifferences) {
- SanitizerMask ModularSanitizers = getPPTransparentSanitizers();
- SanitizerSet ExistingSanitizers = ExistingLangOpts.Sanitize;
- SanitizerSet ImportedSanitizers = LangOpts.Sanitize;
- ExistingSanitizers.clear(ModularSanitizers);
- ImportedSanitizers.clear(ModularSanitizers);
- if (ExistingSanitizers.Mask != ImportedSanitizers.Mask) {
- const std::string Flag = "-fsanitize=";
- if (Diags) {
-#define SANITIZER(NAME, ID) \
- { \
- bool InExistingModule = ExistingSanitizers.has(SanitizerKind::ID); \
- bool InImportedModule = ImportedSanitizers.has(SanitizerKind::ID); \
- if (InExistingModule != InImportedModule) \
- Diags->Report(diag::err_pch_targetopt_feature_mismatch) \
- << InExistingModule << (Flag + NAME); \
- }
-#include "clang/Basic/Sanitizers.def"
- }
- return true;
- }
- }
-
- return false;
-}
-
-/// Compare the given set of target options against an existing set of
-/// target options.
-///
-/// \param Diags If non-NULL, diagnostics will be emitted via this engine.
-///
-/// \returns true if the target options mis-match, false otherwise.
-static bool checkTargetOptions(const TargetOptions &TargetOpts,
- const TargetOptions &ExistingTargetOpts,
- DiagnosticsEngine *Diags,
- bool AllowCompatibleDifferences = true) {
-#define CHECK_TARGET_OPT(Field, Name) \
- if (TargetOpts.Field != ExistingTargetOpts.Field) { \
- if (Diags) \
- Diags->Report(diag::err_pch_targetopt_mismatch) \
- << Name << TargetOpts.Field << ExistingTargetOpts.Field; \
- return true; \
- }
-
- // The triple and ABI must match exactly.
- CHECK_TARGET_OPT(Triple, "target");
- CHECK_TARGET_OPT(ABI, "target ABI");
-
- // We can tolerate different CPUs in many cases, notably when one CPU
- // supports a strict superset of another. When allowing compatible
- // differences skip this check.
- if (!AllowCompatibleDifferences)
- CHECK_TARGET_OPT(CPU, "target CPU");
-
-#undef CHECK_TARGET_OPT
-
- // Compare feature sets.
- SmallVector<StringRef, 4> ExistingFeatures(
- ExistingTargetOpts.FeaturesAsWritten.begin(),
- ExistingTargetOpts.FeaturesAsWritten.end());
- SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(),
- TargetOpts.FeaturesAsWritten.end());
- llvm::sort(ExistingFeatures);
- llvm::sort(ReadFeatures);
-
- // We compute the set difference in both directions explicitly so that we can
- // diagnose the differences differently.
- SmallVector<StringRef, 4> UnmatchedExistingFeatures, UnmatchedReadFeatures;
- std::set_difference(
- ExistingFeatures.begin(), ExistingFeatures.end(), ReadFeatures.begin(),
- ReadFeatures.end(), std::back_inserter(UnmatchedExistingFeatures));
- std::set_difference(ReadFeatures.begin(), ReadFeatures.end(),
- ExistingFeatures.begin(), ExistingFeatures.end(),
- std::back_inserter(UnmatchedReadFeatures));
-
- // If we are allowing compatible differences and the read feature set is
- // a strict subset of the existing feature set, there is nothing to diagnose.
- if (AllowCompatibleDifferences && UnmatchedReadFeatures.empty())
- return false;
-
- if (Diags) {
- for (StringRef Feature : UnmatchedReadFeatures)
- Diags->Report(diag::err_pch_targetopt_feature_mismatch)
- << /* is-existing-feature */ false << Feature;
- for (StringRef Feature : UnmatchedExistingFeatures)
- Diags->Report(diag::err_pch_targetopt_feature_mismatch)
- << /* is-existing-feature */ true << Feature;
- }
-
- return !UnmatchedReadFeatures.empty() || !UnmatchedExistingFeatures.empty();
-}
-
-bool
-PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts,
- bool Complain,
- bool AllowCompatibleDifferences) {
- const LangOptions &ExistingLangOpts = PP.getLangOpts();
- return checkLanguageOptions(LangOpts, ExistingLangOpts,
- Complain ? &Reader.Diags : nullptr,
- AllowCompatibleDifferences);
-}
-
-bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
- bool Complain,
- bool AllowCompatibleDifferences) {
- const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();
- return checkTargetOptions(TargetOpts, ExistingTargetOpts,
- Complain ? &Reader.Diags : nullptr,
- AllowCompatibleDifferences);
-}
-
-namespace {
-
-using MacroDefinitionsMap =
- llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>;
-using DeclsMap = llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8>>;
-
-} // namespace
-
-static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
- DiagnosticsEngine &Diags,
- bool Complain) {
- using Level = DiagnosticsEngine::Level;
-
- // Check current mappings for new -Werror mappings, and the stored mappings
- // for cases that were explicitly mapped to *not* be errors that are now
- // errors because of options like -Werror.
- DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags };
-
- for (DiagnosticsEngine *MappingSource : MappingSources) {
- for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) {
- diag::kind DiagID = DiagIDMappingPair.first;
- Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
- if (CurLevel < DiagnosticsEngine::Error)
- continue; // not significant
- Level StoredLevel =
- StoredDiags.getDiagnosticLevel(DiagID, SourceLocation());
- if (StoredLevel < DiagnosticsEngine::Error) {
- if (Complain)
- Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" +
- Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str();
- return true;
- }
- }
- }
-
- return false;
-}
-
-static bool isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
- diag::Severity Ext = Diags.getExtensionHandlingBehavior();
- if (Ext == diag::Severity::Warning && Diags.getWarningsAsErrors())
- return true;
- return Ext >= diag::Severity::Error;
-}
-
-static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
- DiagnosticsEngine &Diags,
- bool IsSystem, bool Complain) {
- // Top-level options
- if (IsSystem) {
- if (Diags.getSuppressSystemWarnings())
- return false;
- // If -Wsystem-headers was not enabled before, be conservative
- if (StoredDiags.getSuppressSystemWarnings()) {
- if (Complain)
- Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers";
- return true;
- }
- }
-
- if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()) {
- if (Complain)
- Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror";
- return true;
- }
-
- if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings() &&
- !StoredDiags.getEnableAllWarnings()) {
- if (Complain)
- Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror";
- return true;
- }
-
- if (isExtHandlingFromDiagsError(Diags) &&
- !isExtHandlingFromDiagsError(StoredDiags)) {
- if (Complain)
- Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors";
- return true;
- }
-
- return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
-}
-
-/// Return the top import module if it is implicit, nullptr otherwise.
-static Module *getTopImportImplicitModule(ModuleManager &ModuleMgr,
- Preprocessor &PP) {
- // If the original import came from a file explicitly generated by the user,
- // don't check the diagnostic mappings.
- // FIXME: currently this is approximated by checking whether this is not a
- // module import of an implicitly-loaded module file.
- // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
- // the transitive closure of its imports, since unrelated modules cannot be
- // imported until after this module finishes validation.
- ModuleFile *TopImport = &*ModuleMgr.rbegin();
- while (!TopImport->ImportedBy.empty())
- TopImport = TopImport->ImportedBy[0];
- if (TopImport->Kind != MK_ImplicitModule)
- return nullptr;
-
- StringRef ModuleName = TopImport->ModuleName;
- assert(!ModuleName.empty() && "diagnostic options read before module name");
-
- Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
- assert(M && "missing module");
- return M;
-}
-
-bool PCHValidator::ReadDiagnosticOptions(
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
- DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
- IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
- new DiagnosticsEngine(DiagIDs, DiagOpts.get()));
- // This should never fail, because we would have processed these options
- // before writing them to an ASTFile.
- ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
-
- ModuleManager &ModuleMgr = Reader.getModuleManager();
- assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
-
- Module *TopM = getTopImportImplicitModule(ModuleMgr, PP);
- if (!TopM)
- return false;
-
- // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
- // contains the union of their flags.
- return checkDiagnosticMappings(*Diags, ExistingDiags, TopM->IsSystem,
- Complain);
-}
-
-/// Collect the macro definitions provided by the given preprocessor
-/// options.
-static void
-collectMacroDefinitions(const PreprocessorOptions &PPOpts,
- MacroDefinitionsMap &Macros,
- SmallVectorImpl<StringRef> *MacroNames = nullptr) {
- for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
- StringRef Macro = PPOpts.Macros[I].first;
- bool IsUndef = PPOpts.Macros[I].second;
-
- std::pair<StringRef, StringRef> MacroPair = Macro.split('=');
- StringRef MacroName = MacroPair.first;
- StringRef MacroBody = MacroPair.second;
-
- // For an #undef'd macro, we only care about the name.
- if (IsUndef) {
- if (MacroNames && !Macros.count(MacroName))
- MacroNames->push_back(MacroName);
-
- Macros[MacroName] = std::make_pair("", true);
- continue;
- }
-
- // For a #define'd macro, figure out the actual definition.
- if (MacroName.size() == Macro.size())
- MacroBody = "1";
- else {
- // Note: GCC drops anything following an end-of-line character.
- StringRef::size_type End = MacroBody.find_first_of("\n\r");
- MacroBody = MacroBody.substr(0, End);
- }
-
- if (MacroNames && !Macros.count(MacroName))
- MacroNames->push_back(MacroName);
- Macros[MacroName] = std::make_pair(MacroBody, false);
- }
-}
-
-/// Check the preprocessor options deserialized from the control block
-/// against the preprocessor options in an existing preprocessor.
-///
-/// \param Diags If non-null, produce diagnostics for any mismatches incurred.
-/// \param Validate If true, validate preprocessor options. If false, allow
-/// macros defined by \p ExistingPPOpts to override those defined by
-/// \p PPOpts in SuggestedPredefines.
-static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
- const PreprocessorOptions &ExistingPPOpts,
- DiagnosticsEngine *Diags,
- FileManager &FileMgr,
- std::string &SuggestedPredefines,
- const LangOptions &LangOpts,
- bool Validate = true) {
- // Check macro definitions.
- MacroDefinitionsMap ASTFileMacros;
- collectMacroDefinitions(PPOpts, ASTFileMacros);
- MacroDefinitionsMap ExistingMacros;
- SmallVector<StringRef, 4> ExistingMacroNames;
- collectMacroDefinitions(ExistingPPOpts, ExistingMacros, &ExistingMacroNames);
-
- for (unsigned I = 0, N = ExistingMacroNames.size(); I != N; ++I) {
- // Dig out the macro definition in the existing preprocessor options.
- StringRef MacroName = ExistingMacroNames[I];
- std::pair<StringRef, bool> Existing = ExistingMacros[MacroName];
-
- // Check whether we know anything about this macro name or not.
- llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>::iterator Known =
- ASTFileMacros.find(MacroName);
- if (!Validate || Known == ASTFileMacros.end()) {
- // FIXME: Check whether this identifier was referenced anywhere in the
- // AST file. If so, we should reject the AST file. Unfortunately, this
- // information isn't in the control block. What shall we do about it?
-
- if (Existing.second) {
- SuggestedPredefines += "#undef ";
- SuggestedPredefines += MacroName.str();
- SuggestedPredefines += '\n';
- } else {
- SuggestedPredefines += "#define ";
- SuggestedPredefines += MacroName.str();
- SuggestedPredefines += ' ';
- SuggestedPredefines += Existing.first.str();
- SuggestedPredefines += '\n';
- }
- continue;
- }
-
- // If the macro was defined in one but undef'd in the other, we have a
- // conflict.
- if (Existing.second != Known->second.second) {
- if (Diags) {
- Diags->Report(diag::err_pch_macro_def_undef)
- << MacroName << Known->second.second;
- }
- return true;
- }
-
- // If the macro was #undef'd in both, or if the macro bodies are identical,
- // it's fine.
- if (Existing.second || Existing.first == Known->second.first)
- continue;
-
- // The macro bodies differ; complain.
- if (Diags) {
- Diags->Report(diag::err_pch_macro_def_conflict)
- << MacroName << Known->second.first << Existing.first;
- }
- return true;
- }
-
- // Check whether we're using predefines.
- if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines && Validate) {
- if (Diags) {
- Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines;
- }
- return true;
- }
-
- // Detailed record is important since it is used for the module cache hash.
- if (LangOpts.Modules &&
- PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord && Validate) {
- if (Diags) {
- Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord;
- }
- return true;
- }
-
- // Compute the #include and #include_macros lines we need.
- for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) {
- StringRef File = ExistingPPOpts.Includes[I];
-
- if (!ExistingPPOpts.ImplicitPCHInclude.empty() &&
- !ExistingPPOpts.PCHThroughHeader.empty()) {
- // In case the through header is an include, we must add all the includes
- // to the predefines so the start point can be determined.
- SuggestedPredefines += "#include \"";
- SuggestedPredefines += File;
- SuggestedPredefines += "\"\n";
- continue;
- }
-
- if (File == ExistingPPOpts.ImplicitPCHInclude)
- continue;
-
- if (std::find(PPOpts.Includes.begin(), PPOpts.Includes.end(), File)
- != PPOpts.Includes.end())
- continue;
-
- SuggestedPredefines += "#include \"";
- SuggestedPredefines += File;
- SuggestedPredefines += "\"\n";
- }
-
- for (unsigned I = 0, N = ExistingPPOpts.MacroIncludes.size(); I != N; ++I) {
- StringRef File = ExistingPPOpts.MacroIncludes[I];
- if (std::find(PPOpts.MacroIncludes.begin(), PPOpts.MacroIncludes.end(),
- File)
- != PPOpts.MacroIncludes.end())
- continue;
-
- SuggestedPredefines += "#__include_macros \"";
- SuggestedPredefines += File;
- SuggestedPredefines += "\"\n##\n";
- }
-
- return false;
-}
-
-bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
- std::string &SuggestedPredefines) {
- const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts();
-
- return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
- Complain? &Reader.Diags : nullptr,
- PP.getFileManager(),
- SuggestedPredefines,
- PP.getLangOpts());
-}
-
-bool SimpleASTReaderListener::ReadPreprocessorOptions(
- const PreprocessorOptions &PPOpts,
- bool Complain,
- std::string &SuggestedPredefines) {
- return checkPreprocessorOptions(PPOpts,
- PP.getPreprocessorOpts(),
- nullptr,
- PP.getFileManager(),
- SuggestedPredefines,
- PP.getLangOpts(),
- false);
-}
-
-/// Check the header search options deserialized from the control block
-/// against the header search options in an existing preprocessor.
-///
-/// \param Diags If non-null, produce diagnostics for any mismatches incurred.
-static bool checkHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- StringRef ExistingModuleCachePath,
- DiagnosticsEngine *Diags,
- const LangOptions &LangOpts) {
- if (LangOpts.Modules) {
- if (SpecificModuleCachePath != ExistingModuleCachePath) {
- if (Diags)
- Diags->Report(diag::err_pch_modulecache_mismatch)
- << SpecificModuleCachePath << ExistingModuleCachePath;
- return true;
- }
- }
-
- return false;
-}
-
-bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- bool Complain) {
- return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- PP.getHeaderSearchInfo().getModuleCachePath(),
- Complain ? &Reader.Diags : nullptr,
- PP.getLangOpts());
-}
-
-void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) {
- PP.setCounterValue(Value);
-}
-
-//===----------------------------------------------------------------------===//
-// AST reader implementation
-//===----------------------------------------------------------------------===//
-
-void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener,
- bool TakeOwnership) {
- DeserializationListener = Listener;
- OwnsDeserializationListener = TakeOwnership;
-}
-
-unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
- return serialization::ComputeHash(Sel);
-}
-
-std::pair<unsigned, unsigned>
-ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
- using namespace llvm::support;
-
- unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
- unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
- return std::make_pair(KeyLen, DataLen);
-}
-
-ASTSelectorLookupTrait::internal_key_type
-ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
- using namespace llvm::support;
-
- SelectorTable &SelTable = Reader.getContext().Selectors;
- unsigned N = endian::readNext<uint16_t, little, unaligned>(d);
- IdentifierInfo *FirstII = Reader.getLocalIdentifier(
- F, endian::readNext<uint32_t, little, unaligned>(d));
- if (N == 0)
- return SelTable.getNullarySelector(FirstII);
- else if (N == 1)
- return SelTable.getUnarySelector(FirstII);
-
- SmallVector<IdentifierInfo *, 16> Args;
- Args.push_back(FirstII);
- for (unsigned I = 1; I != N; ++I)
- Args.push_back(Reader.getLocalIdentifier(
- F, endian::readNext<uint32_t, little, unaligned>(d)));
-
- return SelTable.getSelector(N, Args.data());
-}
-
-ASTSelectorLookupTrait::data_type
-ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
- unsigned DataLen) {
- using namespace llvm::support;
-
- data_type Result;
-
- Result.ID = Reader.getGlobalSelectorID(
- F, endian::readNext<uint32_t, little, unaligned>(d));
- unsigned FullInstanceBits = endian::readNext<uint16_t, little, unaligned>(d);
- unsigned FullFactoryBits = endian::readNext<uint16_t, little, unaligned>(d);
- Result.InstanceBits = FullInstanceBits & 0x3;
- Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1;
- Result.FactoryBits = FullFactoryBits & 0x3;
- Result.FactoryHasMoreThanOneDecl = (FullFactoryBits >> 2) & 0x1;
- unsigned NumInstanceMethods = FullInstanceBits >> 3;
- unsigned NumFactoryMethods = FullFactoryBits >> 3;
-
- // Load instance methods
- for (unsigned I = 0; I != NumInstanceMethods; ++I) {
- if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
- F, endian::readNext<uint32_t, little, unaligned>(d)))
- Result.Instance.push_back(Method);
- }
-
- // Load factory methods
- for (unsigned I = 0; I != NumFactoryMethods; ++I) {
- if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
- F, endian::readNext<uint32_t, little, unaligned>(d)))
- Result.Factory.push_back(Method);
- }
-
- return Result;
-}
-
-unsigned ASTIdentifierLookupTraitBase::ComputeHash(const internal_key_type& a) {
- return llvm::djbHash(a);
-}
-
-std::pair<unsigned, unsigned>
-ASTIdentifierLookupTraitBase::ReadKeyDataLength(const unsigned char*& d) {
- using namespace llvm::support;
-
- unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
- unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
- return std::make_pair(KeyLen, DataLen);
-}
-
-ASTIdentifierLookupTraitBase::internal_key_type
-ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) {
- assert(n >= 2 && d[n-1] == '\0');
- return StringRef((const char*) d, n-1);
-}
-
-/// Whether the given identifier is "interesting".
-static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II,
- bool IsModule) {
- return II.hadMacroDefinition() ||
- II.isPoisoned() ||
- (IsModule ? II.hasRevertedBuiltin() : II.getObjCOrBuiltinID()) ||
- II.hasRevertedTokenIDToIdentifier() ||
- (!(IsModule && Reader.getPreprocessor().getLangOpts().CPlusPlus) &&
- II.getFETokenInfo());
-}
-
-static bool readBit(unsigned &Bits) {
- bool Value = Bits & 0x1;
- Bits >>= 1;
- return Value;
-}
-
-IdentID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) {
- using namespace llvm::support;
-
- unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
- return Reader.getGlobalIdentifierID(F, RawID >> 1);
-}
-
-static void markIdentifierFromAST(ASTReader &Reader, IdentifierInfo &II) {
- if (!II.isFromAST()) {
- II.setIsFromAST();
- bool IsModule = Reader.getPreprocessor().getCurrentModule() != nullptr;
- if (isInterestingIdentifier(Reader, II, IsModule))
- II.setChangedSinceDeserialization();
- }
-}
-
-IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
- const unsigned char* d,
- unsigned DataLen) {
- using namespace llvm::support;
-
- unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
- bool IsInteresting = RawID & 0x01;
-
- // Wipe out the "is interesting" bit.
- RawID = RawID >> 1;
-
- // Build the IdentifierInfo and link the identifier ID with it.
- IdentifierInfo *II = KnownII;
- if (!II) {
- II = &Reader.getIdentifierTable().getOwn(k);
- KnownII = II;
- }
- markIdentifierFromAST(Reader, *II);
- Reader.markIdentifierUpToDate(II);
-
- IdentID ID = Reader.getGlobalIdentifierID(F, RawID);
- if (!IsInteresting) {
- // For uninteresting identifiers, there's nothing else to do. Just notify
- // the reader that we've finished loading this identifier.
- Reader.SetIdentifierInfo(ID, II);
- return II;
- }
-
- unsigned ObjCOrBuiltinID = endian::readNext<uint16_t, little, unaligned>(d);
- unsigned Bits = endian::readNext<uint16_t, little, unaligned>(d);
- bool CPlusPlusOperatorKeyword = readBit(Bits);
- bool HasRevertedTokenIDToIdentifier = readBit(Bits);
- bool HasRevertedBuiltin = readBit(Bits);
- bool Poisoned = readBit(Bits);
- bool ExtensionToken = readBit(Bits);
- bool HadMacroDefinition = readBit(Bits);
-
- assert(Bits == 0 && "Extra bits in the identifier?");
- DataLen -= 8;
-
- // Set or check the various bits in the IdentifierInfo structure.
- // Token IDs are read-only.
- if (HasRevertedTokenIDToIdentifier && II->getTokenID() != tok::identifier)
- II->revertTokenIDToIdentifier();
- if (!F.isModule())
- II->setObjCOrBuiltinID(ObjCOrBuiltinID);
- else if (HasRevertedBuiltin && II->getBuiltinID()) {
- II->revertBuiltin();
- assert((II->hasRevertedBuiltin() ||
- II->getObjCOrBuiltinID() == ObjCOrBuiltinID) &&
- "Incorrect ObjC keyword or builtin ID");
- }
- assert(II->isExtensionToken() == ExtensionToken &&
- "Incorrect extension token flag");
- (void)ExtensionToken;
- if (Poisoned)
- II->setIsPoisoned(true);
- assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
- "Incorrect C++ operator keyword flag");
- (void)CPlusPlusOperatorKeyword;
-
- // If this identifier is a macro, deserialize the macro
- // definition.
- if (HadMacroDefinition) {
- uint32_t MacroDirectivesOffset =
- endian::readNext<uint32_t, little, unaligned>(d);
- DataLen -= 4;
-
- Reader.addPendingMacro(II, &F, MacroDirectivesOffset);
- }
-
- Reader.SetIdentifierInfo(ID, II);
-
- // Read all of the declarations visible at global scope with this
- // name.
- if (DataLen > 0) {
- SmallVector<uint32_t, 4> DeclIDs;
- for (; DataLen > 0; DataLen -= 4)
- DeclIDs.push_back(Reader.getGlobalDeclID(
- F, endian::readNext<uint32_t, little, unaligned>(d)));
- Reader.SetGloballyVisibleDecls(II, DeclIDs);
- }
-
- return II;
-}
-
-DeclarationNameKey::DeclarationNameKey(DeclarationName Name)
- : Kind(Name.getNameKind()) {
- switch (Kind) {
- case DeclarationName::Identifier:
- Data = (uint64_t)Name.getAsIdentifierInfo();
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr();
- break;
- case DeclarationName::CXXOperatorName:
- Data = Name.getCXXOverloadedOperator();
- break;
- case DeclarationName::CXXLiteralOperatorName:
- Data = (uint64_t)Name.getCXXLiteralIdentifier();
- break;
- case DeclarationName::CXXDeductionGuideName:
- Data = (uint64_t)Name.getCXXDeductionGuideTemplate()
- ->getDeclName().getAsIdentifierInfo();
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- Data = 0;
- break;
- }
-}
-
-unsigned DeclarationNameKey::getHash() const {
- llvm::FoldingSetNodeID ID;
- ID.AddInteger(Kind);
-
- switch (Kind) {
- case DeclarationName::Identifier:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXDeductionGuideName:
- ID.AddString(((IdentifierInfo*)Data)->getName());
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- ID.AddInteger(serialization::ComputeHash(Selector(Data)));
- break;
- case DeclarationName::CXXOperatorName:
- ID.AddInteger((OverloadedOperatorKind)Data);
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
-
- return ID.ComputeHash();
-}
-
-ModuleFile *
-ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) {
- using namespace llvm::support;
-
- uint32_t ModuleFileID = endian::readNext<uint32_t, little, unaligned>(d);
- return Reader.getLocalModuleFile(F, ModuleFileID);
-}
-
-std::pair<unsigned, unsigned>
-ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char *&d) {
- using namespace llvm::support;
-
- unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
- unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
- return std::make_pair(KeyLen, DataLen);
-}
-
-ASTDeclContextNameLookupTrait::internal_key_type
-ASTDeclContextNameLookupTrait::ReadKey(const unsigned char *d, unsigned) {
- using namespace llvm::support;
-
- auto Kind = (DeclarationName::NameKind)*d++;
- uint64_t Data;
- switch (Kind) {
- case DeclarationName::Identifier:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXDeductionGuideName:
- Data = (uint64_t)Reader.getLocalIdentifier(
- F, endian::readNext<uint32_t, little, unaligned>(d));
- break;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- Data =
- (uint64_t)Reader.getLocalSelector(
- F, endian::readNext<uint32_t, little, unaligned>(
- d)).getAsOpaquePtr();
- break;
- case DeclarationName::CXXOperatorName:
- Data = *d++; // OverloadedOperatorKind
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- Data = 0;
- break;
- }
-
- return DeclarationNameKey(Kind, Data);
-}
-
-void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type,
- const unsigned char *d,
- unsigned DataLen,
- data_type_builder &Val) {
- using namespace llvm::support;
-
- for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) {
- uint32_t LocalID = endian::readNext<uint32_t, little, unaligned>(d);
- Val.insert(Reader.getGlobalDeclID(F, LocalID));
- }
-}
-
-bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
- BitstreamCursor &Cursor,
- uint64_t Offset,
- DeclContext *DC) {
- assert(Offset != 0);
-
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Offset);
-
- RecordData Record;
- StringRef Blob;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record, &Blob);
- if (RecCode != DECL_CONTEXT_LEXICAL) {
- Error("Expected lexical block");
- return true;
- }
-
- assert(!isa<TranslationUnitDecl>(DC) &&
- "expected a TU_UPDATE_LEXICAL record for TU");
- // If we are handling a C++ class template instantiation, we can see multiple
- // lexical updates for the same record. It's important that we select only one
- // of them, so that field numbering works properly. Just pick the first one we
- // see.
- auto &Lex = LexicalDecls[DC];
- if (!Lex.first) {
- Lex = std::make_pair(
- &M, llvm::makeArrayRef(
- reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
- Blob.data()),
- Blob.size() / 4));
- }
- DC->setHasExternalLexicalStorage(true);
- return false;
-}
-
-bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
- BitstreamCursor &Cursor,
- uint64_t Offset,
- DeclID ID) {
- assert(Offset != 0);
-
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Offset);
-
- RecordData Record;
- StringRef Blob;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record, &Blob);
- if (RecCode != DECL_CONTEXT_VISIBLE) {
- Error("Expected visible lookup table block");
- return true;
- }
-
- // We can't safely determine the primary context yet, so delay attaching the
- // lookup table until we're done with recursive deserialization.
- auto *Data = (const unsigned char*)Blob.data();
- PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&M, Data});
- return false;
-}
-
-void ASTReader::Error(StringRef Msg) const {
- Error(diag::err_fe_pch_malformed, Msg);
- if (PP.getLangOpts().Modules && !Diags.isDiagnosticInFlight() &&
- !PP.getHeaderSearchInfo().getModuleCachePath().empty()) {
- Diag(diag::note_module_cache_path)
- << PP.getHeaderSearchInfo().getModuleCachePath();
- }
-}
-
-void ASTReader::Error(unsigned DiagID,
- StringRef Arg1, StringRef Arg2) const {
- if (Diags.isDiagnosticInFlight())
- Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);
- else
- Diag(DiagID) << Arg1 << Arg2;
-}
-
-//===----------------------------------------------------------------------===//
-// Source Manager Deserialization
-//===----------------------------------------------------------------------===//
-
-/// Read the line table in the source manager block.
-/// \returns true if there was an error.
-bool ASTReader::ParseLineTable(ModuleFile &F,
- const RecordData &Record) {
- unsigned Idx = 0;
- LineTableInfo &LineTable = SourceMgr.getLineTable();
-
- // Parse the file names
- std::map<int, int> FileIDs;
- FileIDs[-1] = -1; // For unspecified filenames.
- for (unsigned I = 0; Record[Idx]; ++I) {
- // Extract the file name
- auto Filename = ReadPath(F, Record, Idx);
- FileIDs[I] = LineTable.getLineTableFilenameID(Filename);
- }
- ++Idx;
-
- // Parse the line entries
- std::vector<LineEntry> Entries;
- while (Idx < Record.size()) {
- int FID = Record[Idx++];
- assert(FID >= 0 && "Serialized line entries for non-local file.");
- // Remap FileID from 1-based old view.
- FID += F.SLocEntryBaseID - 1;
-
- // Extract the line entries
- unsigned NumEntries = Record[Idx++];
- assert(NumEntries && "no line entries for file ID");
- Entries.clear();
- Entries.reserve(NumEntries);
- for (unsigned I = 0; I != NumEntries; ++I) {
- unsigned FileOffset = Record[Idx++];
- unsigned LineNo = Record[Idx++];
- int FilenameID = FileIDs[Record[Idx++]];
- SrcMgr::CharacteristicKind FileKind
- = (SrcMgr::CharacteristicKind)Record[Idx++];
- unsigned IncludeOffset = Record[Idx++];
- Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
- FileKind, IncludeOffset));
- }
- LineTable.AddEntry(FileID::get(FID), Entries);
- }
-
- return false;
-}
-
-/// Read a source manager block
-bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
- using namespace SrcMgr;
-
- BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
-
- // Set the source-location entry cursor to the current position in
- // the stream. This cursor will be used to read the contents of the
- // source manager block initially, and then lazily read
- // source-location entries as needed.
- SLocEntryCursor = F.Stream;
-
- // The stream itself is going to skip over the source manager block.
- if (F.Stream.SkipBlock()) {
- Error("malformed block record in AST file");
- return true;
- }
-
- // Enter the source manager block.
- if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
- Error("malformed source manager block record in AST file");
- return true;
- }
-
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks();
-
- switch (E.Kind) {
- case llvm::BitstreamEntry::SubBlock: // Handled for us already.
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return true;
- case llvm::BitstreamEntry::EndBlock:
- return false;
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read a record.
- Record.clear();
- StringRef Blob;
- switch (SLocEntryCursor.readRecord(E.ID, Record, &Blob)) {
- default: // Default behavior: ignore.
- break;
-
- case SM_SLOC_FILE_ENTRY:
- case SM_SLOC_BUFFER_ENTRY:
- case SM_SLOC_EXPANSION_ENTRY:
- // Once we hit one of the source location entries, we're done.
- return false;
- }
- }
-}
-
-/// If a header file is not found at the path that we expect it to be
-/// and the PCH file was moved from its original location, try to resolve the
-/// file by assuming that header+PCH were moved together and the header is in
-/// the same place relative to the PCH.
-static std::string
-resolveFileRelativeToOriginalDir(const std::string &Filename,
- const std::string &OriginalDir,
- const std::string &CurrDir) {
- assert(OriginalDir != CurrDir &&
- "No point trying to resolve the file if the PCH dir didn't change");
-
- using namespace llvm::sys;
-
- SmallString<128> filePath(Filename);
- fs::make_absolute(filePath);
- assert(path::is_absolute(OriginalDir));
- SmallString<128> currPCHPath(CurrDir);
-
- path::const_iterator fileDirI = path::begin(path::parent_path(filePath)),
- fileDirE = path::end(path::parent_path(filePath));
- path::const_iterator origDirI = path::begin(OriginalDir),
- origDirE = path::end(OriginalDir);
- // Skip the common path components from filePath and OriginalDir.
- while (fileDirI != fileDirE && origDirI != origDirE &&
- *fileDirI == *origDirI) {
- ++fileDirI;
- ++origDirI;
- }
- for (; origDirI != origDirE; ++origDirI)
- path::append(currPCHPath, "..");
- path::append(currPCHPath, fileDirI, fileDirE);
- path::append(currPCHPath, path::filename(Filename));
- return currPCHPath.str();
-}
-
-bool ASTReader::ReadSLocEntry(int ID) {
- if (ID == 0)
- return false;
-
- if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
- Error("source location entry ID out-of-range for AST file");
- return true;
- }
-
- // Local helper to read the (possibly-compressed) buffer data following the
- // entry record.
- auto ReadBuffer = [this](
- BitstreamCursor &SLocEntryCursor,
- StringRef Name) -> std::unique_ptr<llvm::MemoryBuffer> {
- RecordData Record;
- StringRef Blob;
- unsigned Code = SLocEntryCursor.ReadCode();
- unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob);
-
- if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
- if (!llvm::zlib::isAvailable()) {
- Error("zlib is not available");
- return nullptr;
- }
- SmallString<0> Uncompressed;
- if (llvm::Error E =
- llvm::zlib::uncompress(Blob, Uncompressed, Record[0])) {
- Error("could not decompress embedded file contents: " +
- llvm::toString(std::move(E)));
- return nullptr;
- }
- return llvm::MemoryBuffer::getMemBufferCopy(Uncompressed, Name);
- } else if (RecCode == SM_SLOC_BUFFER_BLOB) {
- return llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name, true);
- } else {
- Error("AST record has invalid code");
- return nullptr;
- }
- };
-
- ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second;
- F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);
- BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
- unsigned BaseOffset = F->SLocEntryBaseOffset;
-
- ++NumSLocEntriesRead;
- llvm::BitstreamEntry Entry = SLocEntryCursor.advance();
- if (Entry.Kind != llvm::BitstreamEntry::Record) {
- Error("incorrectly-formatted source location entry in AST file");
- return true;
- }
-
- RecordData Record;
- StringRef Blob;
- switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) {
- default:
- Error("incorrectly-formatted source location entry in AST file");
- return true;
-
- case SM_SLOC_FILE_ENTRY: {
- // We will detect whether a file changed and return 'Failure' for it, but
- // we will also try to fail gracefully by setting up the SLocEntry.
- unsigned InputID = Record[4];
- InputFile IF = getInputFile(*F, InputID);
- const FileEntry *File = IF.getFile();
- bool OverriddenBuffer = IF.isOverridden();
-
- // Note that we only check if a File was returned. If it was out-of-date
- // we have complained but we will continue creating a FileID to recover
- // gracefully.
- if (!File)
- return true;
-
- SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
- if (IncludeLoc.isInvalid() && F->Kind != MK_MainFile) {
- // This is the module's main file.
- IncludeLoc = getImportLocation(F);
- }
- SrcMgr::CharacteristicKind
- FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
- FileID FID = SourceMgr.createFileID(File, IncludeLoc, FileCharacter,
- ID, BaseOffset + Record[0]);
- SrcMgr::FileInfo &FileInfo =
- const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile());
- FileInfo.NumCreatedFIDs = Record[5];
- if (Record[3])
- FileInfo.setHasLineDirectives();
-
- const DeclID *FirstDecl = F->FileSortedDecls + Record[6];
- unsigned NumFileDecls = Record[7];
- if (NumFileDecls && ContextObj) {
- assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?");
- FileDeclIDs[FID] = FileDeclsInfo(F, llvm::makeArrayRef(FirstDecl,
- NumFileDecls));
- }
-
- const SrcMgr::ContentCache *ContentCache
- = SourceMgr.getOrCreateContentCache(File, isSystem(FileCharacter));
- if (OverriddenBuffer && !ContentCache->BufferOverridden &&
- ContentCache->ContentsEntry == ContentCache->OrigEntry &&
- !ContentCache->getRawBuffer()) {
- auto Buffer = ReadBuffer(SLocEntryCursor, File->getName());
- if (!Buffer)
- return true;
- SourceMgr.overrideFileContents(File, std::move(Buffer));
- }
-
- break;
- }
-
- case SM_SLOC_BUFFER_ENTRY: {
- const char *Name = Blob.data();
- unsigned Offset = Record[0];
- SrcMgr::CharacteristicKind
- FileCharacter = (SrcMgr::CharacteristicKind)Record[2];
- SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
- if (IncludeLoc.isInvalid() && F->isModule()) {
- IncludeLoc = getImportLocation(F);
- }
-
- auto Buffer = ReadBuffer(SLocEntryCursor, Name);
- if (!Buffer)
- return true;
- SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID,
- BaseOffset + Offset, IncludeLoc);
- break;
- }
-
- case SM_SLOC_EXPANSION_ENTRY: {
- SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1]);
- SourceMgr.createExpansionLoc(SpellingLoc,
- ReadSourceLocation(*F, Record[2]),
- ReadSourceLocation(*F, Record[3]),
- Record[5],
- Record[4],
- ID,
- BaseOffset + Record[0]);
- break;
- }
- }
-
- return false;
-}
-
-std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {
- if (ID == 0)
- return std::make_pair(SourceLocation(), "");
-
- if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) {
- Error("source location entry ID out-of-range for AST file");
- return std::make_pair(SourceLocation(), "");
- }
-
- // Find which module file this entry lands in.
- ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second;
- if (!M->isModule())
- return std::make_pair(SourceLocation(), "");
-
- // FIXME: Can we map this down to a particular submodule? That would be
- // ideal.
- return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));
-}
-
-/// Find the location where the module F is imported.
-SourceLocation ASTReader::getImportLocation(ModuleFile *F) {
- if (F->ImportLoc.isValid())
- return F->ImportLoc;
-
- // Otherwise we have a PCH. It's considered to be "imported" at the first
- // location of its includer.
- if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
- // Main file is the importer.
- assert(SourceMgr.getMainFileID().isValid() && "missing main file");
- return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
- }
- return F->ImportedBy[0]->FirstLoc;
-}
-
-/// 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.
-bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) {
- if (Cursor.EnterSubBlock(BlockID))
- return true;
-
- while (true) {
- uint64_t Offset = Cursor.GetCurrentBitNo();
- unsigned Code = Cursor.ReadCode();
-
- // We expect all abbrevs to be at the start of the block.
- if (Code != llvm::bitc::DEFINE_ABBREV) {
- Cursor.JumpToBit(Offset);
- return false;
- }
- Cursor.ReadAbbrevRecord();
- }
-}
-
-Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record,
- unsigned &Idx) {
- Token Tok;
- Tok.startToken();
- Tok.setLocation(ReadSourceLocation(F, Record, Idx));
- Tok.setLength(Record[Idx++]);
- if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++]))
- Tok.setIdentifierInfo(II);
- Tok.setKind((tok::TokenKind)Record[Idx++]);
- Tok.setFlag((Token::TokenFlags)Record[Idx++]);
- return Tok;
-}
-
-MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
- BitstreamCursor &Stream = F.MacroCursor;
-
- // Keep track of where we are in the stream, then jump back there
- // after reading this macro.
- SavedStreamPosition SavedPosition(Stream);
-
- Stream.JumpToBit(Offset);
- RecordData Record;
- SmallVector<IdentifierInfo*, 16> MacroParams;
- MacroInfo *Macro = nullptr;
-
- while (true) {
- // Advance to the next record, but if we get to the end of the block, don't
- // pop it (removing all the abbreviations from the cursor) since we want to
- // be able to reseek within the block and read entries.
- unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd;
- llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(Flags);
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock: // Handled for us already.
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return Macro;
- case llvm::BitstreamEntry::EndBlock:
- return Macro;
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read a record.
- Record.clear();
- PreprocessorRecordTypes RecType =
- (PreprocessorRecordTypes)Stream.readRecord(Entry.ID, Record);
- switch (RecType) {
- case PP_MODULE_MACRO:
- case PP_MACRO_DIRECTIVE_HISTORY:
- return Macro;
-
- case PP_MACRO_OBJECT_LIKE:
- case PP_MACRO_FUNCTION_LIKE: {
- // If we already have a macro, that means that we've hit the end
- // of the definition of the macro we were looking for. We're
- // done.
- if (Macro)
- return Macro;
-
- unsigned NextIndex = 1; // Skip identifier ID.
- SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
- MacroInfo *MI = PP.AllocateMacroInfo(Loc);
- MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex));
- MI->setIsUsed(Record[NextIndex++]);
- MI->setUsedForHeaderGuard(Record[NextIndex++]);
-
- if (RecType == PP_MACRO_FUNCTION_LIKE) {
- // Decode function-like macro info.
- bool isC99VarArgs = Record[NextIndex++];
- bool isGNUVarArgs = Record[NextIndex++];
- bool hasCommaPasting = Record[NextIndex++];
- MacroParams.clear();
- unsigned NumArgs = Record[NextIndex++];
- for (unsigned i = 0; i != NumArgs; ++i)
- MacroParams.push_back(getLocalIdentifier(F, Record[NextIndex++]));
-
- // Install function-like macro info.
- MI->setIsFunctionLike();
- if (isC99VarArgs) MI->setIsC99Varargs();
- if (isGNUVarArgs) MI->setIsGNUVarargs();
- if (hasCommaPasting) MI->setHasCommaPasting();
- MI->setParameterList(MacroParams, PP.getPreprocessorAllocator());
- }
-
- // Remember that we saw this macro last so that we add the tokens that
- // form its body to it.
- Macro = MI;
-
- if (NextIndex + 1 == Record.size() && PP.getPreprocessingRecord() &&
- Record[NextIndex]) {
- // We have a macro definition. Register the association
- PreprocessedEntityID
- GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]);
- PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
- PreprocessingRecord::PPEntityID PPID =
- PPRec.getPPEntityID(GlobalID - 1, /*isLoaded=*/true);
- MacroDefinitionRecord *PPDef = cast_or_null<MacroDefinitionRecord>(
- PPRec.getPreprocessedEntity(PPID));
- if (PPDef)
- PPRec.RegisterMacroDefinition(Macro, PPDef);
- }
-
- ++NumMacrosRead;
- break;
- }
-
- case PP_TOKEN: {
- // If we see a TOKEN before a PP_MACRO_*, then the file is
- // erroneous, just pretend we didn't see this.
- if (!Macro) break;
-
- unsigned Idx = 0;
- Token Tok = ReadToken(F, Record, Idx);
- Macro->AddTokenToBody(Tok);
- break;
- }
- }
- }
-}
-
-PreprocessedEntityID
-ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M,
- unsigned LocalID) const {
- if (!M.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(M);
-
- ContinuousRangeMap<uint32_t, int, 2>::const_iterator
- I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);
- assert(I != M.PreprocessedEntityRemap.end()
- && "Invalid index into preprocessed entity index remap");
-
- return LocalID + I->second;
-}
-
-unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) {
- return llvm::hash_combine(ikey.Size, ikey.ModTime);
-}
-
-HeaderFileInfoTrait::internal_key_type
-HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) {
- internal_key_type ikey = {FE->getSize(),
- M.HasTimestamps ? FE->getModificationTime() : 0,
- FE->getName(), /*Imported*/ false};
- return ikey;
-}
-
-bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) {
- if (a.Size != b.Size || (a.ModTime && b.ModTime && a.ModTime != b.ModTime))
- return false;
-
- if (llvm::sys::path::is_absolute(a.Filename) && a.Filename == b.Filename)
- return true;
-
- // Determine whether the actual files are equivalent.
- FileManager &FileMgr = Reader.getFileManager();
- auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* {
- if (!Key.Imported)
- return FileMgr.getFile(Key.Filename);
-
- std::string Resolved = Key.Filename;
- Reader.ResolveImportedPath(M, Resolved);
- return FileMgr.getFile(Resolved);
- };
-
- const FileEntry *FEA = GetFile(a);
- const FileEntry *FEB = GetFile(b);
- return FEA && FEA == FEB;
-}
-
-std::pair<unsigned, unsigned>
-HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
- using namespace llvm::support;
-
- unsigned KeyLen = (unsigned) endian::readNext<uint16_t, little, unaligned>(d);
- unsigned DataLen = (unsigned) *d++;
- return std::make_pair(KeyLen, DataLen);
-}
-
-HeaderFileInfoTrait::internal_key_type
-HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {
- using namespace llvm::support;
-
- internal_key_type ikey;
- ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d));
- ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d));
- ikey.Filename = (const char *)d;
- ikey.Imported = true;
- return ikey;
-}
-
-HeaderFileInfoTrait::data_type
-HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
- unsigned DataLen) {
- using namespace llvm::support;
-
- const unsigned char *End = d + DataLen;
- HeaderFileInfo HFI;
- unsigned Flags = *d++;
- // FIXME: Refactor with mergeHeaderFileInfo in HeaderSearch.cpp.
- HFI.isImport |= (Flags >> 5) & 0x01;
- HFI.isPragmaOnce |= (Flags >> 4) & 0x01;
- HFI.DirInfo = (Flags >> 1) & 0x07;
- HFI.IndexHeaderMapHeader = Flags & 0x01;
- // FIXME: Find a better way to handle this. Maybe just store a
- // "has been included" flag?
- HFI.NumIncludes = std::max(endian::readNext<uint16_t, little, unaligned>(d),
- HFI.NumIncludes);
- HFI.ControllingMacroID = Reader.getGlobalIdentifierID(
- M, endian::readNext<uint32_t, little, unaligned>(d));
- if (unsigned FrameworkOffset =
- endian::readNext<uint32_t, little, unaligned>(d)) {
- // The framework offset is 1 greater than the actual offset,
- // since 0 is used as an indicator for "no framework name".
- StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
- HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
- }
-
- assert((End - d) % 4 == 0 &&
- "Wrong data length in HeaderFileInfo deserialization");
- while (d != End) {
- uint32_t LocalSMID = endian::readNext<uint32_t, little, unaligned>(d);
- auto HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>(LocalSMID & 3);
- LocalSMID >>= 2;
-
- // This header is part of a module. Associate it with the module to enable
- // implicit module import.
- SubmoduleID GlobalSMID = Reader.getGlobalSubmoduleID(M, LocalSMID);
- Module *Mod = Reader.getSubmodule(GlobalSMID);
- FileManager &FileMgr = Reader.getFileManager();
- ModuleMap &ModMap =
- Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap();
-
- std::string Filename = key.Filename;
- if (key.Imported)
- Reader.ResolveImportedPath(M, Filename);
- // FIXME: This is not always the right filename-as-written, but we're not
- // going to use this information to rebuild the module, so it doesn't make
- // a lot of difference.
- Module::Header H = { key.Filename, FileMgr.getFile(Filename) };
- ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
- HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
- }
-
- // This HeaderFileInfo was externally loaded.
- HFI.External = true;
- HFI.IsValid = true;
- return HFI;
-}
-
-void ASTReader::addPendingMacro(IdentifierInfo *II,
- ModuleFile *M,
- uint64_t MacroDirectivesOffset) {
- assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
- PendingMacroIDs[II].push_back(PendingMacroInfo(M, MacroDirectivesOffset));
-}
-
-void ASTReader::ReadDefinedMacros() {
- // Note that we are loading defined macros.
- Deserializing Macros(this);
-
- for (ModuleFile &I : llvm::reverse(ModuleMgr)) {
- BitstreamCursor &MacroCursor = I.MacroCursor;
-
- // If there was no preprocessor block, skip this file.
- if (MacroCursor.getBitcodeBytes().empty())
- continue;
-
- BitstreamCursor Cursor = MacroCursor;
- Cursor.JumpToBit(I.MacroStartOffset);
-
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks();
-
- switch (E.Kind) {
- case llvm::BitstreamEntry::SubBlock: // Handled for us already.
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return;
- case llvm::BitstreamEntry::EndBlock:
- goto NextCursor;
-
- case llvm::BitstreamEntry::Record:
- Record.clear();
- switch (Cursor.readRecord(E.ID, Record)) {
- default: // Default behavior: ignore.
- break;
-
- case PP_MACRO_OBJECT_LIKE:
- case PP_MACRO_FUNCTION_LIKE: {
- IdentifierInfo *II = getLocalIdentifier(I, Record[0]);
- if (II->isOutOfDate())
- updateOutOfDateIdentifier(*II);
- break;
- }
-
- case PP_TOKEN:
- // Ignore tokens.
- break;
- }
- break;
- }
- }
- NextCursor: ;
- }
-}
-
-namespace {
-
- /// Visitor class used to look up identifirs in an AST file.
- class IdentifierLookupVisitor {
- StringRef Name;
- unsigned NameHash;
- unsigned PriorGeneration;
- unsigned &NumIdentifierLookups;
- unsigned &NumIdentifierLookupHits;
- IdentifierInfo *Found = nullptr;
-
- public:
- IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration,
- unsigned &NumIdentifierLookups,
- unsigned &NumIdentifierLookupHits)
- : Name(Name), NameHash(ASTIdentifierLookupTrait::ComputeHash(Name)),
- PriorGeneration(PriorGeneration),
- NumIdentifierLookups(NumIdentifierLookups),
- NumIdentifierLookupHits(NumIdentifierLookupHits) {}
-
- bool operator()(ModuleFile &M) {
- // If we've already searched this module file, skip it now.
- if (M.Generation <= PriorGeneration)
- return true;
-
- ASTIdentifierLookupTable *IdTable
- = (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
- if (!IdTable)
- return false;
-
- ASTIdentifierLookupTrait Trait(IdTable->getInfoObj().getReader(), M,
- Found);
- ++NumIdentifierLookups;
- ASTIdentifierLookupTable::iterator Pos =
- IdTable->find_hashed(Name, NameHash, &Trait);
- if (Pos == IdTable->end())
- return false;
-
- // Dereferencing the iterator has the effect of building the
- // IdentifierInfo node and populating it with the various
- // declarations it needs.
- ++NumIdentifierLookupHits;
- Found = *Pos;
- return true;
- }
-
- // Retrieve the identifier info found within the module
- // files.
- IdentifierInfo *getIdentifierInfo() const { return Found; }
- };
-
-} // namespace
-
-void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
- // Note that we are loading an identifier.
- Deserializing AnIdentifier(this);
-
- unsigned PriorGeneration = 0;
- if (getContext().getLangOpts().Modules)
- PriorGeneration = IdentifierGeneration[&II];
-
- // If there is a global index, look there first to determine which modules
- // provably do not have any results for this identifier.
- GlobalModuleIndex::HitSet Hits;
- GlobalModuleIndex::HitSet *HitsPtr = nullptr;
- if (!loadGlobalIndex()) {
- if (GlobalIndex->lookupIdentifier(II.getName(), Hits)) {
- HitsPtr = &Hits;
- }
- }
-
- IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration,
- NumIdentifierLookups,
- NumIdentifierLookupHits);
- ModuleMgr.visit(Visitor, HitsPtr);
- markIdentifierUpToDate(&II);
-}
-
-void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
- if (!II)
- return;
-
- II->setOutOfDate(false);
-
- // Update the generation for this identifier.
- if (getContext().getLangOpts().Modules)
- IdentifierGeneration[II] = getGeneration();
-}
-
-void ASTReader::resolvePendingMacro(IdentifierInfo *II,
- const PendingMacroInfo &PMInfo) {
- ModuleFile &M = *PMInfo.M;
-
- BitstreamCursor &Cursor = M.MacroCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(PMInfo.MacroDirectivesOffset);
-
- struct ModuleMacroRecord {
- SubmoduleID SubModID;
- MacroInfo *MI;
- SmallVector<SubmoduleID, 8> Overrides;
- };
- llvm::SmallVector<ModuleMacroRecord, 8> ModuleMacros;
-
- // We expect to see a sequence of PP_MODULE_MACRO records listing exported
- // macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete
- // macro histroy.
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry =
- Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
- if (Entry.Kind != llvm::BitstreamEntry::Record) {
- Error("malformed block record in AST file");
- return;
- }
-
- Record.clear();
- switch ((PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record)) {
- case PP_MACRO_DIRECTIVE_HISTORY:
- break;
-
- case PP_MODULE_MACRO: {
- ModuleMacros.push_back(ModuleMacroRecord());
- auto &Info = ModuleMacros.back();
- Info.SubModID = getGlobalSubmoduleID(M, Record[0]);
- Info.MI = getMacro(getGlobalMacroID(M, Record[1]));
- for (int I = 2, N = Record.size(); I != N; ++I)
- Info.Overrides.push_back(getGlobalSubmoduleID(M, Record[I]));
- continue;
- }
-
- default:
- Error("malformed block record in AST file");
- return;
- }
-
- // We found the macro directive history; that's the last record
- // for this macro.
- break;
- }
-
- // Module macros are listed in reverse dependency order.
- {
- std::reverse(ModuleMacros.begin(), ModuleMacros.end());
- llvm::SmallVector<ModuleMacro*, 8> Overrides;
- for (auto &MMR : ModuleMacros) {
- Overrides.clear();
- for (unsigned ModID : MMR.Overrides) {
- Module *Mod = getSubmodule(ModID);
- auto *Macro = PP.getModuleMacro(Mod, II);
- assert(Macro && "missing definition for overridden macro");
- Overrides.push_back(Macro);
- }
-
- bool Inserted = false;
- Module *Owner = getSubmodule(MMR.SubModID);
- PP.addModuleMacro(Owner, II, MMR.MI, Overrides, Inserted);
- }
- }
-
- // Don't read the directive history for a module; we don't have anywhere
- // to put it.
- if (M.isModule())
- return;
-
- // Deserialize the macro directives history in reverse source-order.
- MacroDirective *Latest = nullptr, *Earliest = nullptr;
- unsigned Idx = 0, N = Record.size();
- while (Idx < N) {
- MacroDirective *MD = nullptr;
- SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
- MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++];
- switch (K) {
- case MacroDirective::MD_Define: {
- MacroInfo *MI = getMacro(getGlobalMacroID(M, Record[Idx++]));
- MD = PP.AllocateDefMacroDirective(MI, Loc);
- break;
- }
- case MacroDirective::MD_Undefine:
- MD = PP.AllocateUndefMacroDirective(Loc);
- break;
- case MacroDirective::MD_Visibility:
- bool isPublic = Record[Idx++];
- MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic);
- break;
- }
-
- if (!Latest)
- Latest = MD;
- if (Earliest)
- Earliest->setPrevious(MD);
- Earliest = MD;
- }
-
- if (Latest)
- PP.setLoadedMacroDirective(II, Earliest, Latest);
-}
-
-ASTReader::InputFileInfo
-ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
- // Go find this input file.
- BitstreamCursor &Cursor = F.InputFilesCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
-
- unsigned Code = Cursor.ReadCode();
- RecordData Record;
- StringRef Blob;
-
- unsigned Result = Cursor.readRecord(Code, Record, &Blob);
- assert(static_cast<InputFileRecordTypes>(Result) == INPUT_FILE &&
- "invalid record type for input file");
- (void)Result;
-
- assert(Record[0] == ID && "Bogus stored ID or offset");
- InputFileInfo R;
- R.StoredSize = static_cast<off_t>(Record[1]);
- R.StoredTime = static_cast<time_t>(Record[2]);
- R.Overridden = static_cast<bool>(Record[3]);
- R.Transient = static_cast<bool>(Record[4]);
- R.TopLevelModuleMap = static_cast<bool>(Record[5]);
- R.Filename = Blob;
- ResolveImportedPath(F, R.Filename);
- return R;
-}
-
-static unsigned moduleKindForDiagnostic(ModuleKind Kind);
-InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
- // If this ID is bogus, just return an empty input file.
- if (ID == 0 || ID > F.InputFilesLoaded.size())
- return InputFile();
-
- // If we've already loaded this input file, return it.
- if (F.InputFilesLoaded[ID-1].getFile())
- return F.InputFilesLoaded[ID-1];
-
- if (F.InputFilesLoaded[ID-1].isNotFound())
- return InputFile();
-
- // Go find this input file.
- BitstreamCursor &Cursor = F.InputFilesCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
-
- InputFileInfo FI = readInputFileInfo(F, ID);
- off_t StoredSize = FI.StoredSize;
- time_t StoredTime = FI.StoredTime;
- bool Overridden = FI.Overridden;
- bool Transient = FI.Transient;
- StringRef Filename = FI.Filename;
-
- const FileEntry *File = FileMgr.getFile(Filename, /*OpenFile=*/false);
- // If we didn't find the file, resolve it relative to the
- // original directory from which this AST file was created.
- if (File == nullptr && !F.OriginalDir.empty() && !F.BaseDirectory.empty() &&
- F.OriginalDir != F.BaseDirectory) {
- std::string Resolved = resolveFileRelativeToOriginalDir(
- Filename, F.OriginalDir, F.BaseDirectory);
- if (!Resolved.empty())
- File = FileMgr.getFile(Resolved);
- }
-
- // For an overridden file, create a virtual file with the stored
- // size/timestamp.
- if ((Overridden || Transient) && File == nullptr)
- File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
-
- if (File == nullptr) {
- if (Complain) {
- std::string ErrorStr = "could not find file '";
- ErrorStr += Filename;
- ErrorStr += "' referenced by AST file '";
- ErrorStr += F.FileName;
- ErrorStr += "'";
- Error(ErrorStr);
- }
- // Record that we didn't find the file.
- F.InputFilesLoaded[ID-1] = InputFile::getNotFound();
- return InputFile();
- }
-
- // Check if there was a request to override the contents of the file
- // that was part of the precompiled header. Overriding such a file
- // can lead to problems when lexing using the source locations from the
- // PCH.
- SourceManager &SM = getSourceManager();
- // FIXME: Reject if the overrides are different.
- if ((!Overridden && !Transient) && SM.isFileOverridden(File)) {
- if (Complain)
- Error(diag::err_fe_pch_file_overridden, Filename);
- // After emitting the diagnostic, recover by disabling the override so
- // that the original file will be used.
- //
- // FIXME: This recovery is just as broken as the original state; there may
- // be another precompiled module that's using the overridden contents, or
- // we might be half way through parsing it. Instead, we should treat the
- // overridden contents as belonging to a separate FileEntry.
- SM.disableFileContentsOverride(File);
- // The FileEntry is a virtual file entry with the size of the contents
- // that would override the original contents. Set it to the original's
- // size/time.
- FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
- StoredSize, StoredTime);
- }
-
- bool IsOutOfDate = false;
-
- // For an overridden file, there is nothing to validate.
- if (!Overridden && //
- (StoredSize != File->getSize() ||
- (StoredTime && StoredTime != File->getModificationTime() &&
- !DisableValidation)
- )) {
- if (Complain) {
- // Build a list of the PCH imports that got us here (in reverse).
- SmallVector<ModuleFile *, 4> ImportStack(1, &F);
- while (!ImportStack.back()->ImportedBy.empty())
- ImportStack.push_back(ImportStack.back()->ImportedBy[0]);
-
- // The top-level PCH is stale.
- StringRef TopLevelPCHName(ImportStack.back()->FileName);
- unsigned DiagnosticKind = moduleKindForDiagnostic(ImportStack.back()->Kind);
- if (DiagnosticKind == 0)
- Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName);
- else if (DiagnosticKind == 1)
- Error(diag::err_fe_module_file_modified, Filename, TopLevelPCHName);
- else
- Error(diag::err_fe_ast_file_modified, Filename, TopLevelPCHName);
-
- // Print the import stack.
- if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) {
- Diag(diag::note_pch_required_by)
- << Filename << ImportStack[0]->FileName;
- for (unsigned I = 1; I < ImportStack.size(); ++I)
- Diag(diag::note_pch_required_by)
- << ImportStack[I-1]->FileName << ImportStack[I]->FileName;
- }
-
- if (!Diags.isDiagnosticInFlight())
- Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
- }
-
- IsOutOfDate = true;
- }
- // FIXME: If the file is overridden and we've already opened it,
- // issue an error (or split it into a separate FileEntry).
-
- InputFile IF = InputFile(File, Overridden || Transient, IsOutOfDate);
-
- // Note that we've loaded this input file.
- F.InputFilesLoaded[ID-1] = IF;
- return IF;
-}
-
-/// If we are loading a relocatable PCH or module file, and the filename
-/// is not an absolute path, add the system or module root to the beginning of
-/// the file name.
-void ASTReader::ResolveImportedPath(ModuleFile &M, std::string &Filename) {
- // Resolve relative to the base directory, if we have one.
- if (!M.BaseDirectory.empty())
- return ResolveImportedPath(Filename, M.BaseDirectory);
-}
-
-void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) {
- if (Filename.empty() || llvm::sys::path::is_absolute(Filename))
- return;
-
- SmallString<128> Buffer;
- llvm::sys::path::append(Buffer, Prefix, Filename);
- Filename.assign(Buffer.begin(), Buffer.end());
-}
-
-static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) {
- switch (ARR) {
- case ASTReader::Failure: return true;
- case ASTReader::Missing: return !(Caps & ASTReader::ARR_Missing);
- case ASTReader::OutOfDate: return !(Caps & ASTReader::ARR_OutOfDate);
- case ASTReader::VersionMismatch: return !(Caps & ASTReader::ARR_VersionMismatch);
- case ASTReader::ConfigurationMismatch:
- return !(Caps & ASTReader::ARR_ConfigurationMismatch);
- case ASTReader::HadErrors: return true;
- case ASTReader::Success: return false;
- }
-
- llvm_unreachable("unknown ASTReadResult");
-}
-
-ASTReader::ASTReadResult ASTReader::ReadOptionsBlock(
- BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
- bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
- std::string &SuggestedPredefines) {
- if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID))
- return Failure;
-
- // Read all of the records in the options block.
- RecordData Record;
- ASTReadResult Result = Success;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- case llvm::BitstreamEntry::SubBlock:
- return Failure;
-
- case llvm::BitstreamEntry::EndBlock:
- return Result;
-
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read and process a record.
- Record.clear();
- switch ((OptionsRecordTypes)Stream.readRecord(Entry.ID, Record)) {
- case LANGUAGE_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
- if (ParseLanguageOptions(Record, Complain, Listener,
- AllowCompatibleConfigurationMismatch))
- Result = ConfigurationMismatch;
- break;
- }
-
- case TARGET_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
- if (ParseTargetOptions(Record, Complain, Listener,
- AllowCompatibleConfigurationMismatch))
- Result = ConfigurationMismatch;
- break;
- }
-
- case FILE_SYSTEM_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
- if (!AllowCompatibleConfigurationMismatch &&
- ParseFileSystemOptions(Record, Complain, Listener))
- Result = ConfigurationMismatch;
- break;
- }
-
- case HEADER_SEARCH_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
- if (!AllowCompatibleConfigurationMismatch &&
- ParseHeaderSearchOptions(Record, Complain, Listener))
- Result = ConfigurationMismatch;
- break;
- }
-
- case PREPROCESSOR_OPTIONS:
- bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
- if (!AllowCompatibleConfigurationMismatch &&
- ParsePreprocessorOptions(Record, Complain, Listener,
- SuggestedPredefines))
- Result = ConfigurationMismatch;
- break;
- }
- }
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadControlBlock(ModuleFile &F,
- SmallVectorImpl<ImportedModule> &Loaded,
- const ModuleFile *ImportedBy,
- unsigned ClientLoadCapabilities) {
- BitstreamCursor &Stream = F.Stream;
- ASTReadResult Result = Success;
-
- if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
- Error("malformed block record in AST file");
- return Failure;
- }
-
- // Lambda to read the unhashed control block the first time it's called.
- //
- // For PCM files, the unhashed control block cannot be read until after the
- // MODULE_NAME record. However, PCH files have no MODULE_NAME, and yet still
- // need to look ahead before reading the IMPORTS record. For consistency,
- // this block is always read somehow (see BitstreamEntry::EndBlock).
- bool HasReadUnhashedControlBlock = false;
- auto readUnhashedControlBlockOnce = [&]() {
- if (!HasReadUnhashedControlBlock) {
- HasReadUnhashedControlBlock = true;
- if (ASTReadResult Result =
- readUnhashedControlBlock(F, ImportedBy, ClientLoadCapabilities))
- return Result;
- }
- return Success;
- };
-
- // Read all of the records and blocks in the control block.
- RecordData Record;
- unsigned NumInputs = 0;
- unsigned NumUserInputs = 0;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return Failure;
- case llvm::BitstreamEntry::EndBlock: {
- // Validate the module before returning. This call catches an AST with
- // no module name and no imports.
- if (ASTReadResult Result = readUnhashedControlBlockOnce())
- return Result;
-
- // Validate input files.
- const HeaderSearchOptions &HSOpts =
- PP.getHeaderSearchInfo().getHeaderSearchOpts();
-
- // All user input files reside at the index range [0, NumUserInputs), and
- // system input files reside at [NumUserInputs, NumInputs). For explicitly
- // loaded module files, ignore missing inputs.
- if (!DisableValidation && F.Kind != MK_ExplicitModule &&
- F.Kind != MK_PrebuiltModule) {
- bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
-
- // If we are reading a module, we will create a verification timestamp,
- // so we verify all input files. Otherwise, verify only user input
- // files.
-
- unsigned N = NumUserInputs;
- if (ValidateSystemInputs ||
- (HSOpts.ModulesValidateOncePerBuildSession &&
- F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp &&
- F.Kind == MK_ImplicitModule))
- N = NumInputs;
-
- for (unsigned I = 0; I < N; ++I) {
- InputFile IF = getInputFile(F, I+1, Complain);
- if (!IF.getFile() || IF.isOutOfDate())
- return OutOfDate;
- }
- }
-
- if (Listener)
- Listener->visitModuleFile(F.FileName, F.Kind);
-
- if (Listener && Listener->needsInputFileVisitation()) {
- unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs
- : NumUserInputs;
- for (unsigned I = 0; I < N; ++I) {
- bool IsSystem = I >= NumUserInputs;
- InputFileInfo FI = readInputFileInfo(F, I+1);
- Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden,
- F.Kind == MK_ExplicitModule ||
- F.Kind == MK_PrebuiltModule);
- }
- }
-
- return Result;
- }
-
- case llvm::BitstreamEntry::SubBlock:
- switch (Entry.ID) {
- case INPUT_FILES_BLOCK_ID:
- F.InputFilesCursor = Stream;
- if (Stream.SkipBlock() || // Skip with the main cursor
- // Read the abbreviations
- ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) {
- Error("malformed block record in AST file");
- return Failure;
- }
- continue;
-
- case OPTIONS_BLOCK_ID:
- // If we're reading the first module for this group, check its options
- // are compatible with ours. For modules it imports, no further checking
- // is required, because we checked them when we built it.
- if (Listener && !ImportedBy) {
- // Should we allow the configuration of the module file to differ from
- // the configuration of the current translation unit in a compatible
- // way?
- //
- // FIXME: Allow this for files explicitly specified with -include-pch.
- bool AllowCompatibleConfigurationMismatch =
- F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
-
- Result = ReadOptionsBlock(Stream, ClientLoadCapabilities,
- AllowCompatibleConfigurationMismatch,
- *Listener, SuggestedPredefines);
- if (Result == Failure) {
- Error("malformed block record in AST file");
- return Result;
- }
-
- if (DisableValidation ||
- (AllowConfigurationMismatch && Result == ConfigurationMismatch))
- Result = Success;
-
- // If we can't load the module, exit early since we likely
- // will rebuild the module anyway. The stream may be in the
- // middle of a block.
- if (Result != Success)
- return Result;
- } else if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
- return Failure;
- }
- continue;
-
- default:
- if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
- return Failure;
- }
- continue;
- }
-
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read and process a record.
- Record.clear();
- StringRef Blob;
- switch ((ControlRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob)) {
- case METADATA: {
- if (Record[0] != VERSION_MAJOR && !DisableValidation) {
- if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
- Diag(Record[0] < VERSION_MAJOR? diag::err_pch_version_too_old
- : diag::err_pch_version_too_new);
- return VersionMismatch;
- }
-
- bool hasErrors = Record[7];
- if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {
- Diag(diag::err_pch_with_compiler_errors);
- return HadErrors;
- }
- if (hasErrors) {
- Diags.ErrorOccurred = true;
- Diags.UncompilableErrorOccurred = true;
- Diags.UnrecoverableErrorOccurred = true;
- }
-
- F.RelocatablePCH = Record[4];
- // Relative paths in a relocatable PCH are relative to our sysroot.
- if (F.RelocatablePCH)
- F.BaseDirectory = isysroot.empty() ? "/" : isysroot;
-
- F.HasTimestamps = Record[5];
-
- F.PCHHasObjectFile = Record[6];
-
- const std::string &CurBranch = getClangFullRepositoryVersion();
- StringRef ASTBranch = Blob;
- if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
- if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
- Diag(diag::err_pch_different_branch) << ASTBranch << CurBranch;
- return VersionMismatch;
- }
- break;
- }
-
- case IMPORTS: {
- // Validate the AST before processing any imports (otherwise, untangling
- // them can be error-prone and expensive). A module will have a name and
- // will already have been validated, but this catches the PCH case.
- if (ASTReadResult Result = readUnhashedControlBlockOnce())
- return Result;
-
- // Load each of the imported PCH files.
- unsigned Idx = 0, N = Record.size();
- while (Idx < N) {
- // Read information about the AST file.
- ModuleKind ImportedKind = (ModuleKind)Record[Idx++];
- // The import location will be the local one for now; we will adjust
- // all import locations of module imports after the global source
- // location info are setup, in ReadAST.
- SourceLocation ImportLoc =
- ReadUntranslatedSourceLocation(Record[Idx++]);
- off_t StoredSize = (off_t)Record[Idx++];
- time_t StoredModTime = (time_t)Record[Idx++];
- ASTFileSignature StoredSignature = {
- {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
- (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
- (uint32_t)Record[Idx++]}}};
-
- std::string ImportedName = ReadString(Record, Idx);
- std::string ImportedFile;
-
- // For prebuilt and explicit modules first consult the file map for
- // an override. Note that here we don't search prebuilt module
- // directories, only the explicit name to file mappings. Also, we will
- // still verify the size/signature making sure it is essentially the
- // same file but perhaps in a different location.
- if (ImportedKind == MK_PrebuiltModule || ImportedKind == MK_ExplicitModule)
- ImportedFile = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(
- ImportedName, /*FileMapOnly*/ true);
-
- if (ImportedFile.empty())
- ImportedFile = ReadPath(F, Record, Idx);
- else
- SkipPath(Record, Idx);
-
- // If our client can't cope with us being out of date, we can't cope with
- // our dependency being missing.
- unsigned Capabilities = ClientLoadCapabilities;
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Capabilities &= ~ARR_Missing;
-
- // Load the AST file.
- auto Result = ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F,
- Loaded, StoredSize, StoredModTime,
- StoredSignature, Capabilities);
-
- // If we diagnosed a problem, produce a backtrace.
- if (isDiagnosedResult(Result, Capabilities))
- Diag(diag::note_module_file_imported_by)
- << F.FileName << !F.ModuleName.empty() << F.ModuleName;
-
- switch (Result) {
- case Failure: return Failure;
- // If we have to ignore the dependency, we'll have to ignore this too.
- case Missing:
- case OutOfDate: return OutOfDate;
- case VersionMismatch: return VersionMismatch;
- case ConfigurationMismatch: return ConfigurationMismatch;
- case HadErrors: return HadErrors;
- case Success: break;
- }
- }
- break;
- }
-
- case ORIGINAL_FILE:
- F.OriginalSourceFileID = FileID::get(Record[0]);
- F.ActualOriginalSourceFileName = Blob;
- F.OriginalSourceFileName = F.ActualOriginalSourceFileName;
- ResolveImportedPath(F, F.OriginalSourceFileName);
- break;
-
- case ORIGINAL_FILE_ID:
- F.OriginalSourceFileID = FileID::get(Record[0]);
- break;
-
- case ORIGINAL_PCH_DIR:
- F.OriginalDir = Blob;
- break;
-
- case MODULE_NAME:
- F.ModuleName = Blob;
- if (Listener)
- Listener->ReadModuleName(F.ModuleName);
-
- // Validate the AST as soon as we have a name so we can exit early on
- // failure.
- if (ASTReadResult Result = readUnhashedControlBlockOnce())
- return Result;
-
- break;
-
- case MODULE_DIRECTORY: {
- assert(!F.ModuleName.empty() &&
- "MODULE_DIRECTORY found before MODULE_NAME");
- // If we've already loaded a module map file covering this module, we may
- // have a better path for it (relative to the current build).
- Module *M = PP.getHeaderSearchInfo().lookupModule(
- F.ModuleName, /*AllowSearch*/ true,
- /*AllowExtraModuleMapSearch*/ true);
- if (M && M->Directory) {
- // If we're implicitly loading a module, the base directory can't
- // change between the build and use.
- // Don't emit module relocation error if we have -fno-validate-pch
- if (!PP.getPreprocessorOpts().DisablePCHValidation &&
- F.Kind != MK_ExplicitModule && F.Kind != MK_PrebuiltModule) {
- const DirectoryEntry *BuildDir =
- PP.getFileManager().getDirectory(Blob);
- if (!BuildDir || BuildDir != M->Directory) {
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Diag(diag::err_imported_module_relocated)
- << F.ModuleName << Blob << M->Directory->getName();
- return OutOfDate;
- }
- }
- F.BaseDirectory = M->Directory->getName();
- } else {
- F.BaseDirectory = Blob;
- }
- break;
- }
-
- case MODULE_MAP_FILE:
- if (ASTReadResult Result =
- ReadModuleMapFileBlock(Record, F, ImportedBy, ClientLoadCapabilities))
- return Result;
- break;
-
- case INPUT_FILE_OFFSETS:
- NumInputs = Record[0];
- NumUserInputs = Record[1];
- F.InputFileOffsets =
- (const llvm::support::unaligned_uint64_t *)Blob.data();
- F.InputFilesLoaded.resize(NumInputs);
- F.NumUserInputFiles = NumUserInputs;
- break;
- }
- }
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
- BitstreamCursor &Stream = F.Stream;
-
- if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
- Error("malformed block record in AST file");
- return Failure;
- }
-
- // Read all of the records and blocks for the AST file.
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- Error("error at end of module block in AST file");
- return Failure;
- case llvm::BitstreamEntry::EndBlock:
- // Outside of C++, we do not store a lookup map for the translation unit.
- // Instead, mark it as needing a lookup map to be built if this module
- // contains any declarations lexically within it (which it always does!).
- // This usually has no cost, since we very rarely need the lookup map for
- // the translation unit outside C++.
- if (ASTContext *Ctx = ContextObj) {
- DeclContext *DC = Ctx->getTranslationUnitDecl();
- if (DC->hasExternalLexicalStorage() && !Ctx->getLangOpts().CPlusPlus)
- DC->setMustBuildLookupTable();
- }
-
- return Success;
- case llvm::BitstreamEntry::SubBlock:
- switch (Entry.ID) {
- case DECLTYPES_BLOCK_ID:
- // We lazily load the decls block, but we want to set up the
- // DeclsCursor cursor to point into it. Clone our current bitcode
- // cursor to it, enter the block and read the abbrevs in that block.
- // With the main cursor, we just skip over it.
- F.DeclsCursor = Stream;
- if (Stream.SkipBlock() || // Skip with the main cursor.
- // Read the abbrevs.
- ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
- Error("malformed block record in AST file");
- return Failure;
- }
- break;
-
- case PREPROCESSOR_BLOCK_ID:
- F.MacroCursor = Stream;
- if (!PP.getExternalSource())
- PP.setExternalSource(this);
-
- if (Stream.SkipBlock() ||
- ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
- Error("malformed block record in AST file");
- return Failure;
- }
- F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
- break;
-
- case PREPROCESSOR_DETAIL_BLOCK_ID:
- F.PreprocessorDetailCursor = Stream;
- if (Stream.SkipBlock() ||
- ReadBlockAbbrevs(F.PreprocessorDetailCursor,
- PREPROCESSOR_DETAIL_BLOCK_ID)) {
- Error("malformed preprocessor detail record in AST file");
- return Failure;
- }
- F.PreprocessorDetailStartOffset
- = F.PreprocessorDetailCursor.GetCurrentBitNo();
-
- if (!PP.getPreprocessingRecord())
- PP.createPreprocessingRecord();
- if (!PP.getPreprocessingRecord()->getExternalSource())
- PP.getPreprocessingRecord()->SetExternalSource(*this);
- break;
-
- case SOURCE_MANAGER_BLOCK_ID:
- if (ReadSourceManagerBlock(F))
- return Failure;
- break;
-
- case SUBMODULE_BLOCK_ID:
- if (ASTReadResult Result =
- ReadSubmoduleBlock(F, ClientLoadCapabilities))
- return Result;
- break;
-
- case COMMENTS_BLOCK_ID: {
- BitstreamCursor C = Stream;
- if (Stream.SkipBlock() ||
- ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
- Error("malformed comments block in AST file");
- return Failure;
- }
- CommentsCursors.push_back(std::make_pair(C, &F));
- break;
- }
-
- default:
- if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
- return Failure;
- }
- break;
- }
- continue;
-
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read and process a record.
- Record.clear();
- StringRef Blob;
- auto RecordType =
- (ASTRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob);
-
- // If we're not loading an AST context, we don't care about most records.
- if (!ContextObj) {
- switch (RecordType) {
- case IDENTIFIER_TABLE:
- case IDENTIFIER_OFFSET:
- case INTERESTING_IDENTIFIERS:
- case STATISTICS:
- case PP_CONDITIONAL_STACK:
- case PP_COUNTER_VALUE:
- case SOURCE_LOCATION_OFFSETS:
- case MODULE_OFFSET_MAP:
- case SOURCE_MANAGER_LINE_TABLE:
- case SOURCE_LOCATION_PRELOADS:
- case PPD_ENTITIES_OFFSETS:
- case HEADER_SEARCH_TABLE:
- case IMPORTED_MODULES:
- case MACRO_OFFSET:
- break;
- default:
- continue;
- }
- }
-
- switch (RecordType) {
- default: // Default behavior: ignore.
- break;
-
- case TYPE_OFFSET: {
- if (F.LocalNumTypes != 0) {
- Error("duplicate TYPE_OFFSET record in AST file");
- return Failure;
- }
- F.TypeOffsets = (const uint32_t *)Blob.data();
- F.LocalNumTypes = Record[0];
- unsigned LocalBaseTypeIndex = Record[1];
- F.BaseTypeIndex = getTotalNumTypes();
-
- if (F.LocalNumTypes > 0) {
- // Introduce the global -> local mapping for types within this module.
- GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F));
-
- // Introduce the local -> global mapping for types within this module.
- F.TypeRemap.insertOrReplace(
- std::make_pair(LocalBaseTypeIndex,
- F.BaseTypeIndex - LocalBaseTypeIndex));
-
- TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);
- }
- break;
- }
-
- case DECL_OFFSET: {
- if (F.LocalNumDecls != 0) {
- Error("duplicate DECL_OFFSET record in AST file");
- return Failure;
- }
- F.DeclOffsets = (const DeclOffset *)Blob.data();
- F.LocalNumDecls = Record[0];
- unsigned LocalBaseDeclID = Record[1];
- F.BaseDeclID = getTotalNumDecls();
-
- if (F.LocalNumDecls > 0) {
- // Introduce the global -> local mapping for declarations within this
- // module.
- GlobalDeclMap.insert(
- std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F));
-
- // Introduce the local -> global mapping for declarations within this
- // module.
- F.DeclRemap.insertOrReplace(
- std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID));
-
- // Introduce the global -> local mapping for declarations within this
- // module.
- F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID;
-
- DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);
- }
- break;
- }
-
- case TU_UPDATE_LEXICAL: {
- DeclContext *TU = ContextObj->getTranslationUnitDecl();
- LexicalContents Contents(
- reinterpret_cast<const llvm::support::unaligned_uint32_t *>(
- Blob.data()),
- static_cast<unsigned int>(Blob.size() / 4));
- TULexicalDecls.push_back(std::make_pair(&F, Contents));
- TU->setHasExternalLexicalStorage(true);
- break;
- }
-
- case UPDATE_VISIBLE: {
- unsigned Idx = 0;
- serialization::DeclID ID = ReadDeclID(F, Record, Idx);
- auto *Data = (const unsigned char*)Blob.data();
- PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data});
- // If we've already loaded the decl, perform the updates when we finish
- // loading this block.
- if (Decl *D = GetExistingDecl(ID))
- PendingUpdateRecords.push_back(
- PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
- break;
- }
-
- case IDENTIFIER_TABLE:
- F.IdentifierTableData = Blob.data();
- if (Record[0]) {
- F.IdentifierLookupTable = ASTIdentifierLookupTable::Create(
- (const unsigned char *)F.IdentifierTableData + Record[0],
- (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t),
- (const unsigned char *)F.IdentifierTableData,
- ASTIdentifierLookupTrait(*this, F));
-
- PP.getIdentifierTable().setExternalIdentifierLookup(this);
- }
- break;
-
- case IDENTIFIER_OFFSET: {
- if (F.LocalNumIdentifiers != 0) {
- Error("duplicate IDENTIFIER_OFFSET record in AST file");
- return Failure;
- }
- F.IdentifierOffsets = (const uint32_t *)Blob.data();
- F.LocalNumIdentifiers = Record[0];
- unsigned LocalBaseIdentifierID = Record[1];
- F.BaseIdentifierID = getTotalNumIdentifiers();
-
- if (F.LocalNumIdentifiers > 0) {
- // Introduce the global -> local mapping for identifiers within this
- // module.
- GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1,
- &F));
-
- // Introduce the local -> global mapping for identifiers within this
- // module.
- F.IdentifierRemap.insertOrReplace(
- std::make_pair(LocalBaseIdentifierID,
- F.BaseIdentifierID - LocalBaseIdentifierID));
-
- IdentifiersLoaded.resize(IdentifiersLoaded.size()
- + F.LocalNumIdentifiers);
- }
- break;
- }
-
- case INTERESTING_IDENTIFIERS:
- F.PreloadIdentifierOffsets.assign(Record.begin(), Record.end());
- break;
-
- case EAGERLY_DESERIALIZED_DECLS:
- // FIXME: Skip reading this record if our ASTConsumer doesn't care
- // about "interesting" decls (for instance, if we're building a module).
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case MODULAR_CODEGEN_DECLS:
- // FIXME: Skip reading this record if our ASTConsumer doesn't care about
- // them (ie: if we're not codegenerating this module).
- if (F.Kind == MK_MainFile)
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case SPECIAL_TYPES:
- if (SpecialTypes.empty()) {
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- SpecialTypes.push_back(getGlobalTypeID(F, Record[I]));
- break;
- }
-
- if (SpecialTypes.size() != Record.size()) {
- Error("invalid special-types record");
- return Failure;
- }
-
- for (unsigned I = 0, N = Record.size(); I != N; ++I) {
- serialization::TypeID ID = getGlobalTypeID(F, Record[I]);
- if (!SpecialTypes[I])
- SpecialTypes[I] = ID;
- // FIXME: If ID && SpecialTypes[I] != ID, do we need a separate
- // merge step?
- }
- break;
-
- case STATISTICS:
- TotalNumStatements += Record[0];
- TotalNumMacros += Record[1];
- TotalLexicalDeclContexts += Record[2];
- TotalVisibleDeclContexts += Record[3];
- break;
-
- case UNUSED_FILESCOPED_DECLS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case DELEGATING_CTORS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case WEAK_UNDECLARED_IDENTIFIERS:
- if (Record.size() % 4 != 0) {
- Error("invalid weak identifiers record");
- return Failure;
- }
-
- // FIXME: Ignore weak undeclared identifiers from non-original PCH
- // files. This isn't the way to do it :)
- WeakUndeclaredIdentifiers.clear();
-
- // Translate the weak, undeclared identifiers into global IDs.
- for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) {
- WeakUndeclaredIdentifiers.push_back(
- getGlobalIdentifierID(F, Record[I++]));
- WeakUndeclaredIdentifiers.push_back(
- getGlobalIdentifierID(F, Record[I++]));
- WeakUndeclaredIdentifiers.push_back(
- ReadSourceLocation(F, Record, I).getRawEncoding());
- WeakUndeclaredIdentifiers.push_back(Record[I++]);
- }
- break;
-
- case SELECTOR_OFFSETS: {
- F.SelectorOffsets = (const uint32_t *)Blob.data();
- F.LocalNumSelectors = Record[0];
- unsigned LocalBaseSelectorID = Record[1];
- F.BaseSelectorID = getTotalNumSelectors();
-
- if (F.LocalNumSelectors > 0) {
- // Introduce the global -> local mapping for selectors within this
- // module.
- GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F));
-
- // Introduce the local -> global mapping for selectors within this
- // module.
- F.SelectorRemap.insertOrReplace(
- std::make_pair(LocalBaseSelectorID,
- F.BaseSelectorID - LocalBaseSelectorID));
-
- SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);
- }
- break;
- }
-
- case METHOD_POOL:
- F.SelectorLookupTableData = (const unsigned char *)Blob.data();
- if (Record[0])
- F.SelectorLookupTable
- = ASTSelectorLookupTable::Create(
- F.SelectorLookupTableData + Record[0],
- F.SelectorLookupTableData,
- ASTSelectorLookupTrait(*this, F));
- TotalNumMethodPoolEntries += Record[1];
- break;
-
- case REFERENCED_SELECTOR_POOL:
- if (!Record.empty()) {
- for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) {
- ReferencedSelectorsData.push_back(getGlobalSelectorID(F,
- Record[Idx++]));
- ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx).
- getRawEncoding());
- }
- }
- break;
-
- case PP_CONDITIONAL_STACK:
- if (!Record.empty()) {
- unsigned Idx = 0, End = Record.size() - 1;
- bool ReachedEOFWhileSkipping = Record[Idx++];
- llvm::Optional<Preprocessor::PreambleSkipInfo> SkipInfo;
- if (ReachedEOFWhileSkipping) {
- SourceLocation HashToken = ReadSourceLocation(F, Record, Idx);
- SourceLocation IfTokenLoc = ReadSourceLocation(F, Record, Idx);
- bool FoundNonSkipPortion = Record[Idx++];
- bool FoundElse = Record[Idx++];
- SourceLocation ElseLoc = ReadSourceLocation(F, Record, Idx);
- SkipInfo.emplace(HashToken, IfTokenLoc, FoundNonSkipPortion,
- FoundElse, ElseLoc);
- }
- SmallVector<PPConditionalInfo, 4> ConditionalStack;
- while (Idx < End) {
- auto Loc = ReadSourceLocation(F, Record, Idx);
- bool WasSkipping = Record[Idx++];
- bool FoundNonSkip = Record[Idx++];
- bool FoundElse = Record[Idx++];
- ConditionalStack.push_back(
- {Loc, WasSkipping, FoundNonSkip, FoundElse});
- }
- PP.setReplayablePreambleConditionalStack(ConditionalStack, SkipInfo);
- }
- break;
-
- case PP_COUNTER_VALUE:
- if (!Record.empty() && Listener)
- Listener->ReadCounter(F, Record[0]);
- break;
-
- case FILE_SORTED_DECLS:
- F.FileSortedDecls = (const DeclID *)Blob.data();
- F.NumFileSortedDecls = Record[0];
- break;
-
- case SOURCE_LOCATION_OFFSETS: {
- F.SLocEntryOffsets = (const uint32_t *)Blob.data();
- F.LocalNumSLocEntries = Record[0];
- unsigned SLocSpaceSize = Record[1];
- std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
- SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
- SLocSpaceSize);
- if (!F.SLocEntryBaseID) {
- Error("ran out of source locations");
- break;
- }
- // Make our entry in the range map. BaseID is negative and growing, so
- // we invert it. Because we invert it, though, we need the other end of
- // the range.
- unsigned RangeStart =
- unsigned(-F.SLocEntryBaseID) - F.LocalNumSLocEntries + 1;
- GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F));
- F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset);
-
- // SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing.
- assert((F.SLocEntryBaseOffset & (1U << 31U)) == 0);
- GlobalSLocOffsetMap.insert(
- std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset
- - SLocSpaceSize,&F));
-
- // Initialize the remapping table.
- // Invalid stays invalid.
- F.SLocRemap.insertOrReplace(std::make_pair(0U, 0));
- // This module. Base was 2 when being compiled.
- F.SLocRemap.insertOrReplace(std::make_pair(2U,
- static_cast<int>(F.SLocEntryBaseOffset - 2)));
-
- TotalNumSLocEntries += F.LocalNumSLocEntries;
- break;
- }
-
- case MODULE_OFFSET_MAP:
- F.ModuleOffsetMap = Blob;
- break;
-
- case SOURCE_MANAGER_LINE_TABLE:
- if (ParseLineTable(F, Record))
- return Failure;
- break;
-
- case SOURCE_LOCATION_PRELOADS: {
- // Need to transform from the local view (1-based IDs) to the global view,
- // which is based off F.SLocEntryBaseID.
- if (!F.PreloadSLocEntries.empty()) {
- Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
- return Failure;
- }
-
- F.PreloadSLocEntries.swap(Record);
- break;
- }
-
- case EXT_VECTOR_DECLS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case VTABLE_USES:
- if (Record.size() % 3 != 0) {
- Error("Invalid VTABLE_USES record");
- return Failure;
- }
-
- // Later tables overwrite earlier ones.
- // FIXME: Modules will have some trouble with this. This is clearly not
- // the right way to do this.
- VTableUses.clear();
-
- for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
- VTableUses.push_back(getGlobalDeclID(F, Record[Idx++]));
- VTableUses.push_back(
- ReadSourceLocation(F, Record, Idx).getRawEncoding());
- VTableUses.push_back(Record[Idx++]);
- }
- break;
-
- case PENDING_IMPLICIT_INSTANTIATIONS:
- if (PendingInstantiations.size() % 2 != 0) {
- Error("Invalid existing PendingInstantiations");
- return Failure;
- }
-
- if (Record.size() % 2 != 0) {
- Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
- return Failure;
- }
-
- for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
- PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));
- PendingInstantiations.push_back(
- ReadSourceLocation(F, Record, I).getRawEncoding());
- }
- break;
-
- case SEMA_DECL_REFS:
- if (Record.size() != 3) {
- Error("Invalid SEMA_DECL_REFS block");
- return Failure;
- }
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case PPD_ENTITIES_OFFSETS: {
- F.PreprocessedEntityOffsets = (const PPEntityOffset *)Blob.data();
- assert(Blob.size() % sizeof(PPEntityOffset) == 0);
- F.NumPreprocessedEntities = Blob.size() / sizeof(PPEntityOffset);
-
- unsigned LocalBasePreprocessedEntityID = Record[0];
-
- unsigned StartingID;
- if (!PP.getPreprocessingRecord())
- PP.createPreprocessingRecord();
- if (!PP.getPreprocessingRecord()->getExternalSource())
- PP.getPreprocessingRecord()->SetExternalSource(*this);
- StartingID
- = PP.getPreprocessingRecord()
- ->allocateLoadedEntities(F.NumPreprocessedEntities);
- F.BasePreprocessedEntityID = StartingID;
-
- if (F.NumPreprocessedEntities > 0) {
- // Introduce the global -> local mapping for preprocessed entities in
- // this module.
- GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));
-
- // Introduce the local -> global mapping for preprocessed entities in
- // this module.
- F.PreprocessedEntityRemap.insertOrReplace(
- std::make_pair(LocalBasePreprocessedEntityID,
- F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID));
- }
-
- break;
- }
-
- case PPD_SKIPPED_RANGES: {
- F.PreprocessedSkippedRangeOffsets = (const PPSkippedRange*)Blob.data();
- assert(Blob.size() % sizeof(PPSkippedRange) == 0);
- F.NumPreprocessedSkippedRanges = Blob.size() / sizeof(PPSkippedRange);
-
- if (!PP.getPreprocessingRecord())
- PP.createPreprocessingRecord();
- if (!PP.getPreprocessingRecord()->getExternalSource())
- PP.getPreprocessingRecord()->SetExternalSource(*this);
- F.BasePreprocessedSkippedRangeID = PP.getPreprocessingRecord()
- ->allocateSkippedRanges(F.NumPreprocessedSkippedRanges);
-
- if (F.NumPreprocessedSkippedRanges > 0)
- GlobalSkippedRangeMap.insert(
- std::make_pair(F.BasePreprocessedSkippedRangeID, &F));
- break;
- }
-
- case DECL_UPDATE_OFFSETS:
- if (Record.size() % 2 != 0) {
- Error("invalid DECL_UPDATE_OFFSETS block in AST file");
- return Failure;
- }
- for (unsigned I = 0, N = Record.size(); I != N; I += 2) {
- GlobalDeclID ID = getGlobalDeclID(F, Record[I]);
- DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1]));
-
- // If we've already loaded the decl, perform the updates when we finish
- // loading this block.
- if (Decl *D = GetExistingDecl(ID))
- PendingUpdateRecords.push_back(
- PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
- }
- break;
-
- case OBJC_CATEGORIES_MAP:
- if (F.LocalNumObjCCategoriesInMap != 0) {
- Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
- return Failure;
- }
-
- F.LocalNumObjCCategoriesInMap = Record[0];
- F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data();
- break;
-
- case OBJC_CATEGORIES:
- F.ObjCCategories.swap(Record);
- break;
-
- case CUDA_SPECIAL_DECL_REFS:
- // Later tables overwrite earlier ones.
- // FIXME: Modules will have trouble with this.
- CUDASpecialDeclRefs.clear();
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case HEADER_SEARCH_TABLE:
- F.HeaderFileInfoTableData = Blob.data();
- F.LocalNumHeaderFileInfos = Record[1];
- if (Record[0]) {
- F.HeaderFileInfoTable
- = HeaderFileInfoLookupTable::Create(
- (const unsigned char *)F.HeaderFileInfoTableData + Record[0],
- (const unsigned char *)F.HeaderFileInfoTableData,
- HeaderFileInfoTrait(*this, F,
- &PP.getHeaderSearchInfo(),
- Blob.data() + Record[2]));
-
- PP.getHeaderSearchInfo().SetExternalSource(this);
- if (!PP.getHeaderSearchInfo().getExternalLookup())
- PP.getHeaderSearchInfo().SetExternalLookup(this);
- }
- break;
-
- case FP_PRAGMA_OPTIONS:
- // Later tables overwrite earlier ones.
- FPPragmaOptions.swap(Record);
- break;
-
- case OPENCL_EXTENSIONS:
- for (unsigned I = 0, E = Record.size(); I != E; ) {
- auto Name = ReadString(Record, I);
- auto &Opt = OpenCLExtensions.OptMap[Name];
- Opt.Supported = Record[I++] != 0;
- Opt.Enabled = Record[I++] != 0;
- Opt.Avail = Record[I++];
- Opt.Core = Record[I++];
- }
- break;
-
- case OPENCL_EXTENSION_TYPES:
- for (unsigned I = 0, E = Record.size(); I != E;) {
- auto TypeID = static_cast<::TypeID>(Record[I++]);
- auto *Type = GetType(TypeID).getTypePtr();
- auto NumExt = static_cast<unsigned>(Record[I++]);
- for (unsigned II = 0; II != NumExt; ++II) {
- auto Ext = ReadString(Record, I);
- OpenCLTypeExtMap[Type].insert(Ext);
- }
- }
- break;
-
- case OPENCL_EXTENSION_DECLS:
- for (unsigned I = 0, E = Record.size(); I != E;) {
- auto DeclID = static_cast<::DeclID>(Record[I++]);
- auto *Decl = GetDecl(DeclID);
- auto NumExt = static_cast<unsigned>(Record[I++]);
- for (unsigned II = 0; II != NumExt; ++II) {
- auto Ext = ReadString(Record, I);
- OpenCLDeclExtMap[Decl].insert(Ext);
- }
- }
- break;
-
- case TENTATIVE_DEFINITIONS:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case KNOWN_NAMESPACES:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- KnownNamespaces.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
- case UNDEFINED_BUT_USED:
- if (UndefinedButUsed.size() % 2 != 0) {
- Error("Invalid existing UndefinedButUsed");
- return Failure;
- }
-
- if (Record.size() % 2 != 0) {
- Error("invalid undefined-but-used record");
- return Failure;
- }
- for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
- UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++]));
- UndefinedButUsed.push_back(
- ReadSourceLocation(F, Record, I).getRawEncoding());
- }
- break;
-
- case DELETE_EXPRS_TO_ANALYZE:
- for (unsigned I = 0, N = Record.size(); I != N;) {
- DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++]));
- const uint64_t Count = Record[I++];
- DelayedDeleteExprs.push_back(Count);
- for (uint64_t C = 0; C < Count; ++C) {
- DelayedDeleteExprs.push_back(ReadSourceLocation(F, Record, I).getRawEncoding());
- bool IsArrayForm = Record[I++] == 1;
- DelayedDeleteExprs.push_back(IsArrayForm);
- }
- }
- break;
-
- case IMPORTED_MODULES:
- if (!F.isModule()) {
- // If we aren't loading a module (which has its own exports), make
- // all of the imported modules visible.
- // FIXME: Deal with macros-only imports.
- for (unsigned I = 0, N = Record.size(); I != N; /**/) {
- unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
- SourceLocation Loc = ReadSourceLocation(F, Record, I);
- if (GlobalID) {
- ImportedModules.push_back(ImportedSubmodule(GlobalID, Loc));
- if (DeserializationListener)
- DeserializationListener->ModuleImportRead(GlobalID, Loc);
- }
- }
- }
- break;
-
- case MACRO_OFFSET: {
- if (F.LocalNumMacros != 0) {
- Error("duplicate MACRO_OFFSET record in AST file");
- return Failure;
- }
- F.MacroOffsets = (const uint32_t *)Blob.data();
- F.LocalNumMacros = Record[0];
- unsigned LocalBaseMacroID = Record[1];
- F.BaseMacroID = getTotalNumMacros();
-
- if (F.LocalNumMacros > 0) {
- // Introduce the global -> local mapping for macros within this module.
- GlobalMacroMap.insert(std::make_pair(getTotalNumMacros() + 1, &F));
-
- // Introduce the local -> global mapping for macros within this module.
- F.MacroRemap.insertOrReplace(
- std::make_pair(LocalBaseMacroID,
- F.BaseMacroID - LocalBaseMacroID));
-
- MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros);
- }
- break;
- }
-
- case LATE_PARSED_TEMPLATE:
- LateParsedTemplates.append(Record.begin(), Record.end());
- break;
-
- case OPTIMIZE_PRAGMA_OPTIONS:
- if (Record.size() != 1) {
- Error("invalid pragma optimize record");
- return Failure;
- }
- OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
- break;
-
- case MSSTRUCT_PRAGMA_OPTIONS:
- if (Record.size() != 1) {
- Error("invalid pragma ms_struct record");
- return Failure;
- }
- PragmaMSStructState = Record[0];
- break;
-
- case POINTERS_TO_MEMBERS_PRAGMA_OPTIONS:
- if (Record.size() != 2) {
- Error("invalid pragma ms_struct record");
- return Failure;
- }
- PragmaMSPointersToMembersState = Record[0];
- PointersToMembersPragmaLocation = ReadSourceLocation(F, Record[1]);
- break;
-
- case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- UnusedLocalTypedefNameCandidates.push_back(
- getGlobalDeclID(F, Record[I]));
- break;
-
- case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH:
- if (Record.size() != 1) {
- Error("invalid cuda pragma options record");
- return Failure;
- }
- ForceCUDAHostDeviceDepth = Record[0];
- break;
-
- case PACK_PRAGMA_OPTIONS: {
- if (Record.size() < 3) {
- Error("invalid pragma pack record");
- return Failure;
- }
- PragmaPackCurrentValue = Record[0];
- PragmaPackCurrentLocation = ReadSourceLocation(F, Record[1]);
- unsigned NumStackEntries = Record[2];
- unsigned Idx = 3;
- // Reset the stack when importing a new module.
- PragmaPackStack.clear();
- for (unsigned I = 0; I < NumStackEntries; ++I) {
- PragmaPackStackEntry Entry;
- Entry.Value = Record[Idx++];
- Entry.Location = ReadSourceLocation(F, Record[Idx++]);
- Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]);
- PragmaPackStrings.push_back(ReadString(Record, Idx));
- Entry.SlotLabel = PragmaPackStrings.back();
- PragmaPackStack.push_back(Entry);
- }
- break;
- }
- }
- }
-}
-
-void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
- assert(!F.ModuleOffsetMap.empty() && "no module offset map to read");
-
- // Additional remapping information.
- const unsigned char *Data = (const unsigned char*)F.ModuleOffsetMap.data();
- const unsigned char *DataEnd = Data + F.ModuleOffsetMap.size();
- F.ModuleOffsetMap = StringRef();
-
- // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders.
- if (F.SLocRemap.find(0) == F.SLocRemap.end()) {
- F.SLocRemap.insert(std::make_pair(0U, 0));
- F.SLocRemap.insert(std::make_pair(2U, 1));
- }
-
- // Continuous range maps we may be updating in our module.
- using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder;
- RemapBuilder SLocRemap(F.SLocRemap);
- RemapBuilder IdentifierRemap(F.IdentifierRemap);
- RemapBuilder MacroRemap(F.MacroRemap);
- RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap);
- RemapBuilder SubmoduleRemap(F.SubmoduleRemap);
- RemapBuilder SelectorRemap(F.SelectorRemap);
- RemapBuilder DeclRemap(F.DeclRemap);
- RemapBuilder TypeRemap(F.TypeRemap);
-
- while (Data < DataEnd) {
- // FIXME: Looking up dependency modules by filename is horrible. Let's
- // start fixing this with prebuilt and explicit modules and see how it
- // goes...
- using namespace llvm::support;
- ModuleKind Kind = static_cast<ModuleKind>(
- endian::readNext<uint8_t, little, unaligned>(Data));
- uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
- StringRef Name = StringRef((const char*)Data, Len);
- Data += Len;
- ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule
- ? ModuleMgr.lookupByModuleName(Name)
- : ModuleMgr.lookupByFileName(Name));
- if (!OM) {
- std::string Msg =
- "SourceLocation remap refers to unknown module, cannot find ";
- Msg.append(Name);
- Error(Msg);
- return;
- }
-
- uint32_t SLocOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t IdentifierIDOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t MacroIDOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t PreprocessedEntityIDOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t SubmoduleIDOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t SelectorIDOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t DeclIDOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
- uint32_t TypeIndexOffset =
- endian::readNext<uint32_t, little, unaligned>(Data);
-
- uint32_t None = std::numeric_limits<uint32_t>::max();
-
- auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset,
- RemapBuilder &Remap) {
- if (Offset != None)
- Remap.insert(std::make_pair(Offset,
- static_cast<int>(BaseOffset - Offset)));
- };
- mapOffset(SLocOffset, OM->SLocEntryBaseOffset, SLocRemap);
- mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap);
- mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap);
- mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID,
- PreprocessedEntityRemap);
- mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap);
- mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap);
- mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap);
- mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap);
-
- // Global -> local mappings.
- F.GlobalToLocalDeclIDs[OM] = DeclIDOffset;
- }
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
- const ModuleFile *ImportedBy,
- unsigned ClientLoadCapabilities) {
- unsigned Idx = 0;
- F.ModuleMapPath = ReadPath(F, Record, Idx);
-
- // Try to resolve ModuleName in the current header search context and
- // verify that it is found in the same module map file as we saved. If the
- // top-level AST file is a main file, skip this check because there is no
- // usable header search context.
- assert(!F.ModuleName.empty() &&
- "MODULE_NAME should come before MODULE_MAP_FILE");
- if (F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) {
- // An implicitly-loaded module file should have its module listed in some
- // module map file that we've already loaded.
- Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
- // Don't emit module relocation error if we have -fno-validate-pch
- if (!PP.getPreprocessorOpts().DisablePCHValidation && !ModMap) {
- assert(ImportedBy && "top-level import should be verified");
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) {
- if (auto *ASTFE = M ? M->getASTFile() : nullptr) {
- // This module was defined by an imported (explicit) module.
- Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName
- << ASTFE->getName();
- } else {
- // This module was built with a different module map.
- Diag(diag::err_imported_module_not_found)
- << F.ModuleName << F.FileName << ImportedBy->FileName
- << F.ModuleMapPath;
- // In case it was imported by a PCH, there's a chance the user is
- // just missing to include the search path to the directory containing
- // the modulemap.
- if (ImportedBy->Kind == MK_PCH)
- Diag(diag::note_imported_by_pch_module_not_found)
- << llvm::sys::path::parent_path(F.ModuleMapPath);
- }
- }
- return OutOfDate;
- }
-
- assert(M->Name == F.ModuleName && "found module with different name");
-
- // Check the primary module map file.
- const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
- if (StoredModMap == nullptr || StoredModMap != ModMap) {
- assert(ModMap && "found module is missing module map file");
- assert(ImportedBy && "top-level import should be verified");
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Diag(diag::err_imported_module_modmap_changed)
- << F.ModuleName << ImportedBy->FileName
- << ModMap->getName() << F.ModuleMapPath;
- return OutOfDate;
- }
-
- llvm::SmallPtrSet<const FileEntry *, 1> AdditionalStoredMaps;
- for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) {
- // FIXME: we should use input files rather than storing names.
- std::string Filename = ReadPath(F, Record, Idx);
- const FileEntry *F =
- FileMgr.getFile(Filename, false, false);
- if (F == nullptr) {
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Error("could not find file '" + Filename +"' referenced by AST file");
- return OutOfDate;
- }
- AdditionalStoredMaps.insert(F);
- }
-
- // Check any additional module map files (e.g. module.private.modulemap)
- // that are not in the pcm.
- if (auto *AdditionalModuleMaps = Map.getAdditionalModuleMapFiles(M)) {
- for (const FileEntry *ModMap : *AdditionalModuleMaps) {
- // Remove files that match
- // Note: SmallPtrSet::erase is really remove
- if (!AdditionalStoredMaps.erase(ModMap)) {
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Diag(diag::err_module_different_modmap)
- << F.ModuleName << /*new*/0 << ModMap->getName();
- return OutOfDate;
- }
- }
- }
-
- // Check any additional module map files that are in the pcm, but not
- // found in header search. Cases that match are already removed.
- for (const FileEntry *ModMap : AdditionalStoredMaps) {
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Diag(diag::err_module_different_modmap)
- << F.ModuleName << /*not new*/1 << ModMap->getName();
- return OutOfDate;
- }
- }
-
- if (Listener)
- Listener->ReadModuleMapFile(F.ModuleMapPath);
- return Success;
-}
-
-/// Move the given method to the back of the global list of methods.
-static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {
- // Find the entry for this selector in the method pool.
- Sema::GlobalMethodPool::iterator Known
- = S.MethodPool.find(Method->getSelector());
- if (Known == S.MethodPool.end())
- return;
-
- // Retrieve the appropriate method list.
- ObjCMethodList &Start = Method->isInstanceMethod()? Known->second.first
- : Known->second.second;
- bool Found = false;
- for (ObjCMethodList *List = &Start; List; List = List->getNext()) {
- if (!Found) {
- if (List->getMethod() == Method) {
- Found = true;
- } else {
- // Keep searching.
- continue;
- }
- }
-
- if (List->getNext())
- List->setMethod(List->getNext()->getMethod());
- else
- List->setMethod(Method);
- }
-}
-
-void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) {
- assert(Owner->NameVisibility != Module::Hidden && "nothing to make visible?");
- for (Decl *D : Names) {
- bool wasHidden = D->isHidden();
- D->setVisibleDespiteOwningModule();
-
- if (wasHidden && SemaObj) {
- if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) {
- moveMethodToBackOfGlobalList(*SemaObj, Method);
- }
- }
- }
-}
-
-void ASTReader::makeModuleVisible(Module *Mod,
- Module::NameVisibilityKind NameVisibility,
- SourceLocation ImportLoc) {
- llvm::SmallPtrSet<Module *, 4> Visited;
- SmallVector<Module *, 4> Stack;
- Stack.push_back(Mod);
- while (!Stack.empty()) {
- Mod = Stack.pop_back_val();
-
- if (NameVisibility <= Mod->NameVisibility) {
- // This module already has this level of visibility (or greater), so
- // there is nothing more to do.
- continue;
- }
-
- if (!Mod->isAvailable()) {
- // Modules that aren't available cannot be made visible.
- continue;
- }
-
- // Update the module's name visibility.
- Mod->NameVisibility = NameVisibility;
-
- // If we've already deserialized any names from this module,
- // mark them as visible.
- HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod);
- if (Hidden != HiddenNamesMap.end()) {
- auto HiddenNames = std::move(*Hidden);
- HiddenNamesMap.erase(Hidden);
- makeNamesVisible(HiddenNames.second, HiddenNames.first);
- assert(HiddenNamesMap.find(Mod) == HiddenNamesMap.end() &&
- "making names visible added hidden names");
- }
-
- // Push any exported modules onto the stack to be marked as visible.
- SmallVector<Module *, 16> Exports;
- Mod->getExportedModules(Exports);
- for (SmallVectorImpl<Module *>::iterator
- I = Exports.begin(), E = Exports.end(); I != E; ++I) {
- Module *Exported = *I;
- if (Visited.insert(Exported).second)
- Stack.push_back(Exported);
- }
- }
-}
-
-/// We've merged the definition \p MergedDef into the existing definition
-/// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made
-/// visible.
-void ASTReader::mergeDefinitionVisibility(NamedDecl *Def,
- NamedDecl *MergedDef) {
- if (Def->isHidden()) {
- // If MergedDef is visible or becomes visible, make the definition visible.
- if (!MergedDef->isHidden())
- Def->setVisibleDespiteOwningModule();
- else {
- getContext().mergeDefinitionIntoModule(
- Def, MergedDef->getImportedOwningModule(),
- /*NotifyListeners*/ false);
- PendingMergedDefinitionsToDeduplicate.insert(Def);
- }
- }
-}
-
-bool ASTReader::loadGlobalIndex() {
- if (GlobalIndex)
- return false;
-
- if (TriedLoadingGlobalIndex || !UseGlobalIndex ||
- !PP.getLangOpts().Modules)
- return true;
-
- // Try to load the global index.
- TriedLoadingGlobalIndex = true;
- StringRef ModuleCachePath
- = getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
- std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> Result
- = GlobalModuleIndex::readIndex(ModuleCachePath);
- if (!Result.first)
- return true;
-
- GlobalIndex.reset(Result.first);
- ModuleMgr.setGlobalIndex(GlobalIndex.get());
- return false;
-}
-
-bool ASTReader::isGlobalIndexUnavailable() const {
- return PP.getLangOpts().Modules && UseGlobalIndex &&
- !hasGlobalIndex() && TriedLoadingGlobalIndex;
-}
-
-static void updateModuleTimestamp(ModuleFile &MF) {
- // Overwrite the timestamp file contents so that file's mtime changes.
- std::string TimestampFilename = MF.getTimestampFilename();
- std::error_code EC;
- llvm::raw_fd_ostream OS(TimestampFilename, EC, llvm::sys::fs::F_Text);
- if (EC)
- return;
- OS << "Timestamp file\n";
- OS.close();
- OS.clear_error(); // Avoid triggering a fatal error.
-}
-
-/// Given a cursor at the start of an AST file, scan ahead and drop the
-/// cursor into the start of the given block ID, returning false on success and
-/// true on failure.
-static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) {
- while (true) {
- llvm::BitstreamEntry Entry = Cursor.advance();
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- case llvm::BitstreamEntry::EndBlock:
- return true;
-
- case llvm::BitstreamEntry::Record:
- // Ignore top-level records.
- Cursor.skipRecord(Entry.ID);
- break;
-
- case llvm::BitstreamEntry::SubBlock:
- if (Entry.ID == BlockID) {
- if (Cursor.EnterSubBlock(BlockID))
- return true;
- // Found it!
- return false;
- }
-
- if (Cursor.SkipBlock())
- return true;
- }
- }
-}
-
-ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
- ModuleKind Type,
- SourceLocation ImportLoc,
- unsigned ClientLoadCapabilities,
- SmallVectorImpl<ImportedSubmodule> *Imported) {
- llvm::SaveAndRestore<SourceLocation>
- SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
-
- // Defer any pending actions until we get to the end of reading the AST file.
- Deserializing AnASTFile(this);
-
- // Bump the generation number.
- unsigned PreviousGeneration = 0;
- if (ContextObj)
- PreviousGeneration = incrementGeneration(*ContextObj);
-
- unsigned NumModules = ModuleMgr.size();
- SmallVector<ImportedModule, 4> Loaded;
- switch (ASTReadResult ReadResult =
- ReadASTCore(FileName, Type, ImportLoc,
- /*ImportedBy=*/nullptr, Loaded, 0, 0,
- ASTFileSignature(), ClientLoadCapabilities)) {
- case Failure:
- case Missing:
- case OutOfDate:
- case VersionMismatch:
- case ConfigurationMismatch:
- case HadErrors: {
- llvm::SmallPtrSet<ModuleFile *, 4> LoadedSet;
- for (const ImportedModule &IM : Loaded)
- LoadedSet.insert(IM.Mod);
-
- ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, LoadedSet,
- PP.getLangOpts().Modules
- ? &PP.getHeaderSearchInfo().getModuleMap()
- : nullptr);
-
- // If we find that any modules are unusable, the global index is going
- // to be out-of-date. Just remove it.
- GlobalIndex.reset();
- ModuleMgr.setGlobalIndex(nullptr);
- return ReadResult;
- }
- case Success:
- break;
- }
-
- // Here comes stuff that we only do once the entire chain is loaded.
-
- // Load the AST blocks of all of the modules that we loaded.
- for (SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),
- MEnd = Loaded.end();
- M != MEnd; ++M) {
- ModuleFile &F = *M->Mod;
-
- // Read the AST block.
- if (ASTReadResult Result = ReadASTBlock(F, ClientLoadCapabilities))
- return Result;
-
- // Read the extension blocks.
- while (!SkipCursorToBlock(F.Stream, EXTENSION_BLOCK_ID)) {
- if (ASTReadResult Result = ReadExtensionBlock(F))
- return Result;
- }
-
- // Once read, set the ModuleFile bit base offset and update the size in
- // bits of all files we've seen.
- F.GlobalBitOffset = TotalModulesSizeInBits;
- TotalModulesSizeInBits += F.SizeInBits;
- GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
-
- // Preload SLocEntries.
- for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {
- int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
- // Load it through the SourceManager and don't call ReadSLocEntry()
- // directly because the entry may have already been loaded in which case
- // calling ReadSLocEntry() directly would trigger an assertion in
- // SourceManager.
- SourceMgr.getLoadedSLocEntryByID(Index);
- }
-
- // Map the original source file ID into the ID space of the current
- // compilation.
- if (F.OriginalSourceFileID.isValid()) {
- F.OriginalSourceFileID = FileID::get(
- F.SLocEntryBaseID + F.OriginalSourceFileID.getOpaqueValue() - 1);
- }
-
- // Preload all the pending interesting identifiers by marking them out of
- // date.
- for (auto Offset : F.PreloadIdentifierOffsets) {
- const unsigned char *Data = reinterpret_cast<const unsigned char *>(
- F.IdentifierTableData + Offset);
-
- ASTIdentifierLookupTrait Trait(*this, F);
- auto KeyDataLen = Trait.ReadKeyDataLength(Data);
- auto Key = Trait.ReadKey(Data, KeyDataLen.first);
- auto &II = PP.getIdentifierTable().getOwn(Key);
- II.setOutOfDate(true);
-
- // Mark this identifier as being from an AST file so that we can track
- // whether we need to serialize it.
- markIdentifierFromAST(*this, II);
-
- // Associate the ID with the identifier so that the writer can reuse it.
- auto ID = Trait.ReadIdentifierID(Data + KeyDataLen.first);
- SetIdentifierInfo(ID, &II);
- }
- }
-
- // Setup the import locations and notify the module manager that we've
- // committed to these module files.
- for (SmallVectorImpl<ImportedModule>::iterator M = Loaded.begin(),
- MEnd = Loaded.end();
- M != MEnd; ++M) {
- ModuleFile &F = *M->Mod;
-
- ModuleMgr.moduleFileAccepted(&F);
-
- // Set the import location.
- F.DirectImportLoc = ImportLoc;
- // FIXME: We assume that locations from PCH / preamble do not need
- // any translation.
- if (!M->ImportedBy)
- F.ImportLoc = M->ImportLoc;
- else
- F.ImportLoc = TranslateSourceLocation(*M->ImportedBy, M->ImportLoc);
- }
-
- if (!PP.getLangOpts().CPlusPlus ||
- (Type != MK_ImplicitModule && Type != MK_ExplicitModule &&
- Type != MK_PrebuiltModule)) {
- // Mark all of the identifiers in the identifier table as being out of date,
- // so that various accessors know to check the loaded modules when the
- // identifier is used.
- //
- // For C++ modules, we don't need information on many identifiers (just
- // those that provide macros or are poisoned), so we mark all of
- // the interesting ones via PreloadIdentifierOffsets.
- for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
- IdEnd = PP.getIdentifierTable().end();
- Id != IdEnd; ++Id)
- Id->second->setOutOfDate(true);
- }
- // Mark selectors as out of date.
- for (auto Sel : SelectorGeneration)
- SelectorOutOfDate[Sel.first] = true;
-
- // Resolve any unresolved module exports.
- for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I) {
- UnresolvedModuleRef &Unresolved = UnresolvedModuleRefs[I];
- SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID);
- Module *ResolvedMod = getSubmodule(GlobalID);
-
- switch (Unresolved.Kind) {
- case UnresolvedModuleRef::Conflict:
- if (ResolvedMod) {
- Module::Conflict Conflict;
- Conflict.Other = ResolvedMod;
- Conflict.Message = Unresolved.String.str();
- Unresolved.Mod->Conflicts.push_back(Conflict);
- }
- continue;
-
- case UnresolvedModuleRef::Import:
- if (ResolvedMod)
- Unresolved.Mod->Imports.insert(ResolvedMod);
- continue;
-
- case UnresolvedModuleRef::Export:
- if (ResolvedMod || Unresolved.IsWildcard)
- Unresolved.Mod->Exports.push_back(
- Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));
- continue;
- }
- }
- UnresolvedModuleRefs.clear();
-
- if (Imported)
- Imported->append(ImportedModules.begin(),
- ImportedModules.end());
-
- // FIXME: How do we load the 'use'd modules? They may not be submodules.
- // Might be unnecessary as use declarations are only used to build the
- // module itself.
-
- if (ContextObj)
- InitializeContext();
-
- if (SemaObj)
- UpdateSema();
-
- if (DeserializationListener)
- DeserializationListener->ReaderInitialized(this);
-
- ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule();
- if (PrimaryModule.OriginalSourceFileID.isValid()) {
- // If this AST file is a precompiled preamble, then set the
- // preamble file ID of the source manager to the file source file
- // from which the preamble was built.
- if (Type == MK_Preamble) {
- SourceMgr.setPreambleFileID(PrimaryModule.OriginalSourceFileID);
- } else if (Type == MK_MainFile) {
- SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID);
- }
- }
-
- // For any Objective-C class definitions we have already loaded, make sure
- // that we load any additional categories.
- if (ContextObj) {
- for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) {
- loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(),
- ObjCClassesLoaded[I],
- PreviousGeneration);
- }
- }
-
- if (PP.getHeaderSearchInfo()
- .getHeaderSearchOpts()
- .ModulesValidateOncePerBuildSession) {
- // Now we are certain that the module and all modules it depends on are
- // up to date. Create or update timestamp files for modules that are
- // located in the module cache (not for PCH files that could be anywhere
- // in the filesystem).
- for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {
- ImportedModule &M = Loaded[I];
- if (M.Mod->Kind == MK_ImplicitModule) {
- updateModuleTimestamp(*M.Mod);
- }
- }
- }
-
- return Success;
-}
-
-static ASTFileSignature readASTFileSignature(StringRef PCH);
-
-/// Whether \p Stream starts with the AST/PCH file magic number 'CPCH'.
-static bool startsWithASTFileMagic(BitstreamCursor &Stream) {
- return Stream.canSkipToPos(4) &&
- Stream.Read(8) == 'C' &&
- Stream.Read(8) == 'P' &&
- Stream.Read(8) == 'C' &&
- Stream.Read(8) == 'H';
-}
-
-static unsigned moduleKindForDiagnostic(ModuleKind Kind) {
- switch (Kind) {
- case MK_PCH:
- return 0; // PCH
- case MK_ImplicitModule:
- case MK_ExplicitModule:
- case MK_PrebuiltModule:
- return 1; // module
- case MK_MainFile:
- case MK_Preamble:
- return 2; // main source file
- }
- llvm_unreachable("unknown module kind");
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadASTCore(StringRef FileName,
- ModuleKind Type,
- SourceLocation ImportLoc,
- ModuleFile *ImportedBy,
- SmallVectorImpl<ImportedModule> &Loaded,
- off_t ExpectedSize, time_t ExpectedModTime,
- ASTFileSignature ExpectedSignature,
- unsigned ClientLoadCapabilities) {
- ModuleFile *M;
- std::string ErrorStr;
- ModuleManager::AddModuleResult AddResult
- = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,
- getGeneration(), ExpectedSize, ExpectedModTime,
- ExpectedSignature, readASTFileSignature,
- M, ErrorStr);
-
- switch (AddResult) {
- case ModuleManager::AlreadyLoaded:
- return Success;
-
- case ModuleManager::NewlyLoaded:
- // Load module file below.
- break;
-
- case ModuleManager::Missing:
- // The module file was missing; if the client can handle that, return
- // it.
- if (ClientLoadCapabilities & ARR_Missing)
- return Missing;
-
- // Otherwise, return an error.
- Diag(diag::err_module_file_not_found) << moduleKindForDiagnostic(Type)
- << FileName << !ErrorStr.empty()
- << ErrorStr;
- return Failure;
-
- case ModuleManager::OutOfDate:
- // We couldn't load the module file because it is out-of-date. If the
- // client can handle out-of-date, return it.
- if (ClientLoadCapabilities & ARR_OutOfDate)
- return OutOfDate;
-
- // Otherwise, return an error.
- Diag(diag::err_module_file_out_of_date) << moduleKindForDiagnostic(Type)
- << FileName << !ErrorStr.empty()
- << ErrorStr;
- return Failure;
- }
-
- assert(M && "Missing module file");
-
- ModuleFile &F = *M;
- BitstreamCursor &Stream = F.Stream;
- Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer));
- F.SizeInBits = F.Buffer->getBufferSize() * 8;
-
- // Sniff for the signature.
- if (!startsWithASTFileMagic(Stream)) {
- Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type)
- << FileName;
- return Failure;
- }
-
- // This is used for compatibility with older PCH formats.
- bool HaveReadControlBlock = false;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- case llvm::BitstreamEntry::Record:
- case llvm::BitstreamEntry::EndBlock:
- Error("invalid record at top-level of AST file");
- return Failure;
-
- case llvm::BitstreamEntry::SubBlock:
- break;
- }
-
- switch (Entry.ID) {
- case CONTROL_BLOCK_ID:
- HaveReadControlBlock = true;
- switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) {
- case Success:
- // Check that we didn't try to load a non-module AST file as a module.
- //
- // FIXME: Should we also perform the converse check? Loading a module as
- // a PCH file sort of works, but it's a bit wonky.
- if ((Type == MK_ImplicitModule || Type == MK_ExplicitModule ||
- Type == MK_PrebuiltModule) &&
- F.ModuleName.empty()) {
- auto Result = (Type == MK_ImplicitModule) ? OutOfDate : Failure;
- if (Result != OutOfDate ||
- (ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Diag(diag::err_module_file_not_module) << FileName;
- return Result;
- }
- break;
-
- case Failure: return Failure;
- case Missing: return Missing;
- case OutOfDate: return OutOfDate;
- case VersionMismatch: return VersionMismatch;
- case ConfigurationMismatch: return ConfigurationMismatch;
- case HadErrors: return HadErrors;
- }
- break;
-
- case AST_BLOCK_ID:
- if (!HaveReadControlBlock) {
- if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
- Diag(diag::err_pch_version_too_old);
- return VersionMismatch;
- }
-
- // Record that we've loaded this module.
- Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
- return Success;
-
- case UNHASHED_CONTROL_BLOCK_ID:
- // This block is handled using look-ahead during ReadControlBlock. We
- // shouldn't get here!
- Error("malformed block record in AST file");
- return Failure;
-
- default:
- if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
- return Failure;
- }
- break;
- }
- }
-
- return Success;
-}
-
-ASTReader::ASTReadResult
-ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
- unsigned ClientLoadCapabilities) {
- const HeaderSearchOptions &HSOpts =
- PP.getHeaderSearchInfo().getHeaderSearchOpts();
- bool AllowCompatibleConfigurationMismatch =
- F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
-
- ASTReadResult Result = readUnhashedControlBlockImpl(
- &F, F.Data, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch,
- Listener.get(),
- WasImportedBy ? false : HSOpts.ModulesValidateDiagnosticOptions);
-
- // If F was directly imported by another module, it's implicitly validated by
- // the importing module.
- if (DisableValidation || WasImportedBy ||
- (AllowConfigurationMismatch && Result == ConfigurationMismatch))
- return Success;
-
- if (Result == Failure) {
- Error("malformed block record in AST file");
- return Failure;
- }
-
- if (Result == OutOfDate && F.Kind == MK_ImplicitModule) {
- // If this module has already been finalized in the PCMCache, we're stuck
- // with it; we can only load a single version of each module.
- //
- // This can happen when a module is imported in two contexts: in one, as a
- // user module; in another, as a system module (due to an import from
- // another module marked with the [system] flag). It usually indicates a
- // bug in the module map: this module should also be marked with [system].
- //
- // If -Wno-system-headers (the default), and the first import is as a
- // system module, then validation will fail during the as-user import,
- // since -Werror flags won't have been validated. However, it's reasonable
- // to treat this consistently as a system module.
- //
- // If -Wsystem-headers, the PCM on disk was built with
- // -Wno-system-headers, and the first import is as a user module, then
- // validation will fail during the as-system import since the PCM on disk
- // doesn't guarantee that -Werror was respected. However, the -Werror
- // flags were checked during the initial as-user import.
- if (PCMCache.isBufferFinal(F.FileName)) {
- Diag(diag::warn_module_system_bit_conflict) << F.FileName;
- return Success;
- }
- }
-
- return Result;
-}
-
-ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
- ModuleFile *F, llvm::StringRef StreamData, unsigned ClientLoadCapabilities,
- bool AllowCompatibleConfigurationMismatch, ASTReaderListener *Listener,
- bool ValidateDiagnosticOptions) {
- // Initialize a stream.
- BitstreamCursor Stream(StreamData);
-
- // Sniff for the signature.
- if (!startsWithASTFileMagic(Stream))
- return Failure;
-
- // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
- if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
- return Failure;
-
- // Read all of the records in the options block.
- RecordData Record;
- ASTReadResult Result = Success;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- case llvm::BitstreamEntry::SubBlock:
- return Failure;
-
- case llvm::BitstreamEntry::EndBlock:
- return Result;
-
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read and process a record.
- Record.clear();
- switch (
- (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) {
- case SIGNATURE:
- if (F)
- std::copy(Record.begin(), Record.end(), F->Signature.data());
- break;
- case DIAGNOSTIC_OPTIONS: {
- bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
- if (Listener && ValidateDiagnosticOptions &&
- !AllowCompatibleConfigurationMismatch &&
- ParseDiagnosticOptions(Record, Complain, *Listener))
- Result = OutOfDate; // Don't return early. Read the signature.
- break;
- }
- case DIAG_PRAGMA_MAPPINGS:
- if (!F)
- break;
- if (F->PragmaDiagMappings.empty())
- F->PragmaDiagMappings.swap(Record);
- else
- F->PragmaDiagMappings.insert(F->PragmaDiagMappings.end(),
- Record.begin(), Record.end());
- break;
- }
- }
-}
-
-/// Parse a record and blob containing module file extension metadata.
-static bool parseModuleFileExtensionMetadata(
- const SmallVectorImpl<uint64_t> &Record,
- StringRef Blob,
- ModuleFileExtensionMetadata &Metadata) {
- if (Record.size() < 4) return true;
-
- Metadata.MajorVersion = Record[0];
- Metadata.MinorVersion = Record[1];
-
- unsigned BlockNameLen = Record[2];
- unsigned UserInfoLen = Record[3];
-
- if (BlockNameLen + UserInfoLen > Blob.size()) return true;
-
- Metadata.BlockName = std::string(Blob.data(), Blob.data() + BlockNameLen);
- Metadata.UserInfo = std::string(Blob.data() + BlockNameLen,
- Blob.data() + BlockNameLen + UserInfoLen);
- return false;
-}
-
-ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) {
- BitstreamCursor &Stream = F.Stream;
-
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock:
- if (Stream.SkipBlock())
- return Failure;
-
- continue;
-
- case llvm::BitstreamEntry::EndBlock:
- return Success;
-
- case llvm::BitstreamEntry::Error:
- return HadErrors;
-
- case llvm::BitstreamEntry::Record:
- break;
- }
-
- Record.clear();
- StringRef Blob;
- unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
- switch (RecCode) {
- case EXTENSION_METADATA: {
- ModuleFileExtensionMetadata Metadata;
- if (parseModuleFileExtensionMetadata(Record, Blob, Metadata))
- return Failure;
-
- // Find a module file extension with this block name.
- auto Known = ModuleFileExtensions.find(Metadata.BlockName);
- if (Known == ModuleFileExtensions.end()) break;
-
- // Form a reader.
- if (auto Reader = Known->second->createExtensionReader(Metadata, *this,
- F, Stream)) {
- F.ExtensionReaders.push_back(std::move(Reader));
- }
-
- break;
- }
- }
- }
-
- return Success;
-}
-
-void ASTReader::InitializeContext() {
- assert(ContextObj && "no context to initialize");
- ASTContext &Context = *ContextObj;
-
- // If there's a listener, notify them that we "read" the translation unit.
- if (DeserializationListener)
- DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID,
- Context.getTranslationUnitDecl());
-
- // FIXME: Find a better way to deal with collisions between these
- // built-in types. Right now, we just ignore the problem.
-
- // Load the special types.
- if (SpecialTypes.size() >= NumSpecialTypeIDs) {
- if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) {
- if (!Context.CFConstantStringTypeDecl)
- Context.setCFConstantStringType(GetType(String));
- }
-
- if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) {
- QualType FileType = GetType(File);
- if (FileType.isNull()) {
- Error("FILE type is NULL");
- return;
- }
-
- if (!Context.FILEDecl) {
- if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
- Context.setFILEDecl(Typedef->getDecl());
- else {
- const TagType *Tag = FileType->getAs<TagType>();
- if (!Tag) {
- Error("Invalid FILE type in AST file");
- return;
- }
- Context.setFILEDecl(Tag->getDecl());
- }
- }
- }
-
- if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) {
- QualType Jmp_bufType = GetType(Jmp_buf);
- if (Jmp_bufType.isNull()) {
- Error("jmp_buf type is NULL");
- return;
- }
-
- if (!Context.jmp_bufDecl) {
- if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
- Context.setjmp_bufDecl(Typedef->getDecl());
- else {
- const TagType *Tag = Jmp_bufType->getAs<TagType>();
- if (!Tag) {
- Error("Invalid jmp_buf type in AST file");
- return;
- }
- Context.setjmp_bufDecl(Tag->getDecl());
- }
- }
- }
-
- if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) {
- QualType Sigjmp_bufType = GetType(Sigjmp_buf);
- if (Sigjmp_bufType.isNull()) {
- Error("sigjmp_buf type is NULL");
- return;
- }
-
- if (!Context.sigjmp_bufDecl) {
- if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
- Context.setsigjmp_bufDecl(Typedef->getDecl());
- else {
- const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
- assert(Tag && "Invalid sigjmp_buf type in AST file");
- Context.setsigjmp_bufDecl(Tag->getDecl());
- }
- }
- }
-
- if (unsigned ObjCIdRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) {
- if (Context.ObjCIdRedefinitionType.isNull())
- Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef);
- }
-
- if (unsigned ObjCClassRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) {
- if (Context.ObjCClassRedefinitionType.isNull())
- Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef);
- }
-
- if (unsigned ObjCSelRedef
- = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) {
- if (Context.ObjCSelRedefinitionType.isNull())
- Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef);
- }
-
- if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) {
- QualType Ucontext_tType = GetType(Ucontext_t);
- if (Ucontext_tType.isNull()) {
- Error("ucontext_t type is NULL");
- return;
- }
-
- if (!Context.ucontext_tDecl) {
- if (const TypedefType *Typedef = Ucontext_tType->getAs<TypedefType>())
- Context.setucontext_tDecl(Typedef->getDecl());
- else {
- const TagType *Tag = Ucontext_tType->getAs<TagType>();
- assert(Tag && "Invalid ucontext_t type in AST file");
- Context.setucontext_tDecl(Tag->getDecl());
- }
- }
- }
- }
-
- ReadPragmaDiagnosticMappings(Context.getDiagnostics());
-
- // If there were any CUDA special declarations, deserialize them.
- if (!CUDASpecialDeclRefs.empty()) {
- assert(CUDASpecialDeclRefs.size() == 1 && "More decl refs than expected!");
- Context.setcudaConfigureCallDecl(
- cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));
- }
-
- // Re-export any modules that were imported by a non-module AST file.
- // FIXME: This does not make macro-only imports visible again.
- for (auto &Import : ImportedModules) {
- if (Module *Imported = getSubmodule(Import.ID)) {
- makeModuleVisible(Imported, Module::AllVisible,
- /*ImportLoc=*/Import.ImportLoc);
- if (Import.ImportLoc.isValid())
- PP.makeModuleVisible(Imported, Import.ImportLoc);
- // FIXME: should we tell Sema to make the module visible too?
- }
- }
- ImportedModules.clear();
-}
-
-void ASTReader::finalizeForWriting() {
- // Nothing to do for now.
-}
-
-/// Reads and return the signature record from \p PCH's control block, or
-/// else returns 0.
-static ASTFileSignature readASTFileSignature(StringRef PCH) {
- BitstreamCursor Stream(PCH);
- if (!startsWithASTFileMagic(Stream))
- return ASTFileSignature();
-
- // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
- if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
- return ASTFileSignature();
-
- // Scan for SIGNATURE inside the diagnostic options block.
- ASTReader::RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
- if (Entry.Kind != llvm::BitstreamEntry::Record)
- return ASTFileSignature();
-
- Record.clear();
- StringRef Blob;
- if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob))
- return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
- (uint32_t)Record[3], (uint32_t)Record[4]}}};
- }
-}
-
-/// Retrieve the name of the original source file name
-/// directly from the AST file, without actually loading the AST
-/// file.
-std::string ASTReader::getOriginalSourceFile(
- const std::string &ASTFileName, FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr, DiagnosticsEngine &Diags) {
- // Open the AST file.
- auto Buffer = FileMgr.getBufferForFile(ASTFileName);
- if (!Buffer) {
- Diags.Report(diag::err_fe_unable_to_read_pch_file)
- << ASTFileName << Buffer.getError().message();
- return std::string();
- }
-
- // Initialize the stream
- BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer));
-
- // Sniff for the signature.
- if (!startsWithASTFileMagic(Stream)) {
- Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
- return std::string();
- }
-
- // Scan for the CONTROL_BLOCK_ID block.
- if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) {
- Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
- return std::string();
- }
-
- // Scan for ORIGINAL_FILE inside the control block.
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
- if (Entry.Kind == llvm::BitstreamEntry::EndBlock)
- return std::string();
-
- if (Entry.Kind != llvm::BitstreamEntry::Record) {
- Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
- return std::string();
- }
-
- Record.clear();
- StringRef Blob;
- if (Stream.readRecord(Entry.ID, Record, &Blob) == ORIGINAL_FILE)
- return Blob.str();
- }
-}
-
-namespace {
-
- class SimplePCHValidator : public ASTReaderListener {
- const LangOptions &ExistingLangOpts;
- const TargetOptions &ExistingTargetOpts;
- const PreprocessorOptions &ExistingPPOpts;
- std::string ExistingModuleCachePath;
- FileManager &FileMgr;
-
- public:
- SimplePCHValidator(const LangOptions &ExistingLangOpts,
- const TargetOptions &ExistingTargetOpts,
- const PreprocessorOptions &ExistingPPOpts,
- StringRef ExistingModuleCachePath,
- FileManager &FileMgr)
- : ExistingLangOpts(ExistingLangOpts),
- ExistingTargetOpts(ExistingTargetOpts),
- ExistingPPOpts(ExistingPPOpts),
- ExistingModuleCachePath(ExistingModuleCachePath),
- FileMgr(FileMgr) {}
-
- bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
- bool AllowCompatibleDifferences) override {
- return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr,
- AllowCompatibleDifferences);
- }
-
- bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
- bool AllowCompatibleDifferences) override {
- return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr,
- AllowCompatibleDifferences);
- }
-
- bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- bool Complain) override {
- return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- ExistingModuleCachePath,
- nullptr, ExistingLangOpts);
- }
-
- bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
- std::string &SuggestedPredefines) override {
- return checkPreprocessorOptions(ExistingPPOpts, PPOpts, nullptr, FileMgr,
- SuggestedPredefines, ExistingLangOpts);
- }
- };
-
-} // namespace
-
-bool ASTReader::readASTFileControlBlock(
- StringRef Filename, FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- bool FindModuleFileExtensions,
- ASTReaderListener &Listener, bool ValidateDiagnosticOptions) {
- // Open the AST file.
- // FIXME: This allows use of the VFS; we do not allow use of the
- // VFS when actually loading a module.
- auto Buffer = FileMgr.getBufferForFile(Filename);
- if (!Buffer) {
- return true;
- }
-
- // Initialize the stream
- StringRef Bytes = PCHContainerRdr.ExtractPCH(**Buffer);
- BitstreamCursor Stream(Bytes);
-
- // Sniff for the signature.
- if (!startsWithASTFileMagic(Stream))
- return true;
-
- // Scan for the CONTROL_BLOCK_ID block.
- if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
- return true;
-
- bool NeedsInputFiles = Listener.needsInputFileVisitation();
- bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation();
- bool NeedsImports = Listener.needsImportVisitation();
- BitstreamCursor InputFilesCursor;
-
- RecordData Record;
- std::string ModuleDir;
- bool DoneWithControlBlock = false;
- while (!DoneWithControlBlock) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock: {
- switch (Entry.ID) {
- case OPTIONS_BLOCK_ID: {
- std::string IgnoredSuggestedPredefines;
- if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate,
- /*AllowCompatibleConfigurationMismatch*/ false,
- Listener, IgnoredSuggestedPredefines) != Success)
- return true;
- break;
- }
-
- case INPUT_FILES_BLOCK_ID:
- InputFilesCursor = Stream;
- if (Stream.SkipBlock() ||
- (NeedsInputFiles &&
- ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID)))
- return true;
- break;
-
- default:
- if (Stream.SkipBlock())
- return true;
- break;
- }
-
- continue;
- }
-
- case llvm::BitstreamEntry::EndBlock:
- DoneWithControlBlock = true;
- break;
-
- case llvm::BitstreamEntry::Error:
- return true;
-
- case llvm::BitstreamEntry::Record:
- break;
- }
-
- if (DoneWithControlBlock) break;
-
- Record.clear();
- StringRef Blob;
- unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
- switch ((ControlRecordTypes)RecCode) {
- case METADATA:
- if (Record[0] != VERSION_MAJOR)
- return true;
- if (Listener.ReadFullVersionInformation(Blob))
- return true;
- break;
- case MODULE_NAME:
- Listener.ReadModuleName(Blob);
- break;
- case MODULE_DIRECTORY:
- ModuleDir = Blob;
- break;
- case MODULE_MAP_FILE: {
- unsigned Idx = 0;
- auto Path = ReadString(Record, Idx);
- ResolveImportedPath(Path, ModuleDir);
- Listener.ReadModuleMapFile(Path);
- break;
- }
- case INPUT_FILE_OFFSETS: {
- if (!NeedsInputFiles)
- break;
-
- unsigned NumInputFiles = Record[0];
- unsigned NumUserFiles = Record[1];
- const llvm::support::unaligned_uint64_t *InputFileOffs =
- (const llvm::support::unaligned_uint64_t *)Blob.data();
- for (unsigned I = 0; I != NumInputFiles; ++I) {
- // Go find this input file.
- bool isSystemFile = I >= NumUserFiles;
-
- if (isSystemFile && !NeedsSystemInputFiles)
- break; // the rest are system input files
-
- BitstreamCursor &Cursor = InputFilesCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(InputFileOffs[I]);
-
- unsigned Code = Cursor.ReadCode();
- RecordData Record;
- StringRef Blob;
- bool shouldContinue = false;
- switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
- case INPUT_FILE:
- bool Overridden = static_cast<bool>(Record[3]);
- std::string Filename = Blob;
- ResolveImportedPath(Filename, ModuleDir);
- shouldContinue = Listener.visitInputFile(
- Filename, isSystemFile, Overridden, /*IsExplicitModule*/false);
- break;
- }
- if (!shouldContinue)
- break;
- }
- break;
- }
-
- case IMPORTS: {
- if (!NeedsImports)
- break;
-
- unsigned Idx = 0, N = Record.size();
- while (Idx < N) {
- // Read information about the AST file.
- Idx += 1+1+1+1+5; // Kind, ImportLoc, Size, ModTime, Signature
- std::string ModuleName = ReadString(Record, Idx);
- std::string Filename = ReadString(Record, Idx);
- ResolveImportedPath(Filename, ModuleDir);
- Listener.visitImport(ModuleName, Filename);
- }
- break;
- }
-
- default:
- // No other validation to perform.
- break;
- }
- }
-
- // Look for module file extension blocks, if requested.
- if (FindModuleFileExtensions) {
- BitstreamCursor SavedStream = Stream;
- while (!SkipCursorToBlock(Stream, EXTENSION_BLOCK_ID)) {
- bool DoneWithExtensionBlock = false;
- while (!DoneWithExtensionBlock) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock:
- if (Stream.SkipBlock())
- return true;
-
- continue;
-
- case llvm::BitstreamEntry::EndBlock:
- DoneWithExtensionBlock = true;
- continue;
-
- case llvm::BitstreamEntry::Error:
- return true;
-
- case llvm::BitstreamEntry::Record:
- break;
- }
-
- Record.clear();
- StringRef Blob;
- unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
- switch (RecCode) {
- case EXTENSION_METADATA: {
- ModuleFileExtensionMetadata Metadata;
- if (parseModuleFileExtensionMetadata(Record, Blob, Metadata))
- return true;
-
- Listener.readModuleFileExtension(Metadata);
- break;
- }
- }
- }
- }
- Stream = SavedStream;
- }
-
- // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
- if (readUnhashedControlBlockImpl(
- nullptr, Bytes, ARR_ConfigurationMismatch | ARR_OutOfDate,
- /*AllowCompatibleConfigurationMismatch*/ false, &Listener,
- ValidateDiagnosticOptions) != Success)
- return true;
-
- return false;
-}
-
-bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- const LangOptions &LangOpts,
- const TargetOptions &TargetOpts,
- const PreprocessorOptions &PPOpts,
- StringRef ExistingModuleCachePath) {
- SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
- ExistingModuleCachePath, FileMgr);
- return !readASTFileControlBlock(Filename, FileMgr, PCHContainerRdr,
- /*FindModuleFileExtensions=*/false,
- validator,
- /*ValidateDiagnosticOptions=*/true);
-}
-
-ASTReader::ASTReadResult
-ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
- // Enter the submodule block.
- if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
- Error("malformed submodule block record in AST file");
- return Failure;
- }
-
- ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
- bool First = true;
- Module *CurrentModule = nullptr;
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock: // Handled for us already.
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return Failure;
- case llvm::BitstreamEntry::EndBlock:
- return Success;
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read a record.
- StringRef Blob;
- Record.clear();
- auto Kind = F.Stream.readRecord(Entry.ID, Record, &Blob);
-
- if ((Kind == SUBMODULE_METADATA) != First) {
- Error("submodule metadata record should be at beginning of block");
- return Failure;
- }
- First = false;
-
- // Submodule information is only valid if we have a current module.
- // FIXME: Should we error on these cases?
- if (!CurrentModule && Kind != SUBMODULE_METADATA &&
- Kind != SUBMODULE_DEFINITION)
- continue;
-
- switch (Kind) {
- default: // Default behavior: ignore.
- break;
-
- case SUBMODULE_DEFINITION: {
- if (Record.size() < 12) {
- Error("malformed module definition");
- return Failure;
- }
-
- StringRef Name = Blob;
- unsigned Idx = 0;
- SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[Idx++]);
- SubmoduleID Parent = getGlobalSubmoduleID(F, Record[Idx++]);
- Module::ModuleKind Kind = (Module::ModuleKind)Record[Idx++];
- bool IsFramework = Record[Idx++];
- bool IsExplicit = Record[Idx++];
- bool IsSystem = Record[Idx++];
- bool IsExternC = Record[Idx++];
- bool InferSubmodules = Record[Idx++];
- bool InferExplicitSubmodules = Record[Idx++];
- bool InferExportWildcard = Record[Idx++];
- bool ConfigMacrosExhaustive = Record[Idx++];
- bool ModuleMapIsPrivate = Record[Idx++];
-
- Module *ParentModule = nullptr;
- if (Parent)
- ParentModule = getSubmodule(Parent);
-
- // Retrieve this (sub)module from the module map, creating it if
- // necessary.
- CurrentModule =
- ModMap.findOrCreateModule(Name, ParentModule, IsFramework, IsExplicit)
- .first;
-
- // FIXME: set the definition loc for CurrentModule, or call
- // ModMap.setInferredModuleAllowedBy()
-
- SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
- if (GlobalIndex >= SubmodulesLoaded.size() ||
- SubmodulesLoaded[GlobalIndex]) {
- Error("too many submodules");
- return Failure;
- }
-
- if (!ParentModule) {
- if (const FileEntry *CurFile = CurrentModule->getASTFile()) {
- // Don't emit module relocation error if we have -fno-validate-pch
- if (!PP.getPreprocessorOpts().DisablePCHValidation &&
- CurFile != F.File) {
- if (!Diags.isDiagnosticInFlight()) {
- Diag(diag::err_module_file_conflict)
- << CurrentModule->getTopLevelModuleName()
- << CurFile->getName()
- << F.File->getName();
- }
- return Failure;
- }
- }
-
- CurrentModule->setASTFile(F.File);
- CurrentModule->PresumedModuleMapFile = F.ModuleMapPath;
- }
-
- CurrentModule->Kind = Kind;
- CurrentModule->Signature = F.Signature;
- CurrentModule->IsFromModuleFile = true;
- CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
- CurrentModule->IsExternC = IsExternC;
- CurrentModule->InferSubmodules = InferSubmodules;
- CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
- CurrentModule->InferExportWildcard = InferExportWildcard;
- CurrentModule->ConfigMacrosExhaustive = ConfigMacrosExhaustive;
- CurrentModule->ModuleMapIsPrivate = ModuleMapIsPrivate;
- if (DeserializationListener)
- DeserializationListener->ModuleRead(GlobalID, CurrentModule);
-
- SubmodulesLoaded[GlobalIndex] = CurrentModule;
-
- // Clear out data that will be replaced by what is in the module file.
- CurrentModule->LinkLibraries.clear();
- CurrentModule->ConfigMacros.clear();
- CurrentModule->UnresolvedConflicts.clear();
- CurrentModule->Conflicts.clear();
-
- // The module is available unless it's missing a requirement; relevant
- // requirements will be (re-)added by SUBMODULE_REQUIRES records.
- // Missing headers that were present when the module was built do not
- // make it unavailable -- if we got this far, this must be an explicitly
- // imported module file.
- CurrentModule->Requirements.clear();
- CurrentModule->MissingHeaders.clear();
- CurrentModule->IsMissingRequirement =
- ParentModule && ParentModule->IsMissingRequirement;
- CurrentModule->IsAvailable = !CurrentModule->IsMissingRequirement;
- break;
- }
-
- case SUBMODULE_UMBRELLA_HEADER: {
- std::string Filename = Blob;
- ResolveImportedPath(F, Filename);
- if (auto *Umbrella = PP.getFileManager().getFile(Filename)) {
- if (!CurrentModule->getUmbrellaHeader())
- ModMap.setUmbrellaHeader(CurrentModule, Umbrella, Blob);
- else if (CurrentModule->getUmbrellaHeader().Entry != Umbrella) {
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Error("mismatched umbrella headers in submodule");
- return OutOfDate;
- }
- }
- break;
- }
-
- case SUBMODULE_HEADER:
- case SUBMODULE_EXCLUDED_HEADER:
- case SUBMODULE_PRIVATE_HEADER:
- // We lazily associate headers with their modules via the HeaderInfo table.
- // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead
- // of complete filenames or remove it entirely.
- break;
-
- case SUBMODULE_TEXTUAL_HEADER:
- case SUBMODULE_PRIVATE_TEXTUAL_HEADER:
- // FIXME: Textual headers are not marked in the HeaderInfo table. Load
- // them here.
- break;
-
- case SUBMODULE_TOPHEADER:
- CurrentModule->addTopHeaderFilename(Blob);
- break;
-
- case SUBMODULE_UMBRELLA_DIR: {
- std::string Dirname = Blob;
- ResolveImportedPath(F, Dirname);
- if (auto *Umbrella = PP.getFileManager().getDirectory(Dirname)) {
- if (!CurrentModule->getUmbrellaDir())
- ModMap.setUmbrellaDir(CurrentModule, Umbrella, Blob);
- else if (CurrentModule->getUmbrellaDir().Entry != Umbrella) {
- if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
- Error("mismatched umbrella directories in submodule");
- return OutOfDate;
- }
- }
- break;
- }
-
- case SUBMODULE_METADATA: {
- F.BaseSubmoduleID = getTotalNumSubmodules();
- F.LocalNumSubmodules = Record[0];
- unsigned LocalBaseSubmoduleID = Record[1];
- if (F.LocalNumSubmodules > 0) {
- // Introduce the global -> local mapping for submodules within this
- // module.
- GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F));
-
- // Introduce the local -> global mapping for submodules within this
- // module.
- F.SubmoduleRemap.insertOrReplace(
- std::make_pair(LocalBaseSubmoduleID,
- F.BaseSubmoduleID - LocalBaseSubmoduleID));
-
- SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules);
- }
- break;
- }
-
- case SUBMODULE_IMPORTS:
- for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {
- UnresolvedModuleRef Unresolved;
- Unresolved.File = &F;
- Unresolved.Mod = CurrentModule;
- Unresolved.ID = Record[Idx];
- Unresolved.Kind = UnresolvedModuleRef::Import;
- Unresolved.IsWildcard = false;
- UnresolvedModuleRefs.push_back(Unresolved);
- }
- break;
-
- case SUBMODULE_EXPORTS:
- for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
- UnresolvedModuleRef Unresolved;
- Unresolved.File = &F;
- Unresolved.Mod = CurrentModule;
- Unresolved.ID = Record[Idx];
- Unresolved.Kind = UnresolvedModuleRef::Export;
- Unresolved.IsWildcard = Record[Idx + 1];
- UnresolvedModuleRefs.push_back(Unresolved);
- }
-
- // Once we've loaded the set of exports, there's no reason to keep
- // the parsed, unresolved exports around.
- CurrentModule->UnresolvedExports.clear();
- break;
-
- case SUBMODULE_REQUIRES:
- CurrentModule->addRequirement(Blob, Record[0], PP.getLangOpts(),
- PP.getTargetInfo());
- break;
-
- case SUBMODULE_LINK_LIBRARY:
- ModMap.resolveLinkAsDependencies(CurrentModule);
- CurrentModule->LinkLibraries.push_back(
- Module::LinkLibrary(Blob, Record[0]));
- break;
-
- case SUBMODULE_CONFIG_MACRO:
- CurrentModule->ConfigMacros.push_back(Blob.str());
- break;
-
- case SUBMODULE_CONFLICT: {
- UnresolvedModuleRef Unresolved;
- Unresolved.File = &F;
- Unresolved.Mod = CurrentModule;
- Unresolved.ID = Record[0];
- Unresolved.Kind = UnresolvedModuleRef::Conflict;
- Unresolved.IsWildcard = false;
- Unresolved.String = Blob;
- UnresolvedModuleRefs.push_back(Unresolved);
- break;
- }
-
- case SUBMODULE_INITIALIZERS: {
- if (!ContextObj)
- break;
- SmallVector<uint32_t, 16> Inits;
- for (auto &ID : Record)
- Inits.push_back(getGlobalDeclID(F, ID));
- ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
- break;
- }
-
- case SUBMODULE_EXPORT_AS:
- CurrentModule->ExportAsModule = Blob.str();
- ModMap.addLinkAsDependency(CurrentModule);
- break;
- }
- }
-}
-
-/// Parse the record that corresponds to a LangOptions data
-/// structure.
-///
-/// This routine parses the language options from the AST file and then gives
-/// them to the AST listener if one is set.
-///
-/// \returns true if the listener deems the file unacceptable, false otherwise.
-bool ASTReader::ParseLanguageOptions(const RecordData &Record,
- bool Complain,
- ASTReaderListener &Listener,
- bool AllowCompatibleDifferences) {
- LangOptions LangOpts;
- unsigned Idx = 0;
-#define LANGOPT(Name, Bits, Default, Description) \
- LangOpts.Name = Record[Idx++];
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));
-#include "clang/Basic/LangOptions.def"
-#define SANITIZER(NAME, ID) \
- LangOpts.Sanitize.set(SanitizerKind::ID, Record[Idx++]);
-#include "clang/Basic/Sanitizers.def"
-
- for (unsigned N = Record[Idx++]; N; --N)
- LangOpts.ModuleFeatures.push_back(ReadString(Record, Idx));
-
- ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];
- VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx);
- LangOpts.ObjCRuntime = ObjCRuntime(runtimeKind, runtimeVersion);
-
- LangOpts.CurrentModule = ReadString(Record, Idx);
-
- // Comment options.
- for (unsigned N = Record[Idx++]; N; --N) {
- LangOpts.CommentOpts.BlockCommandNames.push_back(
- ReadString(Record, Idx));
- }
- LangOpts.CommentOpts.ParseAllComments = Record[Idx++];
-
- // OpenMP offloading options.
- for (unsigned N = Record[Idx++]; N; --N) {
- LangOpts.OMPTargetTriples.push_back(llvm::Triple(ReadString(Record, Idx)));
- }
-
- LangOpts.OMPHostIRFile = ReadString(Record, Idx);
-
- return Listener.ReadLanguageOptions(LangOpts, Complain,
- AllowCompatibleDifferences);
-}
-
-bool ASTReader::ParseTargetOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener,
- bool AllowCompatibleDifferences) {
- unsigned Idx = 0;
- TargetOptions TargetOpts;
- TargetOpts.Triple = ReadString(Record, Idx);
- TargetOpts.CPU = ReadString(Record, Idx);
- TargetOpts.ABI = ReadString(Record, Idx);
- for (unsigned N = Record[Idx++]; N; --N) {
- TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
- }
- for (unsigned N = Record[Idx++]; N; --N) {
- TargetOpts.Features.push_back(ReadString(Record, Idx));
- }
-
- return Listener.ReadTargetOptions(TargetOpts, Complain,
- AllowCompatibleDifferences);
-}
-
-bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener) {
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
- unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
- DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
-#include "clang/Basic/DiagnosticOptions.def"
-
- for (unsigned N = Record[Idx++]; N; --N)
- DiagOpts->Warnings.push_back(ReadString(Record, Idx));
- for (unsigned N = Record[Idx++]; N; --N)
- DiagOpts->Remarks.push_back(ReadString(Record, Idx));
-
- return Listener.ReadDiagnosticOptions(DiagOpts, Complain);
-}
-
-bool ASTReader::ParseFileSystemOptions(const RecordData &Record, bool Complain,
- ASTReaderListener &Listener) {
- FileSystemOptions FSOpts;
- unsigned Idx = 0;
- FSOpts.WorkingDir = ReadString(Record, Idx);
- return Listener.ReadFileSystemOptions(FSOpts, Complain);
-}
-
-bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
- bool Complain,
- ASTReaderListener &Listener) {
- HeaderSearchOptions HSOpts;
- unsigned Idx = 0;
- HSOpts.Sysroot = ReadString(Record, Idx);
-
- // Include entries.
- for (unsigned N = Record[Idx++]; N; --N) {
- std::string Path = ReadString(Record, Idx);
- frontend::IncludeDirGroup Group
- = static_cast<frontend::IncludeDirGroup>(Record[Idx++]);
- bool IsFramework = Record[Idx++];
- bool IgnoreSysRoot = Record[Idx++];
- HSOpts.UserEntries.emplace_back(std::move(Path), Group, IsFramework,
- IgnoreSysRoot);
- }
-
- // System header prefixes.
- for (unsigned N = Record[Idx++]; N; --N) {
- std::string Prefix = ReadString(Record, Idx);
- bool IsSystemHeader = Record[Idx++];
- HSOpts.SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader);
- }
-
- HSOpts.ResourceDir = ReadString(Record, Idx);
- HSOpts.ModuleCachePath = ReadString(Record, Idx);
- HSOpts.ModuleUserBuildPath = ReadString(Record, Idx);
- HSOpts.DisableModuleHash = Record[Idx++];
- HSOpts.ImplicitModuleMaps = Record[Idx++];
- HSOpts.ModuleMapFileHomeIsCwd = Record[Idx++];
- HSOpts.UseBuiltinIncludes = Record[Idx++];
- HSOpts.UseStandardSystemIncludes = Record[Idx++];
- HSOpts.UseStandardCXXIncludes = Record[Idx++];
- HSOpts.UseLibcxx = Record[Idx++];
- std::string SpecificModuleCachePath = ReadString(Record, Idx);
-
- return Listener.ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
- Complain);
-}
-
-bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
- bool Complain,
- ASTReaderListener &Listener,
- std::string &SuggestedPredefines) {
- PreprocessorOptions PPOpts;
- unsigned Idx = 0;
-
- // Macro definitions/undefs
- for (unsigned N = Record[Idx++]; N; --N) {
- std::string Macro = ReadString(Record, Idx);
- bool IsUndef = Record[Idx++];
- PPOpts.Macros.push_back(std::make_pair(Macro, IsUndef));
- }
-
- // Includes
- for (unsigned N = Record[Idx++]; N; --N) {
- PPOpts.Includes.push_back(ReadString(Record, Idx));
- }
-
- // Macro Includes
- for (unsigned N = Record[Idx++]; N; --N) {
- PPOpts.MacroIncludes.push_back(ReadString(Record, Idx));
- }
-
- PPOpts.UsePredefines = Record[Idx++];
- PPOpts.DetailedRecord = Record[Idx++];
- PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);
- PPOpts.ObjCXXARCStandardLibrary =
- static_cast<ObjCXXARCStandardLibraryKind>(Record[Idx++]);
- SuggestedPredefines.clear();
- return Listener.ReadPreprocessorOptions(PPOpts, Complain,
- SuggestedPredefines);
-}
-
-std::pair<ModuleFile *, unsigned>
-ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {
- GlobalPreprocessedEntityMapType::iterator
- I = GlobalPreprocessedEntityMap.find(GlobalIndex);
- assert(I != GlobalPreprocessedEntityMap.end() &&
- "Corrupted global preprocessed entity map");
- ModuleFile *M = I->second;
- unsigned LocalIndex = GlobalIndex - M->BasePreprocessedEntityID;
- return std::make_pair(M, LocalIndex);
-}
-
-llvm::iterator_range<PreprocessingRecord::iterator>
-ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {
- if (PreprocessingRecord *PPRec = PP.getPreprocessingRecord())
- return PPRec->getIteratorsForLoadedRange(Mod.BasePreprocessedEntityID,
- Mod.NumPreprocessedEntities);
-
- return llvm::make_range(PreprocessingRecord::iterator(),
- PreprocessingRecord::iterator());
-}
-
-llvm::iterator_range<ASTReader::ModuleDeclIterator>
-ASTReader::getModuleFileLevelDecls(ModuleFile &Mod) {
- return llvm::make_range(
- ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls),
- ModuleDeclIterator(this, &Mod,
- Mod.FileSortedDecls + Mod.NumFileSortedDecls));
-}
-
-SourceRange ASTReader::ReadSkippedRange(unsigned GlobalIndex) {
- auto I = GlobalSkippedRangeMap.find(GlobalIndex);
- assert(I != GlobalSkippedRangeMap.end() &&
- "Corrupted global skipped range map");
- ModuleFile *M = I->second;
- unsigned LocalIndex = GlobalIndex - M->BasePreprocessedSkippedRangeID;
- assert(LocalIndex < M->NumPreprocessedSkippedRanges);
- PPSkippedRange RawRange = M->PreprocessedSkippedRangeOffsets[LocalIndex];
- SourceRange Range(TranslateSourceLocation(*M, RawRange.getBegin()),
- TranslateSourceLocation(*M, RawRange.getEnd()));
- assert(Range.isValid());
- return Range;
-}
-
-PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
- PreprocessedEntityID PPID = Index+1;
- std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
- ModuleFile &M = *PPInfo.first;
- unsigned LocalIndex = PPInfo.second;
- const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
-
- if (!PP.getPreprocessingRecord()) {
- Error("no preprocessing record");
- return nullptr;
- }
-
- SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
- M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);
-
- llvm::BitstreamEntry Entry =
- M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
- if (Entry.Kind != llvm::BitstreamEntry::Record)
- return nullptr;
-
- // Read the record.
- SourceRange Range(TranslateSourceLocation(M, PPOffs.getBegin()),
- TranslateSourceLocation(M, PPOffs.getEnd()));
- PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
- StringRef Blob;
- RecordData Record;
- PreprocessorDetailRecordTypes RecType =
- (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.readRecord(
- Entry.ID, Record, &Blob);
- switch (RecType) {
- case PPD_MACRO_EXPANSION: {
- bool isBuiltin = Record[0];
- IdentifierInfo *Name = nullptr;
- MacroDefinitionRecord *Def = nullptr;
- if (isBuiltin)
- Name = getLocalIdentifier(M, Record[1]);
- else {
- PreprocessedEntityID GlobalID =
- getGlobalPreprocessedEntityID(M, Record[1]);
- Def = cast<MacroDefinitionRecord>(
- PPRec.getLoadedPreprocessedEntity(GlobalID - 1));
- }
-
- MacroExpansion *ME;
- if (isBuiltin)
- ME = new (PPRec) MacroExpansion(Name, Range);
- else
- ME = new (PPRec) MacroExpansion(Def, Range);
-
- return ME;
- }
-
- case PPD_MACRO_DEFINITION: {
- // Decode the identifier info and then check again; if the macro is
- // still defined and associated with the identifier,
- IdentifierInfo *II = getLocalIdentifier(M, Record[0]);
- MacroDefinitionRecord *MD = new (PPRec) MacroDefinitionRecord(II, Range);
-
- if (DeserializationListener)
- DeserializationListener->MacroDefinitionRead(PPID, MD);
-
- return MD;
- }
-
- case PPD_INCLUSION_DIRECTIVE: {
- const char *FullFileNameStart = Blob.data() + Record[0];
- StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
- const FileEntry *File = nullptr;
- if (!FullFileName.empty())
- File = PP.getFileManager().getFile(FullFileName);
-
- // FIXME: Stable encoding
- InclusionDirective::InclusionKind Kind
- = static_cast<InclusionDirective::InclusionKind>(Record[2]);
- InclusionDirective *ID
- = new (PPRec) InclusionDirective(PPRec, Kind,
- StringRef(Blob.data(), Record[0]),
- Record[1], Record[3],
- File,
- Range);
- return ID;
- }
- }
-
- llvm_unreachable("Invalid PreprocessorDetailRecordTypes");
-}
-
-/// 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.
-PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
- GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
- ++SLocMapI;
- for (GlobalSLocOffsetMapType::const_iterator
- EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {
- ModuleFile &M = *SLocMapI->second;
- if (M.NumPreprocessedEntities)
- return M.BasePreprocessedEntityID;
- }
-
- return getTotalNumPreprocessedEntities();
-}
-
-namespace {
-
-struct PPEntityComp {
- const ASTReader &Reader;
- ModuleFile &M;
-
- PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) {}
-
- bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const {
- SourceLocation LHS = getLoc(L);
- SourceLocation RHS = getLoc(R);
- return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
- }
-
- bool operator()(const PPEntityOffset &L, SourceLocation RHS) const {
- SourceLocation LHS = getLoc(L);
- return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
- }
-
- bool operator()(SourceLocation LHS, const PPEntityOffset &R) const {
- SourceLocation RHS = getLoc(R);
- return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
- }
-
- SourceLocation getLoc(const PPEntityOffset &PPE) const {
- return Reader.TranslateSourceLocation(M, PPE.getBegin());
- }
-};
-
-} // namespace
-
-PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
- bool EndsAfter) const {
- if (SourceMgr.isLocalSourceLocation(Loc))
- return getTotalNumPreprocessedEntities();
-
- GlobalSLocOffsetMapType::const_iterator SLocMapI = GlobalSLocOffsetMap.find(
- SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
- assert(SLocMapI != GlobalSLocOffsetMap.end() &&
- "Corrupted global sloc offset map");
-
- if (SLocMapI->second->NumPreprocessedEntities == 0)
- return findNextPreprocessedEntity(SLocMapI);
-
- ModuleFile &M = *SLocMapI->second;
-
- using pp_iterator = const PPEntityOffset *;
-
- pp_iterator pp_begin = M.PreprocessedEntityOffsets;
- pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
-
- size_t Count = M.NumPreprocessedEntities;
- size_t Half;
- pp_iterator First = pp_begin;
- pp_iterator PPI;
-
- if (EndsAfter) {
- PPI = std::upper_bound(pp_begin, pp_end, Loc,
- PPEntityComp(*this, M));
- } else {
- // Do a binary search manually instead of using std::lower_bound because
- // The end locations of entities may be unordered (when a macro expansion
- // is inside another macro argument), but for this case it is not important
- // whether we get the first macro expansion or its containing macro.
- while (Count > 0) {
- Half = Count / 2;
- PPI = First;
- std::advance(PPI, Half);
- if (SourceMgr.isBeforeInTranslationUnit(
- TranslateSourceLocation(M, PPI->getEnd()), Loc)) {
- First = PPI;
- ++First;
- Count = Count - Half - 1;
- } else
- Count = Half;
- }
- }
-
- if (PPI == pp_end)
- return findNextPreprocessedEntity(SLocMapI);
-
- return M.BasePreprocessedEntityID + (PPI - pp_begin);
-}
-
-/// Returns a pair of [Begin, End) indices of preallocated
-/// preprocessed entities that \arg Range encompasses.
-std::pair<unsigned, unsigned>
- ASTReader::findPreprocessedEntitiesInRange(SourceRange Range) {
- if (Range.isInvalid())
- return std::make_pair(0,0);
- assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
-
- PreprocessedEntityID BeginID =
- findPreprocessedEntity(Range.getBegin(), false);
- PreprocessedEntityID EndID = findPreprocessedEntity(Range.getEnd(), true);
- return std::make_pair(BeginID, EndID);
-}
-
-/// Optionally returns true or false if the preallocated preprocessed
-/// entity with index \arg Index came from file \arg FID.
-Optional<bool> ASTReader::isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) {
- if (FID.isInvalid())
- return false;
-
- std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
- ModuleFile &M = *PPInfo.first;
- unsigned LocalIndex = PPInfo.second;
- const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
-
- SourceLocation Loc = TranslateSourceLocation(M, PPOffs.getBegin());
- if (Loc.isInvalid())
- return false;
-
- if (SourceMgr.isInFileID(SourceMgr.getFileLoc(Loc), FID))
- return true;
- else
- return false;
-}
-
-namespace {
-
- /// Visitor used to search for information about a header file.
- class HeaderFileInfoVisitor {
- const FileEntry *FE;
- Optional<HeaderFileInfo> HFI;
-
- public:
- explicit HeaderFileInfoVisitor(const FileEntry *FE) : FE(FE) {}
-
- bool operator()(ModuleFile &M) {
- HeaderFileInfoLookupTable *Table
- = static_cast<HeaderFileInfoLookupTable *>(M.HeaderFileInfoTable);
- if (!Table)
- return false;
-
- // Look in the on-disk hash table for an entry for this file name.
- HeaderFileInfoLookupTable::iterator Pos = Table->find(FE);
- if (Pos == Table->end())
- return false;
-
- HFI = *Pos;
- return true;
- }
-
- Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; }
- };
-
-} // namespace
-
-HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) {
- HeaderFileInfoVisitor Visitor(FE);
- ModuleMgr.visit(Visitor);
- if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo())
- return *HFI;
-
- return HeaderFileInfo();
-}
-
-void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
- using DiagState = DiagnosticsEngine::DiagState;
- SmallVector<DiagState *, 32> DiagStates;
-
- for (ModuleFile &F : ModuleMgr) {
- unsigned Idx = 0;
- auto &Record = F.PragmaDiagMappings;
- if (Record.empty())
- continue;
-
- DiagStates.clear();
-
- auto ReadDiagState =
- [&](const DiagState &BasedOn, SourceLocation Loc,
- bool IncludeNonPragmaStates) -> DiagnosticsEngine::DiagState * {
- unsigned BackrefID = Record[Idx++];
- if (BackrefID != 0)
- return DiagStates[BackrefID - 1];
-
- // A new DiagState was created here.
- Diag.DiagStates.push_back(BasedOn);
- DiagState *NewState = &Diag.DiagStates.back();
- DiagStates.push_back(NewState);
- unsigned Size = Record[Idx++];
- assert(Idx + Size * 2 <= Record.size() &&
- "Invalid data, not enough diag/map pairs");
- while (Size--) {
- unsigned DiagID = Record[Idx++];
- DiagnosticMapping NewMapping =
- DiagnosticMapping::deserialize(Record[Idx++]);
- if (!NewMapping.isPragma() && !IncludeNonPragmaStates)
- continue;
-
- DiagnosticMapping &Mapping = NewState->getOrAddMapping(DiagID);
-
- // If this mapping was specified as a warning but the severity was
- // upgraded due to diagnostic settings, simulate the current diagnostic
- // settings (and use a warning).
- if (NewMapping.wasUpgradedFromWarning() && !Mapping.isErrorOrFatal()) {
- NewMapping.setSeverity(diag::Severity::Warning);
- NewMapping.setUpgradedFromWarning(false);
- }
-
- Mapping = NewMapping;
- }
- return NewState;
- };
-
- // Read the first state.
- DiagState *FirstState;
- if (F.Kind == MK_ImplicitModule) {
- // Implicitly-built modules are reused with different diagnostic
- // settings. Use the initial diagnostic state from Diag to simulate this
- // compilation's diagnostic settings.
- FirstState = Diag.DiagStatesByLoc.FirstDiagState;
- DiagStates.push_back(FirstState);
-
- // Skip the initial diagnostic state from the serialized module.
- assert(Record[1] == 0 &&
- "Invalid data, unexpected backref in initial state");
- Idx = 3 + Record[2] * 2;
- assert(Idx < Record.size() &&
- "Invalid data, not enough state change pairs in initial state");
- } else if (F.isModule()) {
- // For an explicit module, preserve the flags from the module build
- // command line (-w, -Weverything, -Werror, ...) along with any explicit
- // -Wblah flags.
- unsigned Flags = Record[Idx++];
- DiagState Initial;
- Initial.SuppressSystemWarnings = Flags & 1; Flags >>= 1;
- Initial.ErrorsAsFatal = Flags & 1; Flags >>= 1;
- Initial.WarningsAsErrors = Flags & 1; Flags >>= 1;
- Initial.EnableAllWarnings = Flags & 1; Flags >>= 1;
- Initial.IgnoreAllWarnings = Flags & 1; Flags >>= 1;
- Initial.ExtBehavior = (diag::Severity)Flags;
- FirstState = ReadDiagState(Initial, SourceLocation(), true);
-
- assert(F.OriginalSourceFileID.isValid());
-
- // Set up the root buffer of the module to start with the initial
- // diagnostic state of the module itself, to cover files that contain no
- // explicit transitions (for which we did not serialize anything).
- Diag.DiagStatesByLoc.Files[F.OriginalSourceFileID]
- .StateTransitions.push_back({FirstState, 0});
- } else {
- // For prefix ASTs, start with whatever the user configured on the
- // command line.
- Idx++; // Skip flags.
- FirstState = ReadDiagState(*Diag.DiagStatesByLoc.CurDiagState,
- SourceLocation(), false);
- }
-
- // Read the state transitions.
- unsigned NumLocations = Record[Idx++];
- while (NumLocations--) {
- assert(Idx < Record.size() &&
- "Invalid data, missing pragma diagnostic states");
- SourceLocation Loc = ReadSourceLocation(F, Record[Idx++]);
- auto IDAndOffset = SourceMgr.getDecomposedLoc(Loc);
- assert(IDAndOffset.first.isValid() && "invalid FileID for transition");
- assert(IDAndOffset.second == 0 && "not a start location for a FileID");
- unsigned Transitions = Record[Idx++];
-
- // Note that we don't need to set up Parent/ParentOffset here, because
- // we won't be changing the diagnostic state within imported FileIDs
- // (other than perhaps appending to the main source file, which has no
- // parent).
- auto &F = Diag.DiagStatesByLoc.Files[IDAndOffset.first];
- F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
- for (unsigned I = 0; I != Transitions; ++I) {
- unsigned Offset = Record[Idx++];
- auto *State =
- ReadDiagState(*FirstState, Loc.getLocWithOffset(Offset), false);
- F.StateTransitions.push_back({State, Offset});
- }
- }
-
- // Read the final state.
- assert(Idx < Record.size() &&
- "Invalid data, missing final pragma diagnostic state");
- SourceLocation CurStateLoc =
- ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
- auto *CurState = ReadDiagState(*FirstState, CurStateLoc, false);
-
- if (!F.isModule()) {
- Diag.DiagStatesByLoc.CurDiagState = CurState;
- Diag.DiagStatesByLoc.CurDiagStateLoc = CurStateLoc;
-
- // Preserve the property that the imaginary root file describes the
- // current state.
- FileID NullFile;
- auto &T = Diag.DiagStatesByLoc.Files[NullFile].StateTransitions;
- if (T.empty())
- T.push_back({CurState, 0});
- else
- T[0].State = CurState;
- }
-
- // Don't try to read these mappings again.
- Record.clear();
- }
-}
-
-/// Get the correct cursor and offset for loading a type.
-ASTReader::RecordLocation ASTReader::TypeCursorForIndex(unsigned Index) {
- GlobalTypeMapType::iterator I = GlobalTypeMap.find(Index);
- assert(I != GlobalTypeMap.end() && "Corrupted global type map");
- ModuleFile *M = I->second;
- return RecordLocation(M, M->TypeOffsets[Index - M->BaseTypeIndex]);
-}
-
-/// Read and return the type with the given index..
-///
-/// The index is the type ID, shifted and minus the number of predefs. This
-/// routine actually reads the record corresponding to the type at the given
-/// location. It is a helper routine for GetType, which deals with reading type
-/// IDs.
-QualType ASTReader::readTypeRecord(unsigned Index) {
- assert(ContextObj && "reading type with no AST context");
- ASTContext &Context = *ContextObj;
- RecordLocation Loc = TypeCursorForIndex(Index);
- BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
-
- // Keep track of where we are in the stream, then jump back there
- // after reading this type.
- SavedStreamPosition SavedPosition(DeclsCursor);
-
- ReadingKindTracker ReadingKind(Read_Type, *this);
-
- // Note that we are loading a type record.
- Deserializing AType(this);
-
- unsigned Idx = 0;
- DeclsCursor.JumpToBit(Loc.Offset);
- RecordData Record;
- unsigned Code = DeclsCursor.ReadCode();
- switch ((TypeCode)DeclsCursor.readRecord(Code, Record)) {
- case TYPE_EXT_QUAL: {
- if (Record.size() != 2) {
- Error("Incorrect encoding of extended qualifier type");
- return QualType();
- }
- QualType Base = readType(*Loc.F, Record, Idx);
- Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[Idx++]);
- return Context.getQualifiedType(Base, Quals);
- }
-
- case TYPE_COMPLEX: {
- if (Record.size() != 1) {
- Error("Incorrect encoding of complex type");
- return QualType();
- }
- QualType ElemType = readType(*Loc.F, Record, Idx);
- return Context.getComplexType(ElemType);
- }
-
- case TYPE_POINTER: {
- if (Record.size() != 1) {
- Error("Incorrect encoding of pointer type");
- return QualType();
- }
- QualType PointeeType = readType(*Loc.F, Record, Idx);
- return Context.getPointerType(PointeeType);
- }
-
- case TYPE_DECAYED: {
- if (Record.size() != 1) {
- Error("Incorrect encoding of decayed type");
- return QualType();
- }
- QualType OriginalType = readType(*Loc.F, Record, Idx);
- QualType DT = Context.getAdjustedParameterType(OriginalType);
- if (!isa<DecayedType>(DT))
- Error("Decayed type does not decay");
- return DT;
- }
-
- case TYPE_ADJUSTED: {
- if (Record.size() != 2) {
- Error("Incorrect encoding of adjusted type");
- return QualType();
- }
- QualType OriginalTy = readType(*Loc.F, Record, Idx);
- QualType AdjustedTy = readType(*Loc.F, Record, Idx);
- return Context.getAdjustedType(OriginalTy, AdjustedTy);
- }
-
- case TYPE_BLOCK_POINTER: {
- if (Record.size() != 1) {
- Error("Incorrect encoding of block pointer type");
- return QualType();
- }
- QualType PointeeType = readType(*Loc.F, Record, Idx);
- return Context.getBlockPointerType(PointeeType);
- }
-
- case TYPE_LVALUE_REFERENCE: {
- if (Record.size() != 2) {
- Error("Incorrect encoding of lvalue reference type");
- return QualType();
- }
- QualType PointeeType = readType(*Loc.F, Record, Idx);
- return Context.getLValueReferenceType(PointeeType, Record[1]);
- }
-
- case TYPE_RVALUE_REFERENCE: {
- if (Record.size() != 1) {
- Error("Incorrect encoding of rvalue reference type");
- return QualType();
- }
- QualType PointeeType = readType(*Loc.F, Record, Idx);
- return Context.getRValueReferenceType(PointeeType);
- }
-
- case TYPE_MEMBER_POINTER: {
- if (Record.size() != 2) {
- Error("Incorrect encoding of member pointer type");
- return QualType();
- }
- QualType PointeeType = readType(*Loc.F, Record, Idx);
- QualType ClassType = readType(*Loc.F, Record, Idx);
- if (PointeeType.isNull() || ClassType.isNull())
- return QualType();
-
- return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
- }
-
- case TYPE_CONSTANT_ARRAY: {
- QualType ElementType = readType(*Loc.F, Record, Idx);
- ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
- unsigned IndexTypeQuals = Record[2];
- unsigned Idx = 3;
- llvm::APInt Size = ReadAPInt(Record, Idx);
- return Context.getConstantArrayType(ElementType, Size,
- ASM, IndexTypeQuals);
- }
-
- case TYPE_INCOMPLETE_ARRAY: {
- QualType ElementType = readType(*Loc.F, Record, Idx);
- ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
- unsigned IndexTypeQuals = Record[2];
- return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
- }
-
- case TYPE_VARIABLE_ARRAY: {
- QualType ElementType = readType(*Loc.F, Record, Idx);
- ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
- unsigned IndexTypeQuals = Record[2];
- SourceLocation LBLoc = ReadSourceLocation(*Loc.F, Record[3]);
- SourceLocation RBLoc = ReadSourceLocation(*Loc.F, Record[4]);
- return Context.getVariableArrayType(ElementType, ReadExpr(*Loc.F),
- ASM, IndexTypeQuals,
- SourceRange(LBLoc, RBLoc));
- }
-
- case TYPE_VECTOR: {
- if (Record.size() != 3) {
- Error("incorrect encoding of vector type in AST file");
- return QualType();
- }
-
- QualType ElementType = readType(*Loc.F, Record, Idx);
- unsigned NumElements = Record[1];
- unsigned VecKind = Record[2];
- return Context.getVectorType(ElementType, NumElements,
- (VectorType::VectorKind)VecKind);
- }
-
- case TYPE_EXT_VECTOR: {
- if (Record.size() != 3) {
- Error("incorrect encoding of extended vector type in AST file");
- return QualType();
- }
-
- QualType ElementType = readType(*Loc.F, Record, Idx);
- unsigned NumElements = Record[1];
- return Context.getExtVectorType(ElementType, NumElements);
- }
-
- case TYPE_FUNCTION_NO_PROTO: {
- if (Record.size() != 8) {
- Error("incorrect encoding of no-proto function type");
- return QualType();
- }
- QualType ResultType = readType(*Loc.F, Record, Idx);
- FunctionType::ExtInfo Info(Record[1], Record[2], Record[3],
- (CallingConv)Record[4], Record[5], Record[6],
- Record[7]);
- return Context.getFunctionNoProtoType(ResultType, Info);
- }
-
- case TYPE_FUNCTION_PROTO: {
- QualType ResultType = readType(*Loc.F, Record, Idx);
-
- FunctionProtoType::ExtProtoInfo EPI;
- EPI.ExtInfo = FunctionType::ExtInfo(/*noreturn*/ Record[1],
- /*hasregparm*/ Record[2],
- /*regparm*/ Record[3],
- static_cast<CallingConv>(Record[4]),
- /*produces*/ Record[5],
- /*nocallersavedregs*/ Record[6],
- /*nocfcheck*/ Record[7]);
-
- unsigned Idx = 8;
-
- EPI.Variadic = Record[Idx++];
- EPI.HasTrailingReturn = Record[Idx++];
- EPI.TypeQuals = Qualifiers::fromOpaqueValue(Record[Idx++]);
- EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);
- SmallVector<QualType, 8> ExceptionStorage;
- readExceptionSpec(*Loc.F, ExceptionStorage, EPI.ExceptionSpec, Record, Idx);
-
- unsigned NumParams = Record[Idx++];
- SmallVector<QualType, 16> ParamTypes;
- for (unsigned I = 0; I != NumParams; ++I)
- ParamTypes.push_back(readType(*Loc.F, Record, Idx));
-
- SmallVector<FunctionProtoType::ExtParameterInfo, 4> ExtParameterInfos;
- if (Idx != Record.size()) {
- for (unsigned I = 0; I != NumParams; ++I)
- ExtParameterInfos.push_back(
- FunctionProtoType::ExtParameterInfo
- ::getFromOpaqueValue(Record[Idx++]));
- EPI.ExtParameterInfos = ExtParameterInfos.data();
- }
-
- assert(Idx == Record.size());
-
- return Context.getFunctionType(ResultType, ParamTypes, EPI);
- }
-
- case TYPE_UNRESOLVED_USING: {
- unsigned Idx = 0;
- return Context.getTypeDeclType(
- ReadDeclAs<UnresolvedUsingTypenameDecl>(*Loc.F, Record, Idx));
- }
-
- case TYPE_TYPEDEF: {
- if (Record.size() != 2) {
- Error("incorrect encoding of typedef type");
- return QualType();
- }
- unsigned Idx = 0;
- TypedefNameDecl *Decl = ReadDeclAs<TypedefNameDecl>(*Loc.F, Record, Idx);
- QualType Canonical = readType(*Loc.F, Record, Idx);
- if (!Canonical.isNull())
- Canonical = Context.getCanonicalType(Canonical);
- return Context.getTypedefType(Decl, Canonical);
- }
-
- case TYPE_TYPEOF_EXPR:
- return Context.getTypeOfExprType(ReadExpr(*Loc.F));
-
- case TYPE_TYPEOF: {
- if (Record.size() != 1) {
- Error("incorrect encoding of typeof(type) in AST file");
- return QualType();
- }
- QualType UnderlyingType = readType(*Loc.F, Record, Idx);
- return Context.getTypeOfType(UnderlyingType);
- }
-
- case TYPE_DECLTYPE: {
- QualType UnderlyingType = readType(*Loc.F, Record, Idx);
- return Context.getDecltypeType(ReadExpr(*Loc.F), UnderlyingType);
- }
-
- case TYPE_UNARY_TRANSFORM: {
- QualType BaseType = readType(*Loc.F, Record, Idx);
- QualType UnderlyingType = readType(*Loc.F, Record, Idx);
- UnaryTransformType::UTTKind UKind = (UnaryTransformType::UTTKind)Record[2];
- return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind);
- }
-
- case TYPE_AUTO: {
- QualType Deduced = readType(*Loc.F, Record, Idx);
- AutoTypeKeyword Keyword = (AutoTypeKeyword)Record[Idx++];
- bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;
- return Context.getAutoType(Deduced, Keyword, IsDependent);
- }
-
- case TYPE_DEDUCED_TEMPLATE_SPECIALIZATION: {
- TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
- QualType Deduced = readType(*Loc.F, Record, Idx);
- bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;
- return Context.getDeducedTemplateSpecializationType(Name, Deduced,
- IsDependent);
- }
-
- case TYPE_RECORD: {
- if (Record.size() != 2) {
- Error("incorrect encoding of record type");
- return QualType();
- }
- unsigned Idx = 0;
- bool IsDependent = Record[Idx++];
- RecordDecl *RD = ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx);
- RD = cast_or_null<RecordDecl>(RD->getCanonicalDecl());
- QualType T = Context.getRecordType(RD);
- const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
- return T;
- }
-
- case TYPE_ENUM: {
- if (Record.size() != 2) {
- Error("incorrect encoding of enum type");
- return QualType();
- }
- unsigned Idx = 0;
- bool IsDependent = Record[Idx++];
- QualType T
- = Context.getEnumType(ReadDeclAs<EnumDecl>(*Loc.F, Record, Idx));
- const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
- return T;
- }
-
- case TYPE_ATTRIBUTED: {
- if (Record.size() != 3) {
- Error("incorrect encoding of attributed type");
- return QualType();
- }
- QualType modifiedType = readType(*Loc.F, Record, Idx);
- QualType equivalentType = readType(*Loc.F, Record, Idx);
- AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);
- return Context.getAttributedType(kind, modifiedType, equivalentType);
- }
-
- case TYPE_PAREN: {
- if (Record.size() != 1) {
- Error("incorrect encoding of paren type");
- return QualType();
- }
- QualType InnerType = readType(*Loc.F, Record, Idx);
- return Context.getParenType(InnerType);
- }
-
- case TYPE_PACK_EXPANSION: {
- if (Record.size() != 2) {
- Error("incorrect encoding of pack expansion type");
- return QualType();
- }
- QualType Pattern = readType(*Loc.F, Record, Idx);
- if (Pattern.isNull())
- return QualType();
- Optional<unsigned> NumExpansions;
- if (Record[1])
- NumExpansions = Record[1] - 1;
- return Context.getPackExpansionType(Pattern, NumExpansions);
- }
-
- case TYPE_ELABORATED: {
- unsigned Idx = 0;
- ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
- QualType NamedType = readType(*Loc.F, Record, Idx);
- TagDecl *OwnedTagDecl = ReadDeclAs<TagDecl>(*Loc.F, Record, Idx);
- return Context.getElaboratedType(Keyword, NNS, NamedType, OwnedTagDecl);
- }
-
- case TYPE_OBJC_INTERFACE: {
- unsigned Idx = 0;
- ObjCInterfaceDecl *ItfD
- = ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);
- return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
- }
-
- case TYPE_OBJC_TYPE_PARAM: {
- unsigned Idx = 0;
- ObjCTypeParamDecl *Decl
- = ReadDeclAs<ObjCTypeParamDecl>(*Loc.F, Record, Idx);
- unsigned NumProtos = Record[Idx++];
- SmallVector<ObjCProtocolDecl*, 4> Protos;
- for (unsigned I = 0; I != NumProtos; ++I)
- Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
- return Context.getObjCTypeParamType(Decl, Protos);
- }
-
- case TYPE_OBJC_OBJECT: {
- unsigned Idx = 0;
- QualType Base = readType(*Loc.F, Record, Idx);
- unsigned NumTypeArgs = Record[Idx++];
- SmallVector<QualType, 4> TypeArgs;
- for (unsigned I = 0; I != NumTypeArgs; ++I)
- TypeArgs.push_back(readType(*Loc.F, Record, Idx));
- unsigned NumProtos = Record[Idx++];
- SmallVector<ObjCProtocolDecl*, 4> Protos;
- for (unsigned I = 0; I != NumProtos; ++I)
- Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
- bool IsKindOf = Record[Idx++];
- return Context.getObjCObjectType(Base, TypeArgs, Protos, IsKindOf);
- }
-
- case TYPE_OBJC_OBJECT_POINTER: {
- unsigned Idx = 0;
- QualType Pointee = readType(*Loc.F, Record, Idx);
- return Context.getObjCObjectPointerType(Pointee);
- }
-
- case TYPE_SUBST_TEMPLATE_TYPE_PARM: {
- unsigned Idx = 0;
- QualType Parm = readType(*Loc.F, Record, Idx);
- QualType Replacement = readType(*Loc.F, Record, Idx);
- return Context.getSubstTemplateTypeParmType(
- cast<TemplateTypeParmType>(Parm),
- Context.getCanonicalType(Replacement));
- }
-
- case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
- unsigned Idx = 0;
- QualType Parm = readType(*Loc.F, Record, Idx);
- TemplateArgument ArgPack = ReadTemplateArgument(*Loc.F, Record, Idx);
- return Context.getSubstTemplateTypeParmPackType(
- cast<TemplateTypeParmType>(Parm),
- ArgPack);
- }
-
- case TYPE_INJECTED_CLASS_NAME: {
- CXXRecordDecl *D = ReadDeclAs<CXXRecordDecl>(*Loc.F, Record, Idx);
- QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
- // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
- // for AST reading, too much interdependencies.
- const Type *T = nullptr;
- for (auto *DI = D; DI; DI = DI->getPreviousDecl()) {
- if (const Type *Existing = DI->getTypeForDecl()) {
- T = Existing;
- break;
- }
- }
- if (!T) {
- T = new (Context, TypeAlignment) InjectedClassNameType(D, TST);
- for (auto *DI = D; DI; DI = DI->getPreviousDecl())
- DI->setTypeForDecl(T);
- }
- return QualType(T, 0);
- }
-
- case TYPE_TEMPLATE_TYPE_PARM: {
- unsigned Idx = 0;
- unsigned Depth = Record[Idx++];
- unsigned Index = Record[Idx++];
- bool Pack = Record[Idx++];
- TemplateTypeParmDecl *D
- = ReadDeclAs<TemplateTypeParmDecl>(*Loc.F, Record, Idx);
- return Context.getTemplateTypeParmType(Depth, Index, Pack, D);
- }
-
- case TYPE_DEPENDENT_NAME: {
- unsigned Idx = 0;
- ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
- const IdentifierInfo *Name = GetIdentifierInfo(*Loc.F, Record, Idx);
- QualType Canon = readType(*Loc.F, Record, Idx);
- if (!Canon.isNull())
- Canon = Context.getCanonicalType(Canon);
- return Context.getDependentNameType(Keyword, NNS, Name, Canon);
- }
-
- case TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION: {
- unsigned Idx = 0;
- ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
- const IdentifierInfo *Name = GetIdentifierInfo(*Loc.F, Record, Idx);
- unsigned NumArgs = Record[Idx++];
- SmallVector<TemplateArgument, 8> Args;
- Args.reserve(NumArgs);
- while (NumArgs--)
- Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx));
- return Context.getDependentTemplateSpecializationType(Keyword, NNS, Name,
- Args);
- }
-
- case TYPE_DEPENDENT_SIZED_ARRAY: {
- unsigned Idx = 0;
-
- // ArrayType
- QualType ElementType = readType(*Loc.F, Record, Idx);
- ArrayType::ArraySizeModifier ASM
- = (ArrayType::ArraySizeModifier)Record[Idx++];
- unsigned IndexTypeQuals = Record[Idx++];
-
- // DependentSizedArrayType
- Expr *NumElts = ReadExpr(*Loc.F);
- SourceRange Brackets = ReadSourceRange(*Loc.F, Record, Idx);
-
- return Context.getDependentSizedArrayType(ElementType, NumElts, ASM,
- IndexTypeQuals, Brackets);
- }
-
- case TYPE_TEMPLATE_SPECIALIZATION: {
- unsigned Idx = 0;
- bool IsDependent = Record[Idx++];
- TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
- SmallVector<TemplateArgument, 8> Args;
- ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);
- QualType Underlying = readType(*Loc.F, Record, Idx);
- QualType T;
- if (Underlying.isNull())
- T = Context.getCanonicalTemplateSpecializationType(Name, Args);
- else
- T = Context.getTemplateSpecializationType(Name, Args, Underlying);
- const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
- return T;
- }
-
- case TYPE_ATOMIC: {
- if (Record.size() != 1) {
- Error("Incorrect encoding of atomic type");
- return QualType();
- }
- QualType ValueType = readType(*Loc.F, Record, Idx);
- return Context.getAtomicType(ValueType);
- }
-
- case TYPE_PIPE: {
- if (Record.size() != 2) {
- Error("Incorrect encoding of pipe type");
- return QualType();
- }
-
- // Reading the pipe element type.
- QualType ElementType = readType(*Loc.F, Record, Idx);
- unsigned ReadOnly = Record[1];
- return Context.getPipeType(ElementType, ReadOnly);
- }
-
- case TYPE_DEPENDENT_SIZED_VECTOR: {
- unsigned Idx = 0;
- QualType ElementType = readType(*Loc.F, Record, Idx);
- Expr *SizeExpr = ReadExpr(*Loc.F);
- SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx);
- unsigned VecKind = Record[Idx];
-
- return Context.getDependentVectorType(ElementType, SizeExpr, AttrLoc,
- (VectorType::VectorKind)VecKind);
- }
-
- case TYPE_DEPENDENT_SIZED_EXT_VECTOR: {
- unsigned Idx = 0;
-
- // DependentSizedExtVectorType
- QualType ElementType = readType(*Loc.F, Record, Idx);
- Expr *SizeExpr = ReadExpr(*Loc.F);
- SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx);
-
- return Context.getDependentSizedExtVectorType(ElementType, SizeExpr,
- AttrLoc);
- }
-
- case TYPE_DEPENDENT_ADDRESS_SPACE: {
- unsigned Idx = 0;
-
- // DependentAddressSpaceType
- QualType PointeeType = readType(*Loc.F, Record, Idx);
- Expr *AddrSpaceExpr = ReadExpr(*Loc.F);
- SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx);
-
- return Context.getDependentAddressSpaceType(PointeeType, AddrSpaceExpr,
- AttrLoc);
- }
- }
- llvm_unreachable("Invalid TypeCode!");
-}
-
-void ASTReader::readExceptionSpec(ModuleFile &ModuleFile,
- SmallVectorImpl<QualType> &Exceptions,
- FunctionProtoType::ExceptionSpecInfo &ESI,
- const RecordData &Record, unsigned &Idx) {
- ExceptionSpecificationType EST =
- static_cast<ExceptionSpecificationType>(Record[Idx++]);
- ESI.Type = EST;
- if (EST == EST_Dynamic) {
- for (unsigned I = 0, N = Record[Idx++]; I != N; ++I)
- Exceptions.push_back(readType(ModuleFile, Record, Idx));
- ESI.Exceptions = Exceptions;
- } else if (isComputedNoexcept(EST)) {
- ESI.NoexceptExpr = ReadExpr(ModuleFile);
- } else if (EST == EST_Uninstantiated) {
- ESI.SourceDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
- ESI.SourceTemplate = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
- } else if (EST == EST_Unevaluated) {
- ESI.SourceDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
- }
-}
-
-namespace clang {
-
-class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
- ModuleFile *F;
- ASTReader *Reader;
- const ASTReader::RecordData &Record;
- unsigned &Idx;
-
- SourceLocation ReadSourceLocation() {
- return Reader->ReadSourceLocation(*F, Record, Idx);
- }
-
- TypeSourceInfo *GetTypeSourceInfo() {
- return Reader->GetTypeSourceInfo(*F, Record, Idx);
- }
-
- NestedNameSpecifierLoc ReadNestedNameSpecifierLoc() {
- return Reader->ReadNestedNameSpecifierLoc(*F, Record, Idx);
- }
-
- Attr *ReadAttr() {
- return Reader->ReadAttr(*F, Record, Idx);
- }
-
-public:
- TypeLocReader(ModuleFile &F, ASTReader &Reader,
- const ASTReader::RecordData &Record, unsigned &Idx)
- : F(&F), Reader(&Reader), Record(Record), Idx(Idx) {}
-
- // We want compile-time assurance that we've enumerated all of
- // these, so unfortunately we have to declare them first, then
- // define them out-of-line.
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
-#include "clang/AST/TypeLocNodes.def"
-
- void VisitFunctionTypeLoc(FunctionTypeLoc);
- void VisitArrayTypeLoc(ArrayTypeLoc);
-};
-
-} // namespace clang
-
-void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
- // nothing to do
-}
-
-void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
- TL.setBuiltinLoc(ReadSourceLocation());
- if (TL.needsExtraLocalData()) {
- TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
- TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
- TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
- TL.setModeAttr(Record[Idx++]);
- }
-}
-
-void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
- TL.setStarLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
- // nothing to do
-}
-
-void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
- // nothing to do
-}
-
-void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
- TL.setCaretLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
- TL.setAmpLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
- TL.setAmpAmpLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
- TL.setStarLoc(ReadSourceLocation());
- TL.setClassTInfo(GetTypeSourceInfo());
-}
-
-void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
- TL.setLBracketLoc(ReadSourceLocation());
- TL.setRBracketLoc(ReadSourceLocation());
- if (Record[Idx++])
- TL.setSizeExpr(Reader->ReadExpr(*F));
- else
- TL.setSizeExpr(nullptr);
-}
-
-void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocReader::VisitDependentSizedArrayTypeLoc(
- DependentSizedArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocReader::VisitDependentAddressSpaceTypeLoc(
- DependentAddressSpaceTypeLoc TL) {
-
- TL.setAttrNameLoc(ReadSourceLocation());
- SourceRange range;
- range.setBegin(ReadSourceLocation());
- range.setEnd(ReadSourceLocation());
- TL.setAttrOperandParensRange(range);
- TL.setAttrExprOperand(Reader->ReadExpr(*F));
-}
-
-void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
- DependentSizedExtVectorTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitDependentVectorTypeLoc(
- DependentVectorTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
- TL.setLocalRangeBegin(ReadSourceLocation());
- TL.setLParenLoc(ReadSourceLocation());
- TL.setRParenLoc(ReadSourceLocation());
- TL.setExceptionSpecRange(SourceRange(Reader->ReadSourceLocation(*F, Record, Idx),
- Reader->ReadSourceLocation(*F, Record, Idx)));
- TL.setLocalRangeEnd(ReadSourceLocation());
- for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) {
- TL.setParam(i, Reader->ReadDeclAs<ParmVarDecl>(*F, Record, Idx));
- }
-}
-
-void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
- VisitFunctionTypeLoc(TL);
-}
-
-void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
- VisitFunctionTypeLoc(TL);
-}
-
-void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
- TL.setTypeofLoc(ReadSourceLocation());
- TL.setLParenLoc(ReadSourceLocation());
- TL.setRParenLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
- TL.setTypeofLoc(ReadSourceLocation());
- TL.setLParenLoc(ReadSourceLocation());
- TL.setRParenLoc(ReadSourceLocation());
- TL.setUnderlyingTInfo(GetTypeSourceInfo());
-}
-
-void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
- TL.setKWLoc(ReadSourceLocation());
- TL.setLParenLoc(ReadSourceLocation());
- TL.setRParenLoc(ReadSourceLocation());
- TL.setUnderlyingTInfo(GetTypeSourceInfo());
-}
-
-void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc(
- DeducedTemplateSpecializationTypeLoc TL) {
- TL.setTemplateNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
- TL.setAttr(ReadAttr());
-}
-
-void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
- SubstTemplateTypeParmTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
- SubstTemplateTypeParmPackTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitTemplateSpecializationTypeLoc(
- TemplateSpecializationTypeLoc TL) {
- TL.setTemplateKeywordLoc(ReadSourceLocation());
- TL.setTemplateNameLoc(ReadSourceLocation());
- TL.setLAngleLoc(ReadSourceLocation());
- TL.setRAngleLoc(ReadSourceLocation());
- for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- TL.setArgLocInfo(
- i,
- Reader->GetTemplateArgumentLocInfo(
- *F, TL.getTypePtr()->getArg(i).getKind(), Record, Idx));
-}
-
-void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
- TL.setLParenLoc(ReadSourceLocation());
- TL.setRParenLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- TL.setElaboratedKeywordLoc(ReadSourceLocation());
- TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
-}
-
-void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
- TL.setElaboratedKeywordLoc(ReadSourceLocation());
- TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc TL) {
- TL.setElaboratedKeywordLoc(ReadSourceLocation());
- TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
- TL.setTemplateKeywordLoc(ReadSourceLocation());
- TL.setTemplateNameLoc(ReadSourceLocation());
- TL.setLAngleLoc(ReadSourceLocation());
- TL.setRAngleLoc(ReadSourceLocation());
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- TL.setArgLocInfo(
- I,
- Reader->GetTemplateArgumentLocInfo(
- *F, TL.getTypePtr()->getArg(I).getKind(), Record, Idx));
-}
-
-void TypeLocReader::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
- TL.setEllipsisLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
- TL.setNameLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
- if (TL.getNumProtocols()) {
- TL.setProtocolLAngleLoc(ReadSourceLocation());
- TL.setProtocolRAngleLoc(ReadSourceLocation());
- }
- for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
- TL.setProtocolLoc(i, ReadSourceLocation());
-}
-
-void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
- TL.setHasBaseTypeAsWritten(Record[Idx++]);
- TL.setTypeArgsLAngleLoc(ReadSourceLocation());
- TL.setTypeArgsRAngleLoc(ReadSourceLocation());
- for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)
- TL.setTypeArgTInfo(i, GetTypeSourceInfo());
- TL.setProtocolLAngleLoc(ReadSourceLocation());
- TL.setProtocolRAngleLoc(ReadSourceLocation());
- for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
- TL.setProtocolLoc(i, ReadSourceLocation());
-}
-
-void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
- TL.setStarLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
- TL.setKWLoc(ReadSourceLocation());
- TL.setLParenLoc(ReadSourceLocation());
- TL.setRParenLoc(ReadSourceLocation());
-}
-
-void TypeLocReader::VisitPipeTypeLoc(PipeTypeLoc TL) {
- TL.setKWLoc(ReadSourceLocation());
-}
-
-void ASTReader::ReadTypeLoc(ModuleFile &F, const ASTReader::RecordData &Record,
- unsigned &Idx, TypeLoc TL) {
- TypeLocReader TLR(F, *this, Record, Idx);
- for (; !TL.isNull(); TL = TL.getNextTypeLoc())
- TLR.Visit(TL);
-}
-
-TypeSourceInfo *
-ASTReader::GetTypeSourceInfo(ModuleFile &F, const ASTReader::RecordData &Record,
- unsigned &Idx) {
- QualType InfoTy = readType(F, Record, Idx);
- if (InfoTy.isNull())
- return nullptr;
-
- TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
- ReadTypeLoc(F, Record, Idx, TInfo->getTypeLoc());
- return TInfo;
-}
-
-QualType ASTReader::GetType(TypeID ID) {
- assert(ContextObj && "reading type with no AST context");
- ASTContext &Context = *ContextObj;
-
- unsigned FastQuals = ID & Qualifiers::FastMask;
- unsigned Index = ID >> Qualifiers::FastWidth;
-
- if (Index < NUM_PREDEF_TYPE_IDS) {
- QualType T;
- switch ((PredefinedTypeIDs)Index) {
- case PREDEF_TYPE_NULL_ID:
- return QualType();
- case PREDEF_TYPE_VOID_ID:
- T = Context.VoidTy;
- break;
- case PREDEF_TYPE_BOOL_ID:
- T = Context.BoolTy;
- break;
- case PREDEF_TYPE_CHAR_U_ID:
- case PREDEF_TYPE_CHAR_S_ID:
- // FIXME: Check that the signedness of CharTy is correct!
- T = Context.CharTy;
- break;
- case PREDEF_TYPE_UCHAR_ID:
- T = Context.UnsignedCharTy;
- break;
- case PREDEF_TYPE_USHORT_ID:
- T = Context.UnsignedShortTy;
- break;
- case PREDEF_TYPE_UINT_ID:
- T = Context.UnsignedIntTy;
- break;
- case PREDEF_TYPE_ULONG_ID:
- T = Context.UnsignedLongTy;
- break;
- case PREDEF_TYPE_ULONGLONG_ID:
- T = Context.UnsignedLongLongTy;
- break;
- case PREDEF_TYPE_UINT128_ID:
- T = Context.UnsignedInt128Ty;
- break;
- case PREDEF_TYPE_SCHAR_ID:
- T = Context.SignedCharTy;
- break;
- case PREDEF_TYPE_WCHAR_ID:
- T = Context.WCharTy;
- break;
- case PREDEF_TYPE_SHORT_ID:
- T = Context.ShortTy;
- break;
- case PREDEF_TYPE_INT_ID:
- T = Context.IntTy;
- break;
- case PREDEF_TYPE_LONG_ID:
- T = Context.LongTy;
- break;
- case PREDEF_TYPE_LONGLONG_ID:
- T = Context.LongLongTy;
- break;
- case PREDEF_TYPE_INT128_ID:
- T = Context.Int128Ty;
- break;
- case PREDEF_TYPE_HALF_ID:
- T = Context.HalfTy;
- break;
- case PREDEF_TYPE_FLOAT_ID:
- T = Context.FloatTy;
- break;
- case PREDEF_TYPE_DOUBLE_ID:
- T = Context.DoubleTy;
- break;
- case PREDEF_TYPE_LONGDOUBLE_ID:
- T = Context.LongDoubleTy;
- break;
- case PREDEF_TYPE_SHORT_ACCUM_ID:
- T = Context.ShortAccumTy;
- break;
- case PREDEF_TYPE_ACCUM_ID:
- T = Context.AccumTy;
- break;
- case PREDEF_TYPE_LONG_ACCUM_ID:
- T = Context.LongAccumTy;
- break;
- case PREDEF_TYPE_USHORT_ACCUM_ID:
- T = Context.UnsignedShortAccumTy;
- break;
- case PREDEF_TYPE_UACCUM_ID:
- T = Context.UnsignedAccumTy;
- break;
- case PREDEF_TYPE_ULONG_ACCUM_ID:
- T = Context.UnsignedLongAccumTy;
- break;
- case PREDEF_TYPE_SHORT_FRACT_ID:
- T = Context.ShortFractTy;
- break;
- case PREDEF_TYPE_FRACT_ID:
- T = Context.FractTy;
- break;
- case PREDEF_TYPE_LONG_FRACT_ID:
- T = Context.LongFractTy;
- break;
- case PREDEF_TYPE_USHORT_FRACT_ID:
- T = Context.UnsignedShortFractTy;
- break;
- case PREDEF_TYPE_UFRACT_ID:
- T = Context.UnsignedFractTy;
- break;
- case PREDEF_TYPE_ULONG_FRACT_ID:
- T = Context.UnsignedLongFractTy;
- break;
- case PREDEF_TYPE_SAT_SHORT_ACCUM_ID:
- T = Context.SatShortAccumTy;
- break;
- case PREDEF_TYPE_SAT_ACCUM_ID:
- T = Context.SatAccumTy;
- break;
- case PREDEF_TYPE_SAT_LONG_ACCUM_ID:
- T = Context.SatLongAccumTy;
- break;
- case PREDEF_TYPE_SAT_USHORT_ACCUM_ID:
- T = Context.SatUnsignedShortAccumTy;
- break;
- case PREDEF_TYPE_SAT_UACCUM_ID:
- T = Context.SatUnsignedAccumTy;
- break;
- case PREDEF_TYPE_SAT_ULONG_ACCUM_ID:
- T = Context.SatUnsignedLongAccumTy;
- break;
- case PREDEF_TYPE_SAT_SHORT_FRACT_ID:
- T = Context.SatShortFractTy;
- break;
- case PREDEF_TYPE_SAT_FRACT_ID:
- T = Context.SatFractTy;
- break;
- case PREDEF_TYPE_SAT_LONG_FRACT_ID:
- T = Context.SatLongFractTy;
- break;
- case PREDEF_TYPE_SAT_USHORT_FRACT_ID:
- T = Context.SatUnsignedShortFractTy;
- break;
- case PREDEF_TYPE_SAT_UFRACT_ID:
- T = Context.SatUnsignedFractTy;
- break;
- case PREDEF_TYPE_SAT_ULONG_FRACT_ID:
- T = Context.SatUnsignedLongFractTy;
- break;
- case PREDEF_TYPE_FLOAT16_ID:
- T = Context.Float16Ty;
- break;
- case PREDEF_TYPE_FLOAT128_ID:
- T = Context.Float128Ty;
- break;
- case PREDEF_TYPE_OVERLOAD_ID:
- T = Context.OverloadTy;
- break;
- case PREDEF_TYPE_BOUND_MEMBER:
- T = Context.BoundMemberTy;
- break;
- case PREDEF_TYPE_PSEUDO_OBJECT:
- T = Context.PseudoObjectTy;
- break;
- case PREDEF_TYPE_DEPENDENT_ID:
- T = Context.DependentTy;
- break;
- case PREDEF_TYPE_UNKNOWN_ANY:
- T = Context.UnknownAnyTy;
- break;
- case PREDEF_TYPE_NULLPTR_ID:
- T = Context.NullPtrTy;
- break;
- case PREDEF_TYPE_CHAR8_ID:
- T = Context.Char8Ty;
- break;
- case PREDEF_TYPE_CHAR16_ID:
- T = Context.Char16Ty;
- break;
- case PREDEF_TYPE_CHAR32_ID:
- T = Context.Char32Ty;
- break;
- case PREDEF_TYPE_OBJC_ID:
- T = Context.ObjCBuiltinIdTy;
- break;
- case PREDEF_TYPE_OBJC_CLASS:
- T = Context.ObjCBuiltinClassTy;
- break;
- case PREDEF_TYPE_OBJC_SEL:
- T = Context.ObjCBuiltinSelTy;
- break;
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
- case PREDEF_TYPE_##Id##_ID: \
- T = Context.SingletonId; \
- break;
-#include "clang/Basic/OpenCLImageTypes.def"
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
- case PREDEF_TYPE_##Id##_ID: \
- T = Context.Id##Ty; \
- break;
-#include "clang/Basic/OpenCLExtensionTypes.def"
- case PREDEF_TYPE_SAMPLER_ID:
- T = Context.OCLSamplerTy;
- break;
- case PREDEF_TYPE_EVENT_ID:
- T = Context.OCLEventTy;
- break;
- case PREDEF_TYPE_CLK_EVENT_ID:
- T = Context.OCLClkEventTy;
- break;
- case PREDEF_TYPE_QUEUE_ID:
- T = Context.OCLQueueTy;
- break;
- case PREDEF_TYPE_RESERVE_ID_ID:
- T = Context.OCLReserveIDTy;
- break;
- case PREDEF_TYPE_AUTO_DEDUCT:
- T = Context.getAutoDeductType();
- break;
- case PREDEF_TYPE_AUTO_RREF_DEDUCT:
- T = Context.getAutoRRefDeductType();
- break;
- case PREDEF_TYPE_ARC_UNBRIDGED_CAST:
- T = Context.ARCUnbridgedCastTy;
- break;
- case PREDEF_TYPE_BUILTIN_FN:
- T = Context.BuiltinFnTy;
- break;
- case PREDEF_TYPE_OMP_ARRAY_SECTION:
- T = Context.OMPArraySectionTy;
- break;
- }
-
- assert(!T.isNull() && "Unknown predefined type");
- return T.withFastQualifiers(FastQuals);
- }
-
- Index -= NUM_PREDEF_TYPE_IDS;
- assert(Index < TypesLoaded.size() && "Type index out-of-range");
- if (TypesLoaded[Index].isNull()) {
- TypesLoaded[Index] = readTypeRecord(Index);
- if (TypesLoaded[Index].isNull())
- return QualType();
-
- TypesLoaded[Index]->setFromAST();
- if (DeserializationListener)
- DeserializationListener->TypeRead(TypeIdx::fromTypeID(ID),
- TypesLoaded[Index]);
- }
-
- return TypesLoaded[Index].withFastQualifiers(FastQuals);
-}
-
-QualType ASTReader::getLocalType(ModuleFile &F, unsigned LocalID) {
- return GetType(getGlobalTypeID(F, LocalID));
-}
-
-serialization::TypeID
-ASTReader::getGlobalTypeID(ModuleFile &F, unsigned LocalID) const {
- unsigned FastQuals = LocalID & Qualifiers::FastMask;
- unsigned LocalIndex = LocalID >> Qualifiers::FastWidth;
-
- if (LocalIndex < NUM_PREDEF_TYPE_IDS)
- return LocalID;
-
- if (!F.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(F);
-
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = F.TypeRemap.find(LocalIndex - NUM_PREDEF_TYPE_IDS);
- assert(I != F.TypeRemap.end() && "Invalid index into type index remap");
-
- unsigned GlobalIndex = LocalIndex + I->second;
- return (GlobalIndex << Qualifiers::FastWidth) | FastQuals;
-}
-
-TemplateArgumentLocInfo
-ASTReader::GetTemplateArgumentLocInfo(ModuleFile &F,
- TemplateArgument::ArgKind Kind,
- const RecordData &Record,
- unsigned &Index) {
- switch (Kind) {
- case TemplateArgument::Expression:
- return ReadExpr(F);
- case TemplateArgument::Type:
- return GetTypeSourceInfo(F, Record, Index);
- case TemplateArgument::Template: {
- NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record,
- Index);
- SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
- return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
- SourceLocation());
- }
- case TemplateArgument::TemplateExpansion: {
- NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record,
- Index);
- SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
- SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);
- return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
- EllipsisLoc);
- }
- case TemplateArgument::Null:
- case TemplateArgument::Integral:
- case TemplateArgument::Declaration:
- case TemplateArgument::NullPtr:
- case TemplateArgument::Pack:
- // FIXME: Is this right?
- return TemplateArgumentLocInfo();
- }
- llvm_unreachable("unexpected template argument loc");
-}
-
-TemplateArgumentLoc
-ASTReader::ReadTemplateArgumentLoc(ModuleFile &F,
- const RecordData &Record, unsigned &Index) {
- TemplateArgument Arg = ReadTemplateArgument(F, Record, Index);
-
- if (Arg.getKind() == TemplateArgument::Expression) {
- if (Record[Index++]) // bool InfoHasSameExpr.
- return TemplateArgumentLoc(Arg, TemplateArgumentLocInfo(Arg.getAsExpr()));
- }
- return TemplateArgumentLoc(Arg, GetTemplateArgumentLocInfo(F, Arg.getKind(),
- Record, Index));
-}
-
-const ASTTemplateArgumentListInfo*
-ASTReader::ReadASTTemplateArgumentListInfo(ModuleFile &F,
- const RecordData &Record,
- unsigned &Index) {
- SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Index);
- SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Index);
- unsigned NumArgsAsWritten = Record[Index++];
- TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
- for (unsigned i = 0; i != NumArgsAsWritten; ++i)
- TemplArgsInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Index));
- return ASTTemplateArgumentListInfo::Create(getContext(), TemplArgsInfo);
-}
-
-Decl *ASTReader::GetExternalDecl(uint32_t ID) {
- return GetDecl(ID);
-}
-
-void ASTReader::CompleteRedeclChain(const Decl *D) {
- if (NumCurrentElementsDeserializing) {
- // We arrange to not care about the complete redeclaration chain while we're
- // deserializing. Just remember that the AST has marked this one as complete
- // but that it's not actually complete yet, so we know we still need to
- // complete it later.
- PendingIncompleteDeclChains.push_back(const_cast<Decl*>(D));
- return;
- }
-
- const DeclContext *DC = D->getDeclContext()->getRedeclContext();
-
- // If this is a named declaration, complete it by looking it up
- // within its context.
- //
- // FIXME: Merging a function definition should merge
- // all mergeable entities within it.
- if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
- isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
- if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
- if (!getContext().getLangOpts().CPlusPlus &&
- isa<TranslationUnitDecl>(DC)) {
- // Outside of C++, we don't have a lookup table for the TU, so update
- // the identifier instead. (For C++ modules, we don't store decls
- // in the serialized identifier table, so we do the lookup in the TU.)
- auto *II = Name.getAsIdentifierInfo();
- assert(II && "non-identifier name in C?");
- if (II->isOutOfDate())
- updateOutOfDateIdentifier(*II);
- } else
- DC->lookup(Name);
- } else if (needsAnonymousDeclarationNumber(cast<NamedDecl>(D))) {
- // Find all declarations of this kind from the relevant context.
- for (auto *DCDecl : cast<Decl>(D->getLexicalDeclContext())->redecls()) {
- auto *DC = cast<DeclContext>(DCDecl);
- SmallVector<Decl*, 8> Decls;
- FindExternalLexicalDecls(
- DC, [&](Decl::Kind K) { return K == D->getKind(); }, Decls);
- }
- }
- }
-
- if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
- CTSD->getSpecializedTemplate()->LoadLazySpecializations();
- if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
- VTSD->getSpecializedTemplate()->LoadLazySpecializations();
- if (auto *FD = dyn_cast<FunctionDecl>(D)) {
- if (auto *Template = FD->getPrimaryTemplate())
- Template->LoadLazySpecializations();
- }
-}
-
-CXXCtorInitializer **
-ASTReader::GetExternalCXXCtorInitializers(uint64_t Offset) {
- RecordLocation Loc = getLocalBitOffset(Offset);
- BitstreamCursor &Cursor = Loc.F->DeclsCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Loc.Offset);
- ReadingKindTracker ReadingKind(Read_Decl, *this);
-
- RecordData Record;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record);
- if (RecCode != DECL_CXX_CTOR_INITIALIZERS) {
- Error("malformed AST file: missing C++ ctor initializers");
- return nullptr;
- }
-
- unsigned Idx = 0;
- return ReadCXXCtorInitializers(*Loc.F, Record, Idx);
-}
-
-CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
- assert(ContextObj && "reading base specifiers with no AST context");
- ASTContext &Context = *ContextObj;
-
- RecordLocation Loc = getLocalBitOffset(Offset);
- BitstreamCursor &Cursor = Loc.F->DeclsCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Loc.Offset);
- ReadingKindTracker ReadingKind(Read_Decl, *this);
- RecordData Record;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record);
- if (RecCode != DECL_CXX_BASE_SPECIFIERS) {
- Error("malformed AST file: missing C++ base specifiers");
- return nullptr;
- }
-
- unsigned Idx = 0;
- unsigned NumBases = Record[Idx++];
- void *Mem = Context.Allocate(sizeof(CXXBaseSpecifier) * NumBases);
- CXXBaseSpecifier *Bases = new (Mem) CXXBaseSpecifier [NumBases];
- for (unsigned I = 0; I != NumBases; ++I)
- Bases[I] = ReadCXXBaseSpecifier(*Loc.F, Record, Idx);
- return Bases;
-}
-
-serialization::DeclID
-ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
- if (LocalID < NUM_PREDEF_DECL_IDS)
- return LocalID;
-
- if (!F.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(F);
-
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS);
- assert(I != F.DeclRemap.end() && "Invalid index into decl index remap");
-
- return LocalID + I->second;
-}
-
-bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
- ModuleFile &M) const {
- // Predefined decls aren't from any module.
- if (ID < NUM_PREDEF_DECL_IDS)
- return false;
-
- return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID &&
- ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls;
-}
-
-ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
- if (!D->isFromASTFile())
- return nullptr;
- GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- return I->second;
-}
-
-SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
- if (ID < NUM_PREDEF_DECL_IDS)
- return SourceLocation();
-
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
-
- if (Index > DeclsLoaded.size()) {
- Error("declaration ID out-of-range for AST file");
- return SourceLocation();
- }
-
- if (Decl *D = DeclsLoaded[Index])
- return D->getLocation();
-
- SourceLocation Loc;
- DeclCursorForID(ID, Loc);
- return Loc;
-}
-
-static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) {
- switch (ID) {
- case PREDEF_DECL_NULL_ID:
- return nullptr;
-
- case PREDEF_DECL_TRANSLATION_UNIT_ID:
- return Context.getTranslationUnitDecl();
-
- case PREDEF_DECL_OBJC_ID_ID:
- return Context.getObjCIdDecl();
-
- case PREDEF_DECL_OBJC_SEL_ID:
- return Context.getObjCSelDecl();
-
- case PREDEF_DECL_OBJC_CLASS_ID:
- return Context.getObjCClassDecl();
-
- case PREDEF_DECL_OBJC_PROTOCOL_ID:
- return Context.getObjCProtocolDecl();
-
- case PREDEF_DECL_INT_128_ID:
- return Context.getInt128Decl();
-
- case PREDEF_DECL_UNSIGNED_INT_128_ID:
- return Context.getUInt128Decl();
-
- case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
- return Context.getObjCInstanceTypeDecl();
-
- case PREDEF_DECL_BUILTIN_VA_LIST_ID:
- return Context.getBuiltinVaListDecl();
-
- case PREDEF_DECL_VA_LIST_TAG:
- return Context.getVaListTagDecl();
-
- case PREDEF_DECL_BUILTIN_MS_VA_LIST_ID:
- return Context.getBuiltinMSVaListDecl();
-
- case PREDEF_DECL_EXTERN_C_CONTEXT_ID:
- return Context.getExternCContextDecl();
-
- case PREDEF_DECL_MAKE_INTEGER_SEQ_ID:
- return Context.getMakeIntegerSeqDecl();
-
- case PREDEF_DECL_CF_CONSTANT_STRING_ID:
- return Context.getCFConstantStringDecl();
-
- case PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID:
- return Context.getCFConstantStringTagDecl();
-
- case PREDEF_DECL_TYPE_PACK_ELEMENT_ID:
- return Context.getTypePackElementDecl();
- }
- llvm_unreachable("PredefinedDeclIDs unknown enum value");
-}
-
-Decl *ASTReader::GetExistingDecl(DeclID ID) {
- assert(ContextObj && "reading decl with no AST context");
- if (ID < NUM_PREDEF_DECL_IDS) {
- Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID);
- if (D) {
- // Track that we have merged the declaration with ID \p ID into the
- // pre-existing predefined declaration \p D.
- auto &Merged = KeyDecls[D->getCanonicalDecl()];
- if (Merged.empty())
- Merged.push_back(ID);
- }
- return D;
- }
-
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
-
- if (Index >= DeclsLoaded.size()) {
- assert(0 && "declaration ID out-of-range for AST file");
- Error("declaration ID out-of-range for AST file");
- return nullptr;
- }
-
- return DeclsLoaded[Index];
-}
-
-Decl *ASTReader::GetDecl(DeclID ID) {
- if (ID < NUM_PREDEF_DECL_IDS)
- return GetExistingDecl(ID);
-
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
-
- if (Index >= DeclsLoaded.size()) {
- assert(0 && "declaration ID out-of-range for AST file");
- Error("declaration ID out-of-range for AST file");
- return nullptr;
- }
-
- if (!DeclsLoaded[Index]) {
- ReadDeclRecord(ID);
- if (DeserializationListener)
- DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
- }
-
- return DeclsLoaded[Index];
-}
-
-DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
- DeclID GlobalID) {
- if (GlobalID < NUM_PREDEF_DECL_IDS)
- return GlobalID;
-
- GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID);
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- ModuleFile *Owner = I->second;
-
- llvm::DenseMap<ModuleFile *, serialization::DeclID>::iterator Pos
- = M.GlobalToLocalDeclIDs.find(Owner);
- if (Pos == M.GlobalToLocalDeclIDs.end())
- return 0;
-
- return GlobalID - Owner->BaseDeclID + Pos->second;
-}
-
-serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx) {
- if (Idx >= Record.size()) {
- Error("Corrupted AST file");
- return 0;
- }
-
- return getGlobalDeclID(F, Record[Idx++]);
-}
-
-/// 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 *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
- // Switch case IDs are per Decl.
- ClearSwitchCaseIDs();
-
- // Offset here is a global offset across the entire chain.
- RecordLocation Loc = getLocalBitOffset(Offset);
- Loc.F->DeclsCursor.JumpToBit(Loc.Offset);
- assert(NumCurrentElementsDeserializing == 0 &&
- "should not be called while already deserializing");
- Deserializing D(this);
- return ReadStmtFromStream(*Loc.F);
-}
-
-void ASTReader::FindExternalLexicalDecls(
- const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
- SmallVectorImpl<Decl *> &Decls) {
- bool PredefsVisited[NUM_PREDEF_DECL_IDS] = {};
-
- auto Visit = [&] (ModuleFile *M, LexicalContents LexicalDecls) {
- assert(LexicalDecls.size() % 2 == 0 && "expected an even number of entries");
- for (int I = 0, N = LexicalDecls.size(); I != N; I += 2) {
- auto K = (Decl::Kind)+LexicalDecls[I];
- if (!IsKindWeWant(K))
- continue;
-
- auto ID = (serialization::DeclID)+LexicalDecls[I + 1];
-
- // Don't add predefined declarations to the lexical context more
- // than once.
- if (ID < NUM_PREDEF_DECL_IDS) {
- if (PredefsVisited[ID])
- continue;
-
- PredefsVisited[ID] = true;
- }
-
- if (Decl *D = GetLocalDecl(*M, ID)) {
- assert(D->getKind() == K && "wrong kind for lexical decl");
- if (!DC->isDeclInLexicalTraversal(D))
- Decls.push_back(D);
- }
- }
- };
-
- if (isa<TranslationUnitDecl>(DC)) {
- for (auto Lexical : TULexicalDecls)
- Visit(Lexical.first, Lexical.second);
- } else {
- auto I = LexicalDecls.find(DC);
- if (I != LexicalDecls.end())
- Visit(I->second.first, I->second.second);
- }
-
- ++NumLexicalDeclContextsRead;
-}
-
-namespace {
-
-class DeclIDComp {
- ASTReader &Reader;
- ModuleFile &Mod;
-
-public:
- DeclIDComp(ASTReader &Reader, ModuleFile &M) : Reader(Reader), Mod(M) {}
-
- bool operator()(LocalDeclID L, LocalDeclID R) const {
- SourceLocation LHS = getLocation(L);
- SourceLocation RHS = getLocation(R);
- return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
- }
-
- bool operator()(SourceLocation LHS, LocalDeclID R) const {
- SourceLocation RHS = getLocation(R);
- return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
- }
-
- bool operator()(LocalDeclID L, SourceLocation RHS) const {
- SourceLocation LHS = getLocation(L);
- return Reader.getSourceManager().isBeforeInTranslationUnit(LHS, RHS);
- }
-
- SourceLocation getLocation(LocalDeclID ID) const {
- return Reader.getSourceManager().getFileLoc(
- Reader.getSourceLocationForDeclID(Reader.getGlobalDeclID(Mod, ID)));
- }
-};
-
-} // namespace
-
-void ASTReader::FindFileRegionDecls(FileID File,
- unsigned Offset, unsigned Length,
- SmallVectorImpl<Decl *> &Decls) {
- SourceManager &SM = getSourceManager();
-
- llvm::DenseMap<FileID, FileDeclsInfo>::iterator I = FileDeclIDs.find(File);
- if (I == FileDeclIDs.end())
- return;
-
- FileDeclsInfo &DInfo = I->second;
- if (DInfo.Decls.empty())
- return;
-
- SourceLocation
- BeginLoc = SM.getLocForStartOfFile(File).getLocWithOffset(Offset);
- SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length);
-
- DeclIDComp DIDComp(*this, *DInfo.Mod);
- ArrayRef<serialization::LocalDeclID>::iterator
- BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
- BeginLoc, DIDComp);
- if (BeginIt != DInfo.Decls.begin())
- --BeginIt;
-
- // If we are pointing at a top-level decl inside an objc container, we need
- // to backtrack until we find it otherwise we will fail to report that the
- // region overlaps with an objc container.
- while (BeginIt != DInfo.Decls.begin() &&
- GetDecl(getGlobalDeclID(*DInfo.Mod, *BeginIt))
- ->isTopLevelDeclInObjCContainer())
- --BeginIt;
-
- ArrayRef<serialization::LocalDeclID>::iterator
- EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(),
- EndLoc, DIDComp);
- if (EndIt != DInfo.Decls.end())
- ++EndIt;
-
- for (ArrayRef<serialization::LocalDeclID>::iterator
- DIt = BeginIt; DIt != EndIt; ++DIt)
- Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt)));
-}
-
-bool
-ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
- DeclarationName Name) {
- assert(DC->hasExternalVisibleStorage() && DC == DC->getPrimaryContext() &&
- "DeclContext has no visible decls in storage");
- if (!Name)
- return false;
-
- auto It = Lookups.find(DC);
- if (It == Lookups.end())
- return false;
-
- Deserializing LookupResults(this);
-
- // Load the list of declarations.
- SmallVector<NamedDecl *, 64> Decls;
- for (DeclID ID : It->second.Table.find(Name)) {
- NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
- if (ND->getDeclName() == Name)
- Decls.push_back(ND);
- }
-
- ++NumVisibleDeclContextsRead;
- SetExternalVisibleDeclsForName(DC, Name, Decls);
- return !Decls.empty();
-}
-
-void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) {
- if (!DC->hasExternalVisibleStorage())
- return;
-
- auto It = Lookups.find(DC);
- assert(It != Lookups.end() &&
- "have external visible storage but no lookup tables");
-
- DeclsMap Decls;
-
- for (DeclID ID : It->second.Table.findAll()) {
- NamedDecl *ND = cast<NamedDecl>(GetDecl(ID));
- Decls[ND->getDeclName()].push_back(ND);
- }
-
- ++NumVisibleDeclContextsRead;
-
- for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
- SetExternalVisibleDeclsForName(DC, I->first, I->second);
- }
- const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false);
-}
-
-const serialization::reader::DeclContextLookupTable *
-ASTReader::getLoadedLookupTables(DeclContext *Primary) const {
- auto I = Lookups.find(Primary);
- return I == Lookups.end() ? nullptr : &I->second;
-}
-
-/// Under non-PCH compilation the consumer receives the objc methods
-/// before receiving the implementation, and codegen depends on this.
-/// We simulate this by deserializing and passing to consumer the methods of the
-/// implementation before passing the deserialized implementation decl.
-static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
- ASTConsumer *Consumer) {
- assert(ImplD && Consumer);
-
- for (auto *I : ImplD->methods())
- Consumer->HandleInterestingDecl(DeclGroupRef(I));
-
- Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
-}
-
-void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
- if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
- PassObjCImplDeclToConsumer(ImplD, Consumer);
- else
- Consumer->HandleInterestingDecl(DeclGroupRef(D));
-}
-
-void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
- this->Consumer = Consumer;
-
- if (Consumer)
- PassInterestingDeclsToConsumer();
-
- if (DeserializationListener)
- DeserializationListener->ReaderInitialized(this);
-}
-
-void ASTReader::PrintStats() {
- std::fprintf(stderr, "*** AST File Statistics:\n");
-
- unsigned NumTypesLoaded
- = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
- QualType());
- unsigned NumDeclsLoaded
- = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
- (Decl *)nullptr);
- unsigned NumIdentifiersLoaded
- = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
- IdentifiersLoaded.end(),
- (IdentifierInfo *)nullptr);
- unsigned NumMacrosLoaded
- = MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
- MacrosLoaded.end(),
- (MacroInfo *)nullptr);
- unsigned NumSelectorsLoaded
- = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
- SelectorsLoaded.end(),
- Selector());
-
- if (unsigned TotalNumSLocEntries = getTotalNumSLocs())
- std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
- NumSLocEntriesRead, TotalNumSLocEntries,
- ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
- if (!TypesLoaded.empty())
- std::fprintf(stderr, " %u/%u types read (%f%%)\n",
- NumTypesLoaded, (unsigned)TypesLoaded.size(),
- ((float)NumTypesLoaded/TypesLoaded.size() * 100));
- if (!DeclsLoaded.empty())
- std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
- NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
- ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
- if (!IdentifiersLoaded.empty())
- std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
- NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
- ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
- if (!MacrosLoaded.empty())
- std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
- NumMacrosLoaded, (unsigned)MacrosLoaded.size(),
- ((float)NumMacrosLoaded/MacrosLoaded.size() * 100));
- if (!SelectorsLoaded.empty())
- std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
- NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
- ((float)NumSelectorsLoaded/SelectorsLoaded.size() * 100));
- if (TotalNumStatements)
- std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
- NumStatementsRead, TotalNumStatements,
- ((float)NumStatementsRead/TotalNumStatements * 100));
- if (TotalNumMacros)
- std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
- NumMacrosRead, TotalNumMacros,
- ((float)NumMacrosRead/TotalNumMacros * 100));
- if (TotalLexicalDeclContexts)
- std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
- NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
- ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
- * 100));
- if (TotalVisibleDeclContexts)
- std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
- NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
- ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
- * 100));
- if (TotalNumMethodPoolEntries)
- std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
- NumMethodPoolEntriesRead, TotalNumMethodPoolEntries,
- ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries
- * 100));
- if (NumMethodPoolLookups)
- std::fprintf(stderr, " %u/%u method pool lookups succeeded (%f%%)\n",
- NumMethodPoolHits, NumMethodPoolLookups,
- ((float)NumMethodPoolHits/NumMethodPoolLookups * 100.0));
- if (NumMethodPoolTableLookups)
- std::fprintf(stderr, " %u/%u method pool table lookups succeeded (%f%%)\n",
- NumMethodPoolTableHits, NumMethodPoolTableLookups,
- ((float)NumMethodPoolTableHits/NumMethodPoolTableLookups
- * 100.0));
- if (NumIdentifierLookupHits)
- std::fprintf(stderr,
- " %u / %u identifier table lookups succeeded (%f%%)\n",
- NumIdentifierLookupHits, NumIdentifierLookups,
- (double)NumIdentifierLookupHits*100.0/NumIdentifierLookups);
-
- if (GlobalIndex) {
- std::fprintf(stderr, "\n");
- GlobalIndex->printStats();
- }
-
- std::fprintf(stderr, "\n");
- dump();
- std::fprintf(stderr, "\n");
-}
-
-template<typename Key, typename ModuleFile, unsigned InitialCapacity>
-LLVM_DUMP_METHOD static void
-dumpModuleIDMap(StringRef Name,
- const ContinuousRangeMap<Key, ModuleFile *,
- InitialCapacity> &Map) {
- if (Map.begin() == Map.end())
- return;
-
- using MapType = ContinuousRangeMap<Key, ModuleFile *, InitialCapacity>;
-
- llvm::errs() << Name << ":\n";
- for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
- I != IEnd; ++I) {
- llvm::errs() << " " << I->first << " -> " << I->second->FileName
- << "\n";
- }
-}
-
-LLVM_DUMP_METHOD void ASTReader::dump() {
- llvm::errs() << "*** PCH/ModuleFile Remappings:\n";
- dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);
- dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);
- dumpModuleIDMap("Global type map", GlobalTypeMap);
- dumpModuleIDMap("Global declaration map", GlobalDeclMap);
- dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
- dumpModuleIDMap("Global macro map", GlobalMacroMap);
- dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
- dumpModuleIDMap("Global selector map", GlobalSelectorMap);
- dumpModuleIDMap("Global preprocessed entity map",
- GlobalPreprocessedEntityMap);
-
- llvm::errs() << "\n*** PCH/Modules Loaded:";
- for (ModuleFile &M : ModuleMgr)
- M.dump();
-}
-
-/// Return the amount of memory used by memory buffers, breaking down
-/// by heap-backed versus mmap'ed memory.
-void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
- for (ModuleFile &I : ModuleMgr) {
- if (llvm::MemoryBuffer *buf = I.Buffer) {
- size_t bytes = buf->getBufferSize();
- switch (buf->getBufferKind()) {
- case llvm::MemoryBuffer::MemoryBuffer_Malloc:
- sizes.malloc_bytes += bytes;
- break;
- case llvm::MemoryBuffer::MemoryBuffer_MMap:
- sizes.mmap_bytes += bytes;
- break;
- }
- }
- }
-}
-
-void ASTReader::InitializeSema(Sema &S) {
- SemaObj = &S;
- S.addExternalSource(this);
-
- // Makes sure any declarations that were deserialized "too early"
- // still get added to the identifier's declaration chains.
- for (uint64_t ID : PreloadedDeclIDs) {
- NamedDecl *D = cast<NamedDecl>(GetDecl(ID));
- pushExternalDeclIntoScope(D, D->getDeclName());
- }
- PreloadedDeclIDs.clear();
-
- // FIXME: What happens if these are changed by a module import?
- if (!FPPragmaOptions.empty()) {
- assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
- SemaObj->FPFeatures = FPOptions(FPPragmaOptions[0]);
- }
-
- SemaObj->OpenCLFeatures.copy(OpenCLExtensions);
- SemaObj->OpenCLTypeExtMap = OpenCLTypeExtMap;
- SemaObj->OpenCLDeclExtMap = OpenCLDeclExtMap;
-
- UpdateSema();
-}
-
-void ASTReader::UpdateSema() {
- assert(SemaObj && "no Sema to update");
-
- // Load the offsets of the declarations that Sema references.
- // They will be lazily deserialized when needed.
- if (!SemaDeclRefs.empty()) {
- assert(SemaDeclRefs.size() % 3 == 0);
- for (unsigned I = 0; I != SemaDeclRefs.size(); I += 3) {
- if (!SemaObj->StdNamespace)
- SemaObj->StdNamespace = SemaDeclRefs[I];
- if (!SemaObj->StdBadAlloc)
- SemaObj->StdBadAlloc = SemaDeclRefs[I+1];
- if (!SemaObj->StdAlignValT)
- SemaObj->StdAlignValT = SemaDeclRefs[I+2];
- }
- SemaDeclRefs.clear();
- }
-
- // Update the state of pragmas. Use the same API as if we had encountered the
- // pragma in the source.
- if(OptimizeOffPragmaLocation.isValid())
- SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation);
- if (PragmaMSStructState != -1)
- SemaObj->ActOnPragmaMSStruct((PragmaMSStructKind)PragmaMSStructState);
- if (PointersToMembersPragmaLocation.isValid()) {
- SemaObj->ActOnPragmaMSPointersToMembers(
- (LangOptions::PragmaMSPointersToMembersKind)
- PragmaMSPointersToMembersState,
- PointersToMembersPragmaLocation);
- }
- SemaObj->ForceCUDAHostDeviceDepth = ForceCUDAHostDeviceDepth;
-
- if (PragmaPackCurrentValue) {
- // The bottom of the stack might have a default value. It must be adjusted
- // to the current value to ensure that the packing state is preserved after
- // popping entries that were included/imported from a PCH/module.
- bool DropFirst = false;
- if (!PragmaPackStack.empty() &&
- PragmaPackStack.front().Location.isInvalid()) {
- assert(PragmaPackStack.front().Value == SemaObj->PackStack.DefaultValue &&
- "Expected a default alignment value");
- SemaObj->PackStack.Stack.emplace_back(
- PragmaPackStack.front().SlotLabel, SemaObj->PackStack.CurrentValue,
- SemaObj->PackStack.CurrentPragmaLocation,
- PragmaPackStack.front().PushLocation);
- DropFirst = true;
- }
- for (const auto &Entry :
- llvm::makeArrayRef(PragmaPackStack).drop_front(DropFirst ? 1 : 0))
- SemaObj->PackStack.Stack.emplace_back(Entry.SlotLabel, Entry.Value,
- Entry.Location, Entry.PushLocation);
- if (PragmaPackCurrentLocation.isInvalid()) {
- assert(*PragmaPackCurrentValue == SemaObj->PackStack.DefaultValue &&
- "Expected a default alignment value");
- // Keep the current values.
- } else {
- SemaObj->PackStack.CurrentValue = *PragmaPackCurrentValue;
- SemaObj->PackStack.CurrentPragmaLocation = PragmaPackCurrentLocation;
- }
- }
-}
-
-IdentifierInfo *ASTReader::get(StringRef Name) {
- // Note that we are loading an identifier.
- Deserializing AnIdentifier(this);
-
- IdentifierLookupVisitor Visitor(Name, /*PriorGeneration=*/0,
- NumIdentifierLookups,
- NumIdentifierLookupHits);
-
- // We don't need to do identifier table lookups in C++ modules (we preload
- // all interesting declarations, and don't need to use the scope for name
- // lookups). Perform the lookup in PCH files, though, since we don't build
- // a complete initial identifier table if we're carrying on from a PCH.
- if (PP.getLangOpts().CPlusPlus) {
- for (auto F : ModuleMgr.pch_modules())
- if (Visitor(*F))
- break;
- } else {
- // If there is a global index, look there first to determine which modules
- // provably do not have any results for this identifier.
- GlobalModuleIndex::HitSet Hits;
- GlobalModuleIndex::HitSet *HitsPtr = nullptr;
- if (!loadGlobalIndex()) {
- if (GlobalIndex->lookupIdentifier(Name, Hits)) {
- HitsPtr = &Hits;
- }
- }
-
- ModuleMgr.visit(Visitor, HitsPtr);
- }
-
- IdentifierInfo *II = Visitor.getIdentifierInfo();
- markIdentifierUpToDate(II);
- return II;
-}
-
-namespace clang {
-
- /// An identifier-lookup iterator that enumerates all of the
- /// identifiers stored within a set of AST files.
- class ASTIdentifierIterator : public IdentifierIterator {
- /// The AST reader whose identifiers are being enumerated.
- const ASTReader &Reader;
-
- /// The current index into the chain of AST files stored in
- /// the AST reader.
- unsigned Index;
-
- /// The current position within the identifier lookup table
- /// of the current AST file.
- ASTIdentifierLookupTable::key_iterator Current;
-
- /// The end position within the identifier lookup table of
- /// the current AST file.
- ASTIdentifierLookupTable::key_iterator End;
-
- /// Whether to skip any modules in the ASTReader.
- bool SkipModules;
-
- public:
- explicit ASTIdentifierIterator(const ASTReader &Reader,
- bool SkipModules = false);
-
- StringRef Next() override;
- };
-
-} // namespace clang
-
-ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader,
- bool SkipModules)
- : Reader(Reader), Index(Reader.ModuleMgr.size()), SkipModules(SkipModules) {
-}
-
-StringRef ASTIdentifierIterator::Next() {
- while (Current == End) {
- // If we have exhausted all of our AST files, we're done.
- if (Index == 0)
- return StringRef();
-
- --Index;
- ModuleFile &F = Reader.ModuleMgr[Index];
- if (SkipModules && F.isModule())
- continue;
-
- ASTIdentifierLookupTable *IdTable =
- (ASTIdentifierLookupTable *)F.IdentifierLookupTable;
- Current = IdTable->key_begin();
- End = IdTable->key_end();
- }
-
- // We have any identifiers remaining in the current AST file; return
- // the next one.
- StringRef Result = *Current;
- ++Current;
- return Result;
-}
-
-namespace {
-
-/// A utility for appending two IdentifierIterators.
-class ChainedIdentifierIterator : public IdentifierIterator {
- std::unique_ptr<IdentifierIterator> Current;
- std::unique_ptr<IdentifierIterator> Queued;
-
-public:
- ChainedIdentifierIterator(std::unique_ptr<IdentifierIterator> First,
- std::unique_ptr<IdentifierIterator> Second)
- : Current(std::move(First)), Queued(std::move(Second)) {}
-
- StringRef Next() override {
- if (!Current)
- return StringRef();
-
- StringRef result = Current->Next();
- if (!result.empty())
- return result;
-
- // Try the queued iterator, which may itself be empty.
- Current.reset();
- std::swap(Current, Queued);
- return Next();
- }
-};
-
-} // namespace
-
-IdentifierIterator *ASTReader::getIdentifiers() {
- if (!loadGlobalIndex()) {
- std::unique_ptr<IdentifierIterator> ReaderIter(
- new ASTIdentifierIterator(*this, /*SkipModules=*/true));
- std::unique_ptr<IdentifierIterator> ModulesIter(
- GlobalIndex->createIdentifierIterator());
- return new ChainedIdentifierIterator(std::move(ReaderIter),
- std::move(ModulesIter));
- }
-
- return new ASTIdentifierIterator(*this);
-}
-
-namespace clang {
-namespace serialization {
-
- class ReadMethodPoolVisitor {
- ASTReader &Reader;
- Selector Sel;
- unsigned PriorGeneration;
- unsigned InstanceBits = 0;
- unsigned FactoryBits = 0;
- bool InstanceHasMoreThanOneDecl = false;
- bool FactoryHasMoreThanOneDecl = false;
- SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
- SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
-
- public:
- ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,
- unsigned PriorGeneration)
- : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) {}
-
- bool operator()(ModuleFile &M) {
- if (!M.SelectorLookupTable)
- return false;
-
- // If we've already searched this module file, skip it now.
- if (M.Generation <= PriorGeneration)
- return true;
-
- ++Reader.NumMethodPoolTableLookups;
- ASTSelectorLookupTable *PoolTable
- = (ASTSelectorLookupTable*)M.SelectorLookupTable;
- ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
- if (Pos == PoolTable->end())
- return false;
-
- ++Reader.NumMethodPoolTableHits;
- ++Reader.NumSelectorsRead;
- // FIXME: Not quite happy with the statistics here. We probably should
- // disable this tracking when called via LoadSelector.
- // Also, should entries without methods count as misses?
- ++Reader.NumMethodPoolEntriesRead;
- ASTSelectorLookupTrait::data_type Data = *Pos;
- if (Reader.DeserializationListener)
- Reader.DeserializationListener->SelectorRead(Data.ID, Sel);
-
- InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
- FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
- InstanceBits = Data.InstanceBits;
- FactoryBits = Data.FactoryBits;
- InstanceHasMoreThanOneDecl = Data.InstanceHasMoreThanOneDecl;
- FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl;
- return true;
- }
-
- /// Retrieve the instance methods found by this visitor.
- ArrayRef<ObjCMethodDecl *> getInstanceMethods() const {
- return InstanceMethods;
- }
-
- /// Retrieve the instance methods found by this visitor.
- ArrayRef<ObjCMethodDecl *> getFactoryMethods() const {
- return FactoryMethods;
- }
-
- unsigned getInstanceBits() const { return InstanceBits; }
- unsigned getFactoryBits() const { return FactoryBits; }
-
- bool instanceHasMoreThanOneDecl() const {
- return InstanceHasMoreThanOneDecl;
- }
-
- bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; }
- };
-
-} // namespace serialization
-} // namespace clang
-
-/// Add the given set of methods to the method list.
-static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods,
- ObjCMethodList &List) {
- for (unsigned I = 0, N = Methods.size(); I != N; ++I) {
- S.addMethodToGlobalList(&List, Methods[I]);
- }
-}
-
-void ASTReader::ReadMethodPool(Selector Sel) {
- // Get the selector generation and update it to the current generation.
- unsigned &Generation = SelectorGeneration[Sel];
- unsigned PriorGeneration = Generation;
- Generation = getGeneration();
- SelectorOutOfDate[Sel] = false;
-
- // Search for methods defined with this selector.
- ++NumMethodPoolLookups;
- ReadMethodPoolVisitor Visitor(*this, Sel, PriorGeneration);
- ModuleMgr.visit(Visitor);
-
- if (Visitor.getInstanceMethods().empty() &&
- Visitor.getFactoryMethods().empty())
- return;
-
- ++NumMethodPoolHits;
-
- if (!getSema())
- return;
-
- Sema &S = *getSema();
- Sema::GlobalMethodPool::iterator Pos
- = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first;
-
- Pos->second.first.setBits(Visitor.getInstanceBits());
- Pos->second.first.setHasMoreThanOneDecl(Visitor.instanceHasMoreThanOneDecl());
- Pos->second.second.setBits(Visitor.getFactoryBits());
- Pos->second.second.setHasMoreThanOneDecl(Visitor.factoryHasMoreThanOneDecl());
-
- // Add methods to the global pool *after* setting hasMoreThanOneDecl, since
- // when building a module we keep every method individually and may need to
- // update hasMoreThanOneDecl as we add the methods.
- addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);
- addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);
-}
-
-void ASTReader::updateOutOfDateSelector(Selector Sel) {
- if (SelectorOutOfDate[Sel])
- ReadMethodPool(Sel);
-}
-
-void ASTReader::ReadKnownNamespaces(
- SmallVectorImpl<NamespaceDecl *> &Namespaces) {
- Namespaces.clear();
-
- for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {
- if (NamespaceDecl *Namespace
- = dyn_cast_or_null<NamespaceDecl>(GetDecl(KnownNamespaces[I])))
- Namespaces.push_back(Namespace);
- }
-}
-
-void ASTReader::ReadUndefinedButUsed(
- llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
- for (unsigned Idx = 0, N = UndefinedButUsed.size(); Idx != N;) {
- NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedButUsed[Idx++]));
- SourceLocation Loc =
- SourceLocation::getFromRawEncoding(UndefinedButUsed[Idx++]);
- Undefined.insert(std::make_pair(D, Loc));
- }
-}
-
-void ASTReader::ReadMismatchingDeleteExpressions(llvm::MapVector<
- FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &
- Exprs) {
- for (unsigned Idx = 0, N = DelayedDeleteExprs.size(); Idx != N;) {
- FieldDecl *FD = cast<FieldDecl>(GetDecl(DelayedDeleteExprs[Idx++]));
- uint64_t Count = DelayedDeleteExprs[Idx++];
- for (uint64_t C = 0; C < Count; ++C) {
- SourceLocation DeleteLoc =
- SourceLocation::getFromRawEncoding(DelayedDeleteExprs[Idx++]);
- const bool IsArrayForm = DelayedDeleteExprs[Idx++];
- Exprs[FD].push_back(std::make_pair(DeleteLoc, IsArrayForm));
- }
- }
-}
-
-void ASTReader::ReadTentativeDefinitions(
- SmallVectorImpl<VarDecl *> &TentativeDefs) {
- for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
- VarDecl *Var = dyn_cast_or_null<VarDecl>(GetDecl(TentativeDefinitions[I]));
- if (Var)
- TentativeDefs.push_back(Var);
- }
- TentativeDefinitions.clear();
-}
-
-void ASTReader::ReadUnusedFileScopedDecls(
- SmallVectorImpl<const DeclaratorDecl *> &Decls) {
- for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) {
- DeclaratorDecl *D
- = dyn_cast_or_null<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I]));
- if (D)
- Decls.push_back(D);
- }
- UnusedFileScopedDecls.clear();
-}
-
-void ASTReader::ReadDelegatingConstructors(
- SmallVectorImpl<CXXConstructorDecl *> &Decls) {
- for (unsigned I = 0, N = DelegatingCtorDecls.size(); I != N; ++I) {
- CXXConstructorDecl *D
- = dyn_cast_or_null<CXXConstructorDecl>(GetDecl(DelegatingCtorDecls[I]));
- if (D)
- Decls.push_back(D);
- }
- DelegatingCtorDecls.clear();
-}
-
-void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {
- for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I) {
- TypedefNameDecl *D
- = dyn_cast_or_null<TypedefNameDecl>(GetDecl(ExtVectorDecls[I]));
- if (D)
- Decls.push_back(D);
- }
- ExtVectorDecls.clear();
-}
-
-void ASTReader::ReadUnusedLocalTypedefNameCandidates(
- llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
- for (unsigned I = 0, N = UnusedLocalTypedefNameCandidates.size(); I != N;
- ++I) {
- TypedefNameDecl *D = dyn_cast_or_null<TypedefNameDecl>(
- GetDecl(UnusedLocalTypedefNameCandidates[I]));
- if (D)
- Decls.insert(D);
- }
- UnusedLocalTypedefNameCandidates.clear();
-}
-
-void ASTReader::ReadReferencedSelectors(
- SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) {
- if (ReferencedSelectorsData.empty())
- return;
-
- // If there are @selector references added them to its pool. This is for
- // implementation of -Wselector.
- unsigned int DataSize = ReferencedSelectorsData.size()-1;
- unsigned I = 0;
- while (I < DataSize) {
- Selector Sel = DecodeSelector(ReferencedSelectorsData[I++]);
- SourceLocation SelLoc
- = SourceLocation::getFromRawEncoding(ReferencedSelectorsData[I++]);
- Sels.push_back(std::make_pair(Sel, SelLoc));
- }
- ReferencedSelectorsData.clear();
-}
-
-void ASTReader::ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WeakIDs) {
- if (WeakUndeclaredIdentifiers.empty())
- return;
-
- for (unsigned I = 0, N = WeakUndeclaredIdentifiers.size(); I < N; /*none*/) {
- IdentifierInfo *WeakId
- = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
- IdentifierInfo *AliasId
- = DecodeIdentifierInfo(WeakUndeclaredIdentifiers[I++]);
- SourceLocation Loc
- = SourceLocation::getFromRawEncoding(WeakUndeclaredIdentifiers[I++]);
- bool Used = WeakUndeclaredIdentifiers[I++];
- WeakInfo WI(AliasId, Loc);
- WI.setUsed(Used);
- WeakIDs.push_back(std::make_pair(WeakId, WI));
- }
- WeakUndeclaredIdentifiers.clear();
-}
-
-void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {
- for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) {
- ExternalVTableUse VT;
- VT.Record = dyn_cast_or_null<CXXRecordDecl>(GetDecl(VTableUses[Idx++]));
- VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]);
- VT.DefinitionRequired = VTableUses[Idx++];
- VTables.push_back(VT);
- }
-
- VTableUses.clear();
-}
-
-void ASTReader::ReadPendingInstantiations(
- SmallVectorImpl<std::pair<ValueDecl *, SourceLocation>> &Pending) {
- for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) {
- ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++]));
- SourceLocation Loc
- = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]);
-
- Pending.push_back(std::make_pair(D, Loc));
- }
- PendingInstantiations.clear();
-}
-
-void ASTReader::ReadLateParsedTemplates(
- llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
- &LPTMap) {
- for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N;
- /* In loop */) {
- FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++]));
-
- auto LT = llvm::make_unique<LateParsedTemplate>();
- LT->D = GetDecl(LateParsedTemplates[Idx++]);
-
- ModuleFile *F = getOwningModuleFile(LT->D);
- assert(F && "No module");
-
- unsigned TokN = LateParsedTemplates[Idx++];
- LT->Toks.reserve(TokN);
- for (unsigned T = 0; T < TokN; ++T)
- LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx));
-
- LPTMap.insert(std::make_pair(FD, std::move(LT)));
- }
-
- LateParsedTemplates.clear();
-}
-
-void ASTReader::LoadSelector(Selector Sel) {
- // It would be complicated to avoid reading the methods anyway. So don't.
- ReadMethodPool(Sel);
-}
-
-void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) {
- assert(ID && "Non-zero identifier ID required");
- assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
- IdentifiersLoaded[ID - 1] = II;
- if (DeserializationListener)
- DeserializationListener->IdentifierRead(ID, II);
-}
-
-/// Set the globally-visible declarations associated with the given
-/// identifier.
-///
-/// If the AST reader is currently in a state where the given declaration IDs
-/// cannot safely be resolved, they are queued until it is safe to resolve
-/// them.
-///
-/// \param II an IdentifierInfo that refers to one or more globally-visible
-/// declarations.
-///
-/// \param DeclIDs the set of declaration IDs with the name @p II that are
-/// visible at global scope.
-///
-/// \param Decls if non-null, this vector will be populated with the set of
-/// deserialized declarations. These declarations will not be pushed into
-/// scope.
-void
-ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
- const SmallVectorImpl<uint32_t> &DeclIDs,
- SmallVectorImpl<Decl *> *Decls) {
- if (NumCurrentElementsDeserializing && !Decls) {
- PendingIdentifierInfos[II].append(DeclIDs.begin(), DeclIDs.end());
- return;
- }
-
- for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
- if (!SemaObj) {
- // Queue this declaration so that it will be added to the
- // translation unit scope and identifier's declaration chain
- // once a Sema object is known.
- PreloadedDeclIDs.push_back(DeclIDs[I]);
- continue;
- }
-
- NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
-
- // If we're simply supposed to record the declarations, do so now.
- if (Decls) {
- Decls->push_back(D);
- continue;
- }
-
- // Introduce this declaration into the translation-unit scope
- // and add it to the declaration chain for this identifier, so
- // that (unqualified) name lookup will find it.
- pushExternalDeclIntoScope(D, II);
- }
-}
-
-IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
- if (ID == 0)
- return nullptr;
-
- if (IdentifiersLoaded.empty()) {
- Error("no identifier table in AST file");
- return nullptr;
- }
-
- ID -= 1;
- if (!IdentifiersLoaded[ID]) {
- GlobalIdentifierMapType::iterator I = GlobalIdentifierMap.find(ID + 1);
- assert(I != GlobalIdentifierMap.end() && "Corrupted global identifier map");
- ModuleFile *M = I->second;
- unsigned Index = ID - M->BaseIdentifierID;
- const char *Str = M->IdentifierTableData + M->IdentifierOffsets[Index];
-
- // All of the strings in the AST file are preceded by a 16-bit length.
- // Extract that 16-bit length to avoid having to execute strlen().
- // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
- // unsigned integers. This is important to avoid integer overflow when
- // we cast them to 'unsigned'.
- const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
- unsigned StrLen = (((unsigned) StrLenPtr[0])
- | (((unsigned) StrLenPtr[1]) << 8)) - 1;
- auto &II = PP.getIdentifierTable().get(StringRef(Str, StrLen));
- IdentifiersLoaded[ID] = &II;
- markIdentifierFromAST(*this, II);
- if (DeserializationListener)
- DeserializationListener->IdentifierRead(ID + 1, &II);
- }
-
- return IdentifiersLoaded[ID];
-}
-
-IdentifierInfo *ASTReader::getLocalIdentifier(ModuleFile &M, unsigned LocalID) {
- return DecodeIdentifierInfo(getGlobalIdentifierID(M, LocalID));
-}
-
-IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
- if (LocalID < NUM_PREDEF_IDENT_IDS)
- return LocalID;
-
- if (!M.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(M);
-
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS);
- assert(I != M.IdentifierRemap.end()
- && "Invalid index into identifier index remap");
-
- return LocalID + I->second;
-}
-
-MacroInfo *ASTReader::getMacro(MacroID ID) {
- if (ID == 0)
- return nullptr;
-
- if (MacrosLoaded.empty()) {
- Error("no macro table in AST file");
- return nullptr;
- }
-
- ID -= NUM_PREDEF_MACRO_IDS;
- if (!MacrosLoaded[ID]) {
- GlobalMacroMapType::iterator I
- = GlobalMacroMap.find(ID + NUM_PREDEF_MACRO_IDS);
- assert(I != GlobalMacroMap.end() && "Corrupted global macro map");
- ModuleFile *M = I->second;
- unsigned Index = ID - M->BaseMacroID;
- MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]);
-
- if (DeserializationListener)
- DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS,
- MacrosLoaded[ID]);
- }
-
- return MacrosLoaded[ID];
-}
-
-MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {
- if (LocalID < NUM_PREDEF_MACRO_IDS)
- return LocalID;
-
- if (!M.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(M);
-
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = M.MacroRemap.find(LocalID - NUM_PREDEF_MACRO_IDS);
- assert(I != M.MacroRemap.end() && "Invalid index into macro index remap");
-
- return LocalID + I->second;
-}
-
-serialization::SubmoduleID
-ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
- if (LocalID < NUM_PREDEF_SUBMODULE_IDS)
- return LocalID;
-
- if (!M.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(M);
-
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);
- assert(I != M.SubmoduleRemap.end()
- && "Invalid index into submodule index remap");
-
- return LocalID + I->second;
-}
-
-Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {
- if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {
- assert(GlobalID == 0 && "Unhandled global submodule ID");
- return nullptr;
- }
-
- if (GlobalID > SubmodulesLoaded.size()) {
- Error("submodule ID out of range in AST file");
- return nullptr;
- }
-
- return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
-}
-
-Module *ASTReader::getModule(unsigned ID) {
- return getSubmodule(ID);
-}
-
-bool ASTReader::DeclIsFromPCHWithObjectFile(const Decl *D) {
- ModuleFile *MF = getOwningModuleFile(D);
- return MF && MF->PCHHasObjectFile;
-}
-
-ModuleFile *ASTReader::getLocalModuleFile(ModuleFile &F, unsigned ID) {
- if (ID & 1) {
- // It's a module, look it up by submodule ID.
- auto I = GlobalSubmoduleMap.find(getGlobalSubmoduleID(F, ID >> 1));
- return I == GlobalSubmoduleMap.end() ? nullptr : I->second;
- } else {
- // It's a prefix (preamble, PCH, ...). Look it up by index.
- unsigned IndexFromEnd = ID >> 1;
- assert(IndexFromEnd && "got reference to unknown module file");
- return getModuleManager().pch_modules().end()[-IndexFromEnd];
- }
-}
-
-unsigned ASTReader::getModuleFileID(ModuleFile *F) {
- if (!F)
- return 1;
-
- // For a file representing a module, use the submodule ID of the top-level
- // module as the file ID. For any other kind of file, the number of such
- // files loaded beforehand will be the same on reload.
- // FIXME: Is this true even if we have an explicit module file and a PCH?
- if (F->isModule())
- return ((F->BaseSubmoduleID + NUM_PREDEF_SUBMODULE_IDS) << 1) | 1;
-
- auto PCHModules = getModuleManager().pch_modules();
- auto I = std::find(PCHModules.begin(), PCHModules.end(), F);
- assert(I != PCHModules.end() && "emitting reference to unknown file");
- return (I - PCHModules.end()) << 1;
-}
-
-llvm::Optional<ExternalASTSource::ASTSourceDescriptor>
-ASTReader::getSourceDescriptor(unsigned ID) {
- if (const Module *M = getSubmodule(ID))
- return ExternalASTSource::ASTSourceDescriptor(*M);
-
- // If there is only a single PCH, return it instead.
- // Chained PCH are not supported.
- const auto &PCHChain = ModuleMgr.pch_modules();
- if (std::distance(std::begin(PCHChain), std::end(PCHChain))) {
- ModuleFile &MF = ModuleMgr.getPrimaryModule();
- StringRef ModuleName = llvm::sys::path::filename(MF.OriginalSourceFileName);
- StringRef FileName = llvm::sys::path::filename(MF.FileName);
- return ASTReader::ASTSourceDescriptor(ModuleName, MF.OriginalDir, FileName,
- MF.Signature);
- }
- return None;
-}
-
-ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(const Decl *FD) {
- auto I = DefinitionSource.find(FD);
- if (I == DefinitionSource.end())
- return EK_ReplyHazy;
- return I->second ? EK_Never : EK_Always;
-}
-
-Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) {
- return DecodeSelector(getGlobalSelectorID(M, LocalID));
-}
-
-Selector ASTReader::DecodeSelector(serialization::SelectorID ID) {
- if (ID == 0)
- return Selector();
-
- if (ID > SelectorsLoaded.size()) {
- Error("selector ID out of range in AST file");
- return Selector();
- }
-
- if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == nullptr) {
- // Load this selector from the selector table.
- GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);
- assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");
- ModuleFile &M = *I->second;
- ASTSelectorLookupTrait Trait(*this, M);
- unsigned Idx = ID - M.BaseSelectorID - NUM_PREDEF_SELECTOR_IDS;
- SelectorsLoaded[ID - 1] =
- Trait.ReadKey(M.SelectorLookupTableData + M.SelectorOffsets[Idx], 0);
- if (DeserializationListener)
- DeserializationListener->SelectorRead(ID, SelectorsLoaded[ID - 1]);
- }
-
- return SelectorsLoaded[ID - 1];
-}
-
-Selector ASTReader::GetExternalSelector(serialization::SelectorID ID) {
- return DecodeSelector(ID);
-}
-
-uint32_t ASTReader::GetNumExternalSelectors() {
- // ID 0 (the null selector) is considered an external selector.
- return getTotalNumSelectors() + 1;
-}
-
-serialization::SelectorID
-ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const {
- if (LocalID < NUM_PREDEF_SELECTOR_IDS)
- return LocalID;
-
- if (!M.ModuleOffsetMap.empty())
- ReadModuleOffsetMap(M);
-
- ContinuousRangeMap<uint32_t, int, 2>::iterator I
- = M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);
- assert(I != M.SelectorRemap.end()
- && "Invalid index into selector index remap");
-
- return LocalID + I->second;
-}
-
-DeclarationName
-ASTReader::ReadDeclarationName(ModuleFile &F,
- const RecordData &Record, unsigned &Idx) {
- ASTContext &Context = getContext();
- DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
- switch (Kind) {
- case DeclarationName::Identifier:
- return DeclarationName(GetIdentifierInfo(F, Record, Idx));
-
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- return DeclarationName(ReadSelector(F, Record, Idx));
-
- case DeclarationName::CXXConstructorName:
- return Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(readType(F, Record, Idx)));
-
- case DeclarationName::CXXDestructorName:
- return Context.DeclarationNames.getCXXDestructorName(
- Context.getCanonicalType(readType(F, Record, Idx)));
-
- case DeclarationName::CXXDeductionGuideName:
- return Context.DeclarationNames.getCXXDeductionGuideName(
- ReadDeclAs<TemplateDecl>(F, Record, Idx));
-
- case DeclarationName::CXXConversionFunctionName:
- return Context.DeclarationNames.getCXXConversionFunctionName(
- Context.getCanonicalType(readType(F, Record, Idx)));
-
- case DeclarationName::CXXOperatorName:
- return Context.DeclarationNames.getCXXOperatorName(
- (OverloadedOperatorKind)Record[Idx++]);
-
- case DeclarationName::CXXLiteralOperatorName:
- return Context.DeclarationNames.getCXXLiteralOperatorName(
- GetIdentifierInfo(F, Record, Idx));
-
- case DeclarationName::CXXUsingDirective:
- return DeclarationName::getUsingDirectiveName();
- }
-
- llvm_unreachable("Invalid NameKind!");
-}
-
-void ASTReader::ReadDeclarationNameLoc(ModuleFile &F,
- DeclarationNameLoc &DNLoc,
- DeclarationName Name,
- const RecordData &Record, unsigned &Idx) {
- switch (Name.getNameKind()) {
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- DNLoc.NamedType.TInfo = GetTypeSourceInfo(F, Record, Idx);
- break;
-
- case DeclarationName::CXXOperatorName:
- DNLoc.CXXOperatorName.BeginOpNameLoc
- = ReadSourceLocation(F, Record, Idx).getRawEncoding();
- DNLoc.CXXOperatorName.EndOpNameLoc
- = ReadSourceLocation(F, Record, Idx).getRawEncoding();
- break;
-
- case DeclarationName::CXXLiteralOperatorName:
- DNLoc.CXXLiteralOperatorName.OpNameLoc
- = ReadSourceLocation(F, Record, Idx).getRawEncoding();
- break;
-
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXUsingDirective:
- case DeclarationName::CXXDeductionGuideName:
- break;
- }
-}
-
-void ASTReader::ReadDeclarationNameInfo(ModuleFile &F,
- DeclarationNameInfo &NameInfo,
- const RecordData &Record, unsigned &Idx) {
- NameInfo.setName(ReadDeclarationName(F, Record, Idx));
- NameInfo.setLoc(ReadSourceLocation(F, Record, Idx));
- DeclarationNameLoc DNLoc;
- ReadDeclarationNameLoc(F, DNLoc, NameInfo.getName(), Record, Idx);
- NameInfo.setInfo(DNLoc);
-}
-
-void ASTReader::ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info,
- const RecordData &Record, unsigned &Idx) {
- Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
- unsigned NumTPLists = Record[Idx++];
- Info.NumTemplParamLists = NumTPLists;
- if (NumTPLists) {
- Info.TemplParamLists =
- new (getContext()) TemplateParameterList *[NumTPLists];
- for (unsigned i = 0; i != NumTPLists; ++i)
- Info.TemplParamLists[i] = ReadTemplateParameterList(F, Record, Idx);
- }
-}
-
-TemplateName
-ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record,
- unsigned &Idx) {
- ASTContext &Context = getContext();
- TemplateName::NameKind Kind = (TemplateName::NameKind)Record[Idx++];
- switch (Kind) {
- case TemplateName::Template:
- return TemplateName(ReadDeclAs<TemplateDecl>(F, Record, Idx));
-
- case TemplateName::OverloadedTemplate: {
- unsigned size = Record[Idx++];
- UnresolvedSet<8> Decls;
- while (size--)
- Decls.addDecl(ReadDeclAs<NamedDecl>(F, Record, Idx));
-
- return Context.getOverloadedTemplateName(Decls.begin(), Decls.end());
- }
-
- case TemplateName::QualifiedTemplate: {
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
- bool hasTemplKeyword = Record[Idx++];
- TemplateDecl *Template = ReadDeclAs<TemplateDecl>(F, Record, Idx);
- return Context.getQualifiedTemplateName(NNS, hasTemplKeyword, Template);
- }
-
- case TemplateName::DependentTemplate: {
- NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx);
- if (Record[Idx++]) // isIdentifier
- return Context.getDependentTemplateName(NNS,
- GetIdentifierInfo(F, Record,
- Idx));
- return Context.getDependentTemplateName(NNS,
- (OverloadedOperatorKind)Record[Idx++]);
- }
-
- case TemplateName::SubstTemplateTemplateParm: {
- TemplateTemplateParmDecl *param
- = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
- if (!param) return TemplateName();
- TemplateName replacement = ReadTemplateName(F, Record, Idx);
- return Context.getSubstTemplateTemplateParm(param, replacement);
- }
-
- case TemplateName::SubstTemplateTemplateParmPack: {
- TemplateTemplateParmDecl *Param
- = ReadDeclAs<TemplateTemplateParmDecl>(F, Record, Idx);
- if (!Param)
- return TemplateName();
-
- TemplateArgument ArgPack = ReadTemplateArgument(F, Record, Idx);
- if (ArgPack.getKind() != TemplateArgument::Pack)
- return TemplateName();
-
- return Context.getSubstTemplateTemplateParmPack(Param, ArgPack);
- }
- }
-
- llvm_unreachable("Unhandled template name kind!");
-}
-
-TemplateArgument ASTReader::ReadTemplateArgument(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx,
- bool Canonicalize) {
- ASTContext &Context = getContext();
- if (Canonicalize) {
- // The caller wants a canonical template argument. Sometimes the AST only
- // wants template arguments in canonical form (particularly as the template
- // argument lists of template specializations) so ensure we preserve that
- // canonical form across serialization.
- TemplateArgument Arg = ReadTemplateArgument(F, Record, Idx, false);
- return Context.getCanonicalTemplateArgument(Arg);
- }
-
- TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++];
- switch (Kind) {
- case TemplateArgument::Null:
- return TemplateArgument();
- case TemplateArgument::Type:
- return TemplateArgument(readType(F, Record, Idx));
- case TemplateArgument::Declaration: {
- ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx);
- return TemplateArgument(D, readType(F, Record, Idx));
- }
- case TemplateArgument::NullPtr:
- return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true);
- case TemplateArgument::Integral: {
- llvm::APSInt Value = ReadAPSInt(Record, Idx);
- QualType T = readType(F, Record, Idx);
- return TemplateArgument(Context, Value, T);
- }
- case TemplateArgument::Template:
- return TemplateArgument(ReadTemplateName(F, Record, Idx));
- case TemplateArgument::TemplateExpansion: {
- TemplateName Name = ReadTemplateName(F, Record, Idx);
- Optional<unsigned> NumTemplateExpansions;
- if (unsigned NumExpansions = Record[Idx++])
- NumTemplateExpansions = NumExpansions - 1;
- return TemplateArgument(Name, NumTemplateExpansions);
- }
- case TemplateArgument::Expression:
- return TemplateArgument(ReadExpr(F));
- case TemplateArgument::Pack: {
- unsigned NumArgs = Record[Idx++];
- TemplateArgument *Args = new (Context) TemplateArgument[NumArgs];
- for (unsigned I = 0; I != NumArgs; ++I)
- Args[I] = ReadTemplateArgument(F, Record, Idx);
- return TemplateArgument(llvm::makeArrayRef(Args, NumArgs));
- }
- }
-
- llvm_unreachable("Unhandled template argument kind!");
-}
-
-TemplateParameterList *
-ASTReader::ReadTemplateParameterList(ModuleFile &F,
- const RecordData &Record, unsigned &Idx) {
- SourceLocation TemplateLoc = ReadSourceLocation(F, Record, Idx);
- SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Idx);
- SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Idx);
-
- unsigned NumParams = Record[Idx++];
- SmallVector<NamedDecl *, 16> Params;
- Params.reserve(NumParams);
- while (NumParams--)
- Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));
-
- // TODO: Concepts
- TemplateParameterList *TemplateParams = TemplateParameterList::Create(
- getContext(), TemplateLoc, LAngleLoc, Params, RAngleLoc, nullptr);
- return TemplateParams;
-}
-
-void
-ASTReader::
-ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
- ModuleFile &F, const RecordData &Record,
- unsigned &Idx, bool Canonicalize) {
- unsigned NumTemplateArgs = Record[Idx++];
- TemplArgs.reserve(NumTemplateArgs);
- while (NumTemplateArgs--)
- TemplArgs.push_back(ReadTemplateArgument(F, Record, Idx, Canonicalize));
-}
-
-/// Read a UnresolvedSet structure.
-void ASTReader::ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set,
- const RecordData &Record, unsigned &Idx) {
- unsigned NumDecls = Record[Idx++];
- Set.reserve(getContext(), NumDecls);
- while (NumDecls--) {
- DeclID ID = ReadDeclID(F, Record, Idx);
- AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
- Set.addLazyDecl(getContext(), ID, AS);
- }
-}
-
-CXXBaseSpecifier
-ASTReader::ReadCXXBaseSpecifier(ModuleFile &F,
- const RecordData &Record, unsigned &Idx) {
- bool isVirtual = static_cast<bool>(Record[Idx++]);
- bool isBaseOfClass = static_cast<bool>(Record[Idx++]);
- AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]);
- bool inheritConstructors = static_cast<bool>(Record[Idx++]);
- TypeSourceInfo *TInfo = GetTypeSourceInfo(F, Record, Idx);
- SourceRange Range = ReadSourceRange(F, Record, Idx);
- SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Idx);
- CXXBaseSpecifier Result(Range, isVirtual, isBaseOfClass, AS, TInfo,
- EllipsisLoc);
- Result.setInheritConstructors(inheritConstructors);
- return Result;
-}
-
-CXXCtorInitializer **
-ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
- unsigned &Idx) {
- ASTContext &Context = getContext();
- unsigned NumInitializers = Record[Idx++];
- assert(NumInitializers && "wrote ctor initializers but have no inits");
- auto **CtorInitializers = new (Context) CXXCtorInitializer*[NumInitializers];
- for (unsigned i = 0; i != NumInitializers; ++i) {
- TypeSourceInfo *TInfo = nullptr;
- bool IsBaseVirtual = false;
- FieldDecl *Member = nullptr;
- IndirectFieldDecl *IndirectMember = nullptr;
-
- CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
- switch (Type) {
- case CTOR_INITIALIZER_BASE:
- TInfo = GetTypeSourceInfo(F, Record, Idx);
- IsBaseVirtual = Record[Idx++];
- break;
-
- case CTOR_INITIALIZER_DELEGATING:
- TInfo = GetTypeSourceInfo(F, Record, Idx);
- break;
-
- case CTOR_INITIALIZER_MEMBER:
- Member = ReadDeclAs<FieldDecl>(F, Record, Idx);
- break;
-
- case CTOR_INITIALIZER_INDIRECT_MEMBER:
- IndirectMember = ReadDeclAs<IndirectFieldDecl>(F, Record, Idx);
- break;
- }
-
- SourceLocation MemberOrEllipsisLoc = ReadSourceLocation(F, Record, Idx);
- Expr *Init = ReadExpr(F);
- SourceLocation LParenLoc = ReadSourceLocation(F, Record, Idx);
- SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
-
- CXXCtorInitializer *BOMInit;
- if (Type == CTOR_INITIALIZER_BASE)
- BOMInit = new (Context)
- CXXCtorInitializer(Context, TInfo, IsBaseVirtual, LParenLoc, Init,
- RParenLoc, MemberOrEllipsisLoc);
- else if (Type == CTOR_INITIALIZER_DELEGATING)
- BOMInit = new (Context)
- CXXCtorInitializer(Context, TInfo, LParenLoc, Init, RParenLoc);
- else if (Member)
- BOMInit = new (Context)
- CXXCtorInitializer(Context, Member, MemberOrEllipsisLoc, LParenLoc,
- Init, RParenLoc);
- else
- BOMInit = new (Context)
- CXXCtorInitializer(Context, IndirectMember, MemberOrEllipsisLoc,
- LParenLoc, Init, RParenLoc);
-
- if (/*IsWritten*/Record[Idx++]) {
- unsigned SourceOrder = Record[Idx++];
- BOMInit->setSourceOrder(SourceOrder);
- }
-
- CtorInitializers[i] = BOMInit;
- }
-
- return CtorInitializers;
-}
-
-NestedNameSpecifier *
-ASTReader::ReadNestedNameSpecifier(ModuleFile &F,
- const RecordData &Record, unsigned &Idx) {
- ASTContext &Context = getContext();
- unsigned N = Record[Idx++];
- NestedNameSpecifier *NNS = nullptr, *Prev = nullptr;
- for (unsigned I = 0; I != N; ++I) {
- NestedNameSpecifier::SpecifierKind Kind
- = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
- switch (Kind) {
- case NestedNameSpecifier::Identifier: {
- IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
- NNS = NestedNameSpecifier::Create(Context, Prev, II);
- break;
- }
-
- case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
- NNS = NestedNameSpecifier::Create(Context, Prev, NS);
- break;
- }
-
- case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
- NNS = NestedNameSpecifier::Create(Context, Prev, Alias);
- break;
- }
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate: {
- const Type *T = readType(F, Record, Idx).getTypePtrOrNull();
- if (!T)
- return nullptr;
-
- bool Template = Record[Idx++];
- NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);
- break;
- }
-
- case NestedNameSpecifier::Global:
- NNS = NestedNameSpecifier::GlobalSpecifier(Context);
- // No associated value, and there can't be a prefix.
- break;
-
- case NestedNameSpecifier::Super: {
- CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx);
- NNS = NestedNameSpecifier::SuperSpecifier(Context, RD);
- break;
- }
- }
- Prev = NNS;
- }
- return NNS;
-}
-
-NestedNameSpecifierLoc
-ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record,
- unsigned &Idx) {
- ASTContext &Context = getContext();
- unsigned N = Record[Idx++];
- NestedNameSpecifierLocBuilder Builder;
- for (unsigned I = 0; I != N; ++I) {
- NestedNameSpecifier::SpecifierKind Kind
- = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
- switch (Kind) {
- case NestedNameSpecifier::Identifier: {
- IdentifierInfo *II = GetIdentifierInfo(F, Record, Idx);
- SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());
- break;
- }
-
- case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS = ReadDeclAs<NamespaceDecl>(F, Record, Idx);
- SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());
- break;
- }
-
- case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias =ReadDeclAs<NamespaceAliasDecl>(F, Record, Idx);
- SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());
- break;
- }
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate: {
- bool Template = Record[Idx++];
- TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
- if (!T)
- return NestedNameSpecifierLoc();
- SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
-
- // FIXME: 'template' keyword location not saved anywhere, so we fake it.
- Builder.Extend(Context,
- Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),
- T->getTypeLoc(), ColonColonLoc);
- break;
- }
-
- case NestedNameSpecifier::Global: {
- SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
- Builder.MakeGlobal(Context, ColonColonLoc);
- break;
- }
-
- case NestedNameSpecifier::Super: {
- CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx);
- SourceRange Range = ReadSourceRange(F, Record, Idx);
- Builder.MakeSuper(Context, RD, Range.getBegin(), Range.getEnd());
- break;
- }
- }
- }
-
- return Builder.getWithLocInContext(Context);
-}
-
-SourceRange
-ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record,
- unsigned &Idx) {
- SourceLocation beg = ReadSourceLocation(F, Record, Idx);
- SourceLocation end = ReadSourceLocation(F, Record, Idx);
- return SourceRange(beg, end);
-}
-
-/// Read an integral value
-llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
- unsigned BitWidth = Record[Idx++];
- unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
- llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
- Idx += NumWords;
- return Result;
-}
-
-/// Read a signed integral value
-llvm::APSInt ASTReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
- bool isUnsigned = Record[Idx++];
- return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
-}
-
-/// Read a floating-point value
-llvm::APFloat ASTReader::ReadAPFloat(const RecordData &Record,
- const llvm::fltSemantics &Sem,
- unsigned &Idx) {
- return llvm::APFloat(Sem, ReadAPInt(Record, Idx));
-}
-
-// Read a string
-std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {
- unsigned Len = Record[Idx++];
- std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
- Idx += Len;
- return Result;
-}
-
-std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record,
- unsigned &Idx) {
- std::string Filename = ReadString(Record, Idx);
- ResolveImportedPath(F, Filename);
- return Filename;
-}
-
-VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,
- unsigned &Idx) {
- unsigned Major = Record[Idx++];
- unsigned Minor = Record[Idx++];
- unsigned Subminor = Record[Idx++];
- if (Minor == 0)
- return VersionTuple(Major);
- if (Subminor == 0)
- return VersionTuple(Major, Minor - 1);
- return VersionTuple(Major, Minor - 1, Subminor - 1);
-}
-
-CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F,
- const RecordData &Record,
- unsigned &Idx) {
- CXXDestructorDecl *Decl = ReadDeclAs<CXXDestructorDecl>(F, Record, Idx);
- return CXXTemporary::Create(getContext(), Decl);
-}
-
-DiagnosticBuilder ASTReader::Diag(unsigned DiagID) const {
- return Diag(CurrentImportLoc, DiagID);
-}
-
-DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const {
- return Diags.Report(Loc, DiagID);
-}
-
-/// Retrieve the identifier table associated with the
-/// preprocessor.
-IdentifierTable &ASTReader::getIdentifierTable() {
- return PP.getIdentifierTable();
-}
-
-/// Record that the given ID maps to the given switch-case
-/// statement.
-void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
- assert((*CurrSwitchCaseStmts)[ID] == nullptr &&
- "Already have a SwitchCase with this ID");
- (*CurrSwitchCaseStmts)[ID] = SC;
-}
-
-/// Retrieve the switch-case statement with the given ID.
-SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
- assert((*CurrSwitchCaseStmts)[ID] != nullptr && "No SwitchCase with this ID");
- return (*CurrSwitchCaseStmts)[ID];
-}
-
-void ASTReader::ClearSwitchCaseIDs() {
- CurrSwitchCaseStmts->clear();
-}
-
-void ASTReader::ReadComments() {
- ASTContext &Context = getContext();
- std::vector<RawComment *> Comments;
- for (SmallVectorImpl<std::pair<BitstreamCursor,
- serialization::ModuleFile *>>::iterator
- I = CommentsCursors.begin(),
- E = CommentsCursors.end();
- I != E; ++I) {
- Comments.clear();
- BitstreamCursor &Cursor = I->first;
- serialization::ModuleFile &F = *I->second;
- SavedStreamPosition SavedPosition(Cursor);
-
- RecordData Record;
- while (true) {
- llvm::BitstreamEntry Entry =
- Cursor.advanceSkippingSubblocks(BitstreamCursor::AF_DontPopBlockAtEnd);
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock: // Handled for us already.
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return;
- case llvm::BitstreamEntry::EndBlock:
- goto NextCursor;
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- // Read a record.
- Record.clear();
- switch ((CommentRecordTypes)Cursor.readRecord(Entry.ID, Record)) {
- case COMMENTS_RAW_COMMENT: {
- unsigned Idx = 0;
- SourceRange SR = ReadSourceRange(F, Record, Idx);
- RawComment::CommentKind Kind =
- (RawComment::CommentKind) Record[Idx++];
- bool IsTrailingComment = Record[Idx++];
- bool IsAlmostTrailingComment = Record[Idx++];
- Comments.push_back(new (Context) RawComment(
- SR, Kind, IsTrailingComment, IsAlmostTrailingComment));
- break;
- }
- }
- }
- NextCursor:
- // De-serialized SourceLocations get negative FileIDs for other modules,
- // potentially invalidating the original order. Sort it again.
- llvm::sort(Comments, BeforeThanCompare<RawComment>(SourceMgr));
- Context.Comments.addDeserializedComments(Comments);
- }
-}
-
-void ASTReader::visitInputFiles(serialization::ModuleFile &MF,
- bool IncludeSystem, bool Complain,
- llvm::function_ref<void(const serialization::InputFile &IF,
- bool isSystem)> Visitor) {
- unsigned NumUserInputs = MF.NumUserInputFiles;
- unsigned NumInputs = MF.InputFilesLoaded.size();
- assert(NumUserInputs <= NumInputs);
- unsigned N = IncludeSystem ? NumInputs : NumUserInputs;
- for (unsigned I = 0; I < N; ++I) {
- bool IsSystem = I >= NumUserInputs;
- InputFile IF = getInputFile(MF, I+1, Complain);
- Visitor(IF, IsSystem);
- }
-}
-
-void ASTReader::visitTopLevelModuleMaps(
- serialization::ModuleFile &MF,
- llvm::function_ref<void(const FileEntry *FE)> Visitor) {
- unsigned NumInputs = MF.InputFilesLoaded.size();
- for (unsigned I = 0; I < NumInputs; ++I) {
- InputFileInfo IFI = readInputFileInfo(MF, I + 1);
- if (IFI.TopLevelModuleMap)
- // FIXME: This unnecessarily re-reads the InputFileInfo.
- if (auto *FE = getInputFile(MF, I + 1).getFile())
- Visitor(FE);
- }
-}
-
-std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
- // If we know the owning module, use it.
- if (Module *M = D->getImportedOwningModule())
- return M->getFullModuleName();
-
- // Otherwise, use the name of the top-level module the decl is within.
- if (ModuleFile *M = getOwningModuleFile(D))
- return M->ModuleName;
-
- // Not from a module.
- return {};
-}
-
-void ASTReader::finishPendingActions() {
- while (!PendingIdentifierInfos.empty() || !PendingFunctionTypes.empty() ||
- !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
- !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
- !PendingUpdateRecords.empty()) {
- // If any identifiers with corresponding top-level declarations have
- // been loaded, load those declarations now.
- using TopLevelDeclsMap =
- llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2>>;
- TopLevelDeclsMap TopLevelDecls;
-
- while (!PendingIdentifierInfos.empty()) {
- IdentifierInfo *II = PendingIdentifierInfos.back().first;
- SmallVector<uint32_t, 4> DeclIDs =
- std::move(PendingIdentifierInfos.back().second);
- PendingIdentifierInfos.pop_back();
-
- SetGloballyVisibleDecls(II, DeclIDs, &TopLevelDecls[II]);
- }
-
- // Load each function type that we deferred loading because it was a
- // deduced type that might refer to a local type declared within itself.
- for (unsigned I = 0; I != PendingFunctionTypes.size(); ++I) {
- auto *FD = PendingFunctionTypes[I].first;
- FD->setType(GetType(PendingFunctionTypes[I].second));
-
- // If we gave a function a deduced return type, remember that we need to
- // propagate that along the redeclaration chain.
- auto *DT = FD->getReturnType()->getContainedDeducedType();
- if (DT && DT->isDeduced())
- PendingDeducedTypeUpdates.insert(
- {FD->getCanonicalDecl(), FD->getReturnType()});
- }
- PendingFunctionTypes.clear();
-
- // For each decl chain that we wanted to complete while deserializing, mark
- // it as "still needs to be completed".
- for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) {
- markIncompleteDeclChain(PendingIncompleteDeclChains[I]);
- }
- PendingIncompleteDeclChains.clear();
-
- // Load pending declaration chains.
- for (unsigned I = 0; I != PendingDeclChains.size(); ++I)
- loadPendingDeclChain(PendingDeclChains[I].first,
- PendingDeclChains[I].second);
- PendingDeclChains.clear();
-
- // Make the most recent of the top-level declarations visible.
- for (TopLevelDeclsMap::iterator TLD = TopLevelDecls.begin(),
- TLDEnd = TopLevelDecls.end(); TLD != TLDEnd; ++TLD) {
- IdentifierInfo *II = TLD->first;
- for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) {
- pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II);
- }
- }
-
- // Load any pending macro definitions.
- for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) {
- IdentifierInfo *II = PendingMacroIDs.begin()[I].first;
- SmallVector<PendingMacroInfo, 2> GlobalIDs;
- GlobalIDs.swap(PendingMacroIDs.begin()[I].second);
- // Initialize the macro history from chained-PCHs ahead of module imports.
- for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
- ++IDIdx) {
- const PendingMacroInfo &Info = GlobalIDs[IDIdx];
- if (!Info.M->isModule())
- resolvePendingMacro(II, Info);
- }
- // Handle module imports.
- for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
- ++IDIdx) {
- const PendingMacroInfo &Info = GlobalIDs[IDIdx];
- if (Info.M->isModule())
- resolvePendingMacro(II, Info);
- }
- }
- PendingMacroIDs.clear();
-
- // Wire up the DeclContexts for Decls that we delayed setting until
- // recursive loading is completed.
- while (!PendingDeclContextInfos.empty()) {
- PendingDeclContextInfo Info = PendingDeclContextInfos.front();
- PendingDeclContextInfos.pop_front();
- DeclContext *SemaDC = cast<DeclContext>(GetDecl(Info.SemaDC));
- DeclContext *LexicalDC = cast<DeclContext>(GetDecl(Info.LexicalDC));
- Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext());
- }
-
- // Perform any pending declaration updates.
- while (!PendingUpdateRecords.empty()) {
- auto Update = PendingUpdateRecords.pop_back_val();
- ReadingKindTracker ReadingKind(Read_Decl, *this);
- loadDeclUpdateRecords(Update);
- }
- }
-
- // At this point, all update records for loaded decls are in place, so any
- // fake class definitions should have become real.
- assert(PendingFakeDefinitionData.empty() &&
- "faked up a class definition but never saw the real one");
-
- // If we deserialized any C++ or Objective-C class definitions, any
- // Objective-C protocol definitions, or any redeclarable templates, make sure
- // that all redeclarations point to the definitions. Note that this can only
- // happen now, after the redeclaration chains have been fully wired.
- for (Decl *D : PendingDefinitions) {
- if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- if (const TagType *TagT = dyn_cast<TagType>(TD->getTypeForDecl())) {
- // Make sure that the TagType points at the definition.
- const_cast<TagType*>(TagT)->decl = TD;
- }
-
- if (auto RD = dyn_cast<CXXRecordDecl>(D)) {
- for (auto *R = getMostRecentExistingDecl(RD); R;
- R = R->getPreviousDecl()) {
- assert((R == D) ==
- cast<CXXRecordDecl>(R)->isThisDeclarationADefinition() &&
- "declaration thinks it's the definition but it isn't");
- cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData;
- }
- }
-
- continue;
- }
-
- if (auto ID = dyn_cast<ObjCInterfaceDecl>(D)) {
- // Make sure that the ObjCInterfaceType points at the definition.
- const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))
- ->Decl = ID;
-
- for (auto *R = getMostRecentExistingDecl(ID); R; R = R->getPreviousDecl())
- cast<ObjCInterfaceDecl>(R)->Data = ID->Data;
-
- continue;
- }
-
- if (auto PD = dyn_cast<ObjCProtocolDecl>(D)) {
- for (auto *R = getMostRecentExistingDecl(PD); R; R = R->getPreviousDecl())
- cast<ObjCProtocolDecl>(R)->Data = PD->Data;
-
- continue;
- }
-
- auto RTD = cast<RedeclarableTemplateDecl>(D)->getCanonicalDecl();
- for (auto *R = getMostRecentExistingDecl(RTD); R; R = R->getPreviousDecl())
- cast<RedeclarableTemplateDecl>(R)->Common = RTD->Common;
- }
- PendingDefinitions.clear();
-
- // Load the bodies of any functions or methods we've encountered. We do
- // this now (delayed) so that we can be sure that the declaration chains
- // have been fully wired up (hasBody relies on this).
- // FIXME: We shouldn't require complete redeclaration chains here.
- for (PendingBodiesMap::iterator PB = PendingBodies.begin(),
- PBEnd = PendingBodies.end();
- PB != PBEnd; ++PB) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
- // For a function defined inline within a class template, force the
- // canonical definition to be the one inside the canonical definition of
- // the template. This ensures that we instantiate from a correct view
- // of the template.
- //
- // Sadly we can't do this more generally: we can't be sure that all
- // copies of an arbitrary class definition will have the same members
- // defined (eg, some member functions may not be instantiated, and some
- // special members may or may not have been implicitly defined).
- if (auto *RD = dyn_cast<CXXRecordDecl>(FD->getLexicalParent()))
- if (RD->isDependentContext() && !RD->isThisDeclarationADefinition())
- continue;
-
- // FIXME: Check for =delete/=default?
- // FIXME: Complain about ODR violations here?
- const FunctionDecl *Defn = nullptr;
- if (!getContext().getLangOpts().Modules || !FD->hasBody(Defn)) {
- FD->setLazyBody(PB->second);
- } else {
- auto *NonConstDefn = const_cast<FunctionDecl*>(Defn);
- mergeDefinitionVisibility(NonConstDefn, FD);
-
- if (!FD->isLateTemplateParsed() &&
- !NonConstDefn->isLateTemplateParsed() &&
- FD->getODRHash() != NonConstDefn->getODRHash()) {
- if (!isa<CXXMethodDecl>(FD)) {
- PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn);
- } else if (FD->getLexicalParent()->isFileContext() &&
- NonConstDefn->getLexicalParent()->isFileContext()) {
- // Only diagnose out-of-line method definitions. If they are
- // in class definitions, then an error will be generated when
- // processing the class bodies.
- PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn);
- }
- }
- }
- continue;
- }
-
- ObjCMethodDecl *MD = cast<ObjCMethodDecl>(PB->first);
- if (!getContext().getLangOpts().Modules || !MD->hasBody())
- MD->setLazyBody(PB->second);
- }
- PendingBodies.clear();
-
- // Do some cleanup.
- for (auto *ND : PendingMergedDefinitionsToDeduplicate)
- getContext().deduplicateMergedDefinitonsFor(ND);
- PendingMergedDefinitionsToDeduplicate.clear();
-}
-
-void ASTReader::diagnoseOdrViolations() {
- if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty() &&
- PendingFunctionOdrMergeFailures.empty() &&
- PendingEnumOdrMergeFailures.empty())
- return;
-
- // Trigger the import of the full definition of each class that had any
- // odr-merging problems, so we can produce better diagnostics for them.
- // These updates may in turn find and diagnose some ODR failures, so take
- // ownership of the set first.
- auto OdrMergeFailures = std::move(PendingOdrMergeFailures);
- PendingOdrMergeFailures.clear();
- for (auto &Merge : OdrMergeFailures) {
- Merge.first->buildLookup();
- Merge.first->decls_begin();
- Merge.first->bases_begin();
- Merge.first->vbases_begin();
- for (auto &RecordPair : Merge.second) {
- auto *RD = RecordPair.first;
- RD->decls_begin();
- RD->bases_begin();
- RD->vbases_begin();
- }
- }
-
- // Trigger the import of functions.
- auto FunctionOdrMergeFailures = std::move(PendingFunctionOdrMergeFailures);
- PendingFunctionOdrMergeFailures.clear();
- for (auto &Merge : FunctionOdrMergeFailures) {
- Merge.first->buildLookup();
- Merge.first->decls_begin();
- Merge.first->getBody();
- for (auto &FD : Merge.second) {
- FD->buildLookup();
- FD->decls_begin();
- FD->getBody();
- }
- }
-
- // Trigger the import of enums.
- auto EnumOdrMergeFailures = std::move(PendingEnumOdrMergeFailures);
- PendingEnumOdrMergeFailures.clear();
- for (auto &Merge : EnumOdrMergeFailures) {
- Merge.first->decls_begin();
- for (auto &Enum : Merge.second) {
- Enum->decls_begin();
- }
- }
-
- // For each declaration from a merged context, check that the canonical
- // definition of that context also contains a declaration of the same
- // entity.
- //
- // Caution: this loop does things that might invalidate iterators into
- // PendingOdrMergeChecks. Don't turn this into a range-based for loop!
- while (!PendingOdrMergeChecks.empty()) {
- NamedDecl *D = PendingOdrMergeChecks.pop_back_val();
-
- // FIXME: Skip over implicit declarations for now. This matters for things
- // like implicitly-declared special member functions. This isn't entirely
- // correct; we can end up with multiple unmerged declarations of the same
- // implicit entity.
- if (D->isImplicit())
- continue;
-
- DeclContext *CanonDef = D->getDeclContext();
-
- bool Found = false;
- const Decl *DCanon = D->getCanonicalDecl();
-
- for (auto RI : D->redecls()) {
- if (RI->getLexicalDeclContext() == CanonDef) {
- Found = true;
- break;
- }
- }
- if (Found)
- continue;
-
- // Quick check failed, time to do the slow thing. Note, we can't just
- // look up the name of D in CanonDef here, because the member that is
- // in CanonDef might not be found by name lookup (it might have been
- // replaced by a more recent declaration in the lookup table), and we
- // can't necessarily find it in the redeclaration chain because it might
- // be merely mergeable, not redeclarable.
- llvm::SmallVector<const NamedDecl*, 4> Candidates;
- for (auto *CanonMember : CanonDef->decls()) {
- if (CanonMember->getCanonicalDecl() == DCanon) {
- // This can happen if the declaration is merely mergeable and not
- // actually redeclarable (we looked for redeclarations earlier).
- //
- // FIXME: We should be able to detect this more efficiently, without
- // pulling in all of the members of CanonDef.
- Found = true;
- break;
- }
- if (auto *ND = dyn_cast<NamedDecl>(CanonMember))
- if (ND->getDeclName() == D->getDeclName())
- Candidates.push_back(ND);
- }
-
- if (!Found) {
- // The AST doesn't like TagDecls becoming invalid after they've been
- // completed. We only really need to mark FieldDecls as invalid here.
- if (!isa<TagDecl>(D))
- D->setInvalidDecl();
-
- // Ensure we don't accidentally recursively enter deserialization while
- // we're producing our diagnostic.
- Deserializing RecursionGuard(this);
-
- std::string CanonDefModule =
- getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef));
- Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl)
- << D << getOwningModuleNameForDiagnostic(D)
- << CanonDef << CanonDefModule.empty() << CanonDefModule;
-
- if (Candidates.empty())
- Diag(cast<Decl>(CanonDef)->getLocation(),
- diag::note_module_odr_violation_no_possible_decls) << D;
- else {
- for (unsigned I = 0, N = Candidates.size(); I != N; ++I)
- Diag(Candidates[I]->getLocation(),
- diag::note_module_odr_violation_possible_decl)
- << Candidates[I];
- }
-
- DiagnosedOdrMergeFailures.insert(CanonDef);
- }
- }
-
- if (OdrMergeFailures.empty() && FunctionOdrMergeFailures.empty() &&
- EnumOdrMergeFailures.empty())
- return;
-
- // Ensure we don't accidentally recursively enter deserialization while
- // we're producing our diagnostics.
- Deserializing RecursionGuard(this);
-
- // Common code for hashing helpers.
- ODRHash Hash;
- auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {
- Hash.clear();
- Hash.AddQualType(Ty);
- return Hash.CalculateHash();
- };
-
- auto ComputeODRHash = [&Hash](const Stmt *S) {
- assert(S);
- Hash.clear();
- Hash.AddStmt(S);
- return Hash.CalculateHash();
- };
-
- auto ComputeSubDeclODRHash = [&Hash](const Decl *D) {
- assert(D);
- Hash.clear();
- Hash.AddSubDecl(D);
- return Hash.CalculateHash();
- };
-
- auto ComputeTemplateArgumentODRHash = [&Hash](const TemplateArgument &TA) {
- Hash.clear();
- Hash.AddTemplateArgument(TA);
- return Hash.CalculateHash();
- };
-
- auto ComputeTemplateParameterListODRHash =
- [&Hash](const TemplateParameterList *TPL) {
- assert(TPL);
- Hash.clear();
- Hash.AddTemplateParameterList(TPL);
- return Hash.CalculateHash();
- };
-
- // Issue any pending ODR-failure diagnostics.
- for (auto &Merge : OdrMergeFailures) {
- // If we've already pointed out a specific problem with this class, don't
- // bother issuing a general "something's different" diagnostic.
- if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
- continue;
-
- bool Diagnosed = false;
- CXXRecordDecl *FirstRecord = Merge.first;
- std::string FirstModule = getOwningModuleNameForDiagnostic(FirstRecord);
- for (auto &RecordPair : Merge.second) {
- CXXRecordDecl *SecondRecord = RecordPair.first;
- // Multiple different declarations got merged together; tell the user
- // where they came from.
- if (FirstRecord == SecondRecord)
- continue;
-
- std::string SecondModule = getOwningModuleNameForDiagnostic(SecondRecord);
-
- auto *FirstDD = FirstRecord->DefinitionData;
- auto *SecondDD = RecordPair.second;
-
- assert(FirstDD && SecondDD && "Definitions without DefinitionData");
-
- // Diagnostics from DefinitionData are emitted here.
- if (FirstDD != SecondDD) {
- enum ODRDefinitionDataDifference {
- NumBases,
- NumVBases,
- BaseType,
- BaseVirtual,
- BaseAccess,
- };
- auto ODRDiagError = [FirstRecord, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRDefinitionDataDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_definition_data)
- << FirstRecord << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagNote = [&SecondModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRDefinitionDataDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_definition_data)
- << SecondModule << Range << DiffType;
- };
-
- unsigned FirstNumBases = FirstDD->NumBases;
- unsigned FirstNumVBases = FirstDD->NumVBases;
- unsigned SecondNumBases = SecondDD->NumBases;
- unsigned SecondNumVBases = SecondDD->NumVBases;
-
- auto GetSourceRange = [](struct CXXRecordDecl::DefinitionData *DD) {
- unsigned NumBases = DD->NumBases;
- if (NumBases == 0) return SourceRange();
- auto bases = DD->bases();
- return SourceRange(bases[0].getBeginLoc(),
- bases[NumBases - 1].getEndLoc());
- };
-
- if (FirstNumBases != SecondNumBases) {
- ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
- NumBases)
- << FirstNumBases;
- ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
- NumBases)
- << SecondNumBases;
- Diagnosed = true;
- break;
- }
-
- if (FirstNumVBases != SecondNumVBases) {
- ODRDiagError(FirstRecord->getLocation(), GetSourceRange(FirstDD),
- NumVBases)
- << FirstNumVBases;
- ODRDiagNote(SecondRecord->getLocation(), GetSourceRange(SecondDD),
- NumVBases)
- << SecondNumVBases;
- Diagnosed = true;
- break;
- }
-
- auto FirstBases = FirstDD->bases();
- auto SecondBases = SecondDD->bases();
- unsigned i = 0;
- for (i = 0; i < FirstNumBases; ++i) {
- auto FirstBase = FirstBases[i];
- auto SecondBase = SecondBases[i];
- if (ComputeQualTypeODRHash(FirstBase.getType()) !=
- ComputeQualTypeODRHash(SecondBase.getType())) {
- ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
- BaseType)
- << (i + 1) << FirstBase.getType();
- ODRDiagNote(SecondRecord->getLocation(),
- SecondBase.getSourceRange(), BaseType)
- << (i + 1) << SecondBase.getType();
- break;
- }
-
- if (FirstBase.isVirtual() != SecondBase.isVirtual()) {
- ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
- BaseVirtual)
- << (i + 1) << FirstBase.isVirtual() << FirstBase.getType();
- ODRDiagNote(SecondRecord->getLocation(),
- SecondBase.getSourceRange(), BaseVirtual)
- << (i + 1) << SecondBase.isVirtual() << SecondBase.getType();
- break;
- }
-
- if (FirstBase.getAccessSpecifierAsWritten() !=
- SecondBase.getAccessSpecifierAsWritten()) {
- ODRDiagError(FirstRecord->getLocation(), FirstBase.getSourceRange(),
- BaseAccess)
- << (i + 1) << FirstBase.getType()
- << (int)FirstBase.getAccessSpecifierAsWritten();
- ODRDiagNote(SecondRecord->getLocation(),
- SecondBase.getSourceRange(), BaseAccess)
- << (i + 1) << SecondBase.getType()
- << (int)SecondBase.getAccessSpecifierAsWritten();
- break;
- }
- }
-
- if (i != FirstNumBases) {
- Diagnosed = true;
- break;
- }
- }
-
- using DeclHashes = llvm::SmallVector<std::pair<Decl *, unsigned>, 4>;
-
- const ClassTemplateDecl *FirstTemplate =
- FirstRecord->getDescribedClassTemplate();
- const ClassTemplateDecl *SecondTemplate =
- SecondRecord->getDescribedClassTemplate();
-
- assert(!FirstTemplate == !SecondTemplate &&
- "Both pointers should be null or non-null");
-
- enum ODRTemplateDifference {
- ParamEmptyName,
- ParamName,
- ParamSingleDefaultArgument,
- ParamDifferentDefaultArgument,
- };
-
- if (FirstTemplate && SecondTemplate) {
- DeclHashes FirstTemplateHashes;
- DeclHashes SecondTemplateHashes;
-
- auto PopulateTemplateParameterHashs =
- [&ComputeSubDeclODRHash](DeclHashes &Hashes,
- const ClassTemplateDecl *TD) {
- for (auto *D : TD->getTemplateParameters()->asArray()) {
- Hashes.emplace_back(D, ComputeSubDeclODRHash(D));
- }
- };
-
- PopulateTemplateParameterHashs(FirstTemplateHashes, FirstTemplate);
- PopulateTemplateParameterHashs(SecondTemplateHashes, SecondTemplate);
-
- assert(FirstTemplateHashes.size() == SecondTemplateHashes.size() &&
- "Number of template parameters should be equal.");
-
- auto FirstIt = FirstTemplateHashes.begin();
- auto FirstEnd = FirstTemplateHashes.end();
- auto SecondIt = SecondTemplateHashes.begin();
- for (; FirstIt != FirstEnd; ++FirstIt, ++SecondIt) {
- if (FirstIt->second == SecondIt->second)
- continue;
-
- auto ODRDiagError = [FirstRecord, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRTemplateDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_template_parameter)
- << FirstRecord << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagNote = [&SecondModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRTemplateDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_template_parameter)
- << SecondModule << Range << DiffType;
- };
-
- const NamedDecl* FirstDecl = cast<NamedDecl>(FirstIt->first);
- const NamedDecl* SecondDecl = cast<NamedDecl>(SecondIt->first);
-
- assert(FirstDecl->getKind() == SecondDecl->getKind() &&
- "Parameter Decl's should be the same kind.");
-
- DeclarationName FirstName = FirstDecl->getDeclName();
- DeclarationName SecondName = SecondDecl->getDeclName();
-
- if (FirstName != SecondName) {
- const bool FirstNameEmpty =
- FirstName.isIdentifier() && !FirstName.getAsIdentifierInfo();
- const bool SecondNameEmpty =
- SecondName.isIdentifier() && !SecondName.getAsIdentifierInfo();
- assert((!FirstNameEmpty || !SecondNameEmpty) &&
- "Both template parameters cannot be unnamed.");
- ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
- FirstNameEmpty ? ParamEmptyName : ParamName)
- << FirstName;
- ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
- SecondNameEmpty ? ParamEmptyName : ParamName)
- << SecondName;
- break;
- }
-
- switch (FirstDecl->getKind()) {
- default:
- llvm_unreachable("Invalid template parameter type.");
- case Decl::TemplateTypeParm: {
- const auto *FirstParam = cast<TemplateTypeParmDecl>(FirstDecl);
- const auto *SecondParam = cast<TemplateTypeParmDecl>(SecondDecl);
- const bool HasFirstDefaultArgument =
- FirstParam->hasDefaultArgument() &&
- !FirstParam->defaultArgumentWasInherited();
- const bool HasSecondDefaultArgument =
- SecondParam->hasDefaultArgument() &&
- !SecondParam->defaultArgumentWasInherited();
-
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- ODRDiagError(FirstDecl->getLocation(),
- FirstDecl->getSourceRange(),
- ParamSingleDefaultArgument)
- << HasFirstDefaultArgument;
- ODRDiagNote(SecondDecl->getLocation(),
- SecondDecl->getSourceRange(),
- ParamSingleDefaultArgument)
- << HasSecondDefaultArgument;
- break;
- }
-
- assert(HasFirstDefaultArgument && HasSecondDefaultArgument &&
- "Expecting default arguments.");
-
- ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
- ParamDifferentDefaultArgument);
- ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
- ParamDifferentDefaultArgument);
-
- break;
- }
- case Decl::NonTypeTemplateParm: {
- const auto *FirstParam = cast<NonTypeTemplateParmDecl>(FirstDecl);
- const auto *SecondParam = cast<NonTypeTemplateParmDecl>(SecondDecl);
- const bool HasFirstDefaultArgument =
- FirstParam->hasDefaultArgument() &&
- !FirstParam->defaultArgumentWasInherited();
- const bool HasSecondDefaultArgument =
- SecondParam->hasDefaultArgument() &&
- !SecondParam->defaultArgumentWasInherited();
-
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- ODRDiagError(FirstDecl->getLocation(),
- FirstDecl->getSourceRange(),
- ParamSingleDefaultArgument)
- << HasFirstDefaultArgument;
- ODRDiagNote(SecondDecl->getLocation(),
- SecondDecl->getSourceRange(),
- ParamSingleDefaultArgument)
- << HasSecondDefaultArgument;
- break;
- }
-
- assert(HasFirstDefaultArgument && HasSecondDefaultArgument &&
- "Expecting default arguments.");
-
- ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
- ParamDifferentDefaultArgument);
- ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
- ParamDifferentDefaultArgument);
-
- break;
- }
- case Decl::TemplateTemplateParm: {
- const auto *FirstParam = cast<TemplateTemplateParmDecl>(FirstDecl);
- const auto *SecondParam =
- cast<TemplateTemplateParmDecl>(SecondDecl);
- const bool HasFirstDefaultArgument =
- FirstParam->hasDefaultArgument() &&
- !FirstParam->defaultArgumentWasInherited();
- const bool HasSecondDefaultArgument =
- SecondParam->hasDefaultArgument() &&
- !SecondParam->defaultArgumentWasInherited();
-
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- ODRDiagError(FirstDecl->getLocation(),
- FirstDecl->getSourceRange(),
- ParamSingleDefaultArgument)
- << HasFirstDefaultArgument;
- ODRDiagNote(SecondDecl->getLocation(),
- SecondDecl->getSourceRange(),
- ParamSingleDefaultArgument)
- << HasSecondDefaultArgument;
- break;
- }
-
- assert(HasFirstDefaultArgument && HasSecondDefaultArgument &&
- "Expecting default arguments.");
-
- ODRDiagError(FirstDecl->getLocation(), FirstDecl->getSourceRange(),
- ParamDifferentDefaultArgument);
- ODRDiagNote(SecondDecl->getLocation(), SecondDecl->getSourceRange(),
- ParamDifferentDefaultArgument);
-
- break;
- }
- }
-
- break;
- }
-
- if (FirstIt != FirstEnd) {
- Diagnosed = true;
- break;
- }
- }
-
- DeclHashes FirstHashes;
- DeclHashes SecondHashes;
-
- auto PopulateHashes = [&ComputeSubDeclODRHash, FirstRecord](
- DeclHashes &Hashes, CXXRecordDecl *Record) {
- for (auto *D : Record->decls()) {
- // Due to decl merging, the first CXXRecordDecl is the parent of
- // Decls in both records.
- if (!ODRHash::isWhitelistedDecl(D, FirstRecord))
- continue;
- Hashes.emplace_back(D, ComputeSubDeclODRHash(D));
- }
- };
- PopulateHashes(FirstHashes, FirstRecord);
- PopulateHashes(SecondHashes, SecondRecord);
-
- // Used with err_module_odr_violation_mismatch_decl and
- // note_module_odr_violation_mismatch_decl
- // This list should be the same Decl's as in ODRHash::isWhiteListedDecl
- enum {
- EndOfClass,
- PublicSpecifer,
- PrivateSpecifer,
- ProtectedSpecifer,
- StaticAssert,
- Field,
- CXXMethod,
- TypeAlias,
- TypeDef,
- Var,
- Friend,
- FunctionTemplate,
- Other
- } FirstDiffType = Other,
- SecondDiffType = Other;
-
- auto DifferenceSelector = [](Decl *D) {
- assert(D && "valid Decl required");
- switch (D->getKind()) {
- default:
- return Other;
- case Decl::AccessSpec:
- switch (D->getAccess()) {
- case AS_public:
- return PublicSpecifer;
- case AS_private:
- return PrivateSpecifer;
- case AS_protected:
- return ProtectedSpecifer;
- case AS_none:
- break;
- }
- llvm_unreachable("Invalid access specifier");
- case Decl::StaticAssert:
- return StaticAssert;
- case Decl::Field:
- return Field;
- case Decl::CXXMethod:
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- return CXXMethod;
- case Decl::TypeAlias:
- return TypeAlias;
- case Decl::Typedef:
- return TypeDef;
- case Decl::Var:
- return Var;
- case Decl::Friend:
- return Friend;
- case Decl::FunctionTemplate:
- return FunctionTemplate;
- }
- };
-
- Decl *FirstDecl = nullptr;
- Decl *SecondDecl = nullptr;
- auto FirstIt = FirstHashes.begin();
- auto SecondIt = SecondHashes.begin();
-
- // If there is a diagnoseable difference, FirstDiffType and
- // SecondDiffType will not be Other and FirstDecl and SecondDecl will be
- // filled in if not EndOfClass.
- while (FirstIt != FirstHashes.end() || SecondIt != SecondHashes.end()) {
- if (FirstIt != FirstHashes.end() && SecondIt != SecondHashes.end() &&
- FirstIt->second == SecondIt->second) {
- ++FirstIt;
- ++SecondIt;
- continue;
- }
-
- FirstDecl = FirstIt == FirstHashes.end() ? nullptr : FirstIt->first;
- SecondDecl = SecondIt == SecondHashes.end() ? nullptr : SecondIt->first;
-
- FirstDiffType = FirstDecl ? DifferenceSelector(FirstDecl) : EndOfClass;
- SecondDiffType =
- SecondDecl ? DifferenceSelector(SecondDecl) : EndOfClass;
-
- break;
- }
-
- if (FirstDiffType == Other || SecondDiffType == Other) {
- // Reaching this point means an unexpected Decl was encountered
- // or no difference was detected. This causes a generic error
- // message to be emitted.
- Diag(FirstRecord->getLocation(),
- diag::err_module_odr_violation_different_definitions)
- << FirstRecord << FirstModule.empty() << FirstModule;
-
- if (FirstDecl) {
- Diag(FirstDecl->getLocation(), diag::note_first_module_difference)
- << FirstRecord << FirstDecl->getSourceRange();
- }
-
- Diag(SecondRecord->getLocation(),
- diag::note_module_odr_violation_different_definitions)
- << SecondModule;
-
- if (SecondDecl) {
- Diag(SecondDecl->getLocation(), diag::note_second_module_difference)
- << SecondDecl->getSourceRange();
- }
-
- Diagnosed = true;
- break;
- }
-
- if (FirstDiffType != SecondDiffType) {
- SourceLocation FirstLoc;
- SourceRange FirstRange;
- if (FirstDiffType == EndOfClass) {
- FirstLoc = FirstRecord->getBraceRange().getEnd();
- } else {
- FirstLoc = FirstIt->first->getLocation();
- FirstRange = FirstIt->first->getSourceRange();
- }
- Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl)
- << FirstRecord << FirstModule.empty() << FirstModule << FirstRange
- << FirstDiffType;
-
- SourceLocation SecondLoc;
- SourceRange SecondRange;
- if (SecondDiffType == EndOfClass) {
- SecondLoc = SecondRecord->getBraceRange().getEnd();
- } else {
- SecondLoc = SecondDecl->getLocation();
- SecondRange = SecondDecl->getSourceRange();
- }
- Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl)
- << SecondModule << SecondRange << SecondDiffType;
- Diagnosed = true;
- break;
- }
-
- assert(FirstDiffType == SecondDiffType);
-
- // Used with err_module_odr_violation_mismatch_decl_diff and
- // note_module_odr_violation_mismatch_decl_diff
- enum ODRDeclDifference {
- StaticAssertCondition,
- StaticAssertMessage,
- StaticAssertOnlyMessage,
- FieldName,
- FieldTypeName,
- FieldSingleBitField,
- FieldDifferentWidthBitField,
- FieldSingleMutable,
- FieldSingleInitializer,
- FieldDifferentInitializers,
- MethodName,
- MethodDeleted,
- MethodDefaulted,
- MethodVirtual,
- MethodStatic,
- MethodVolatile,
- MethodConst,
- MethodInline,
- MethodNumberParameters,
- MethodParameterType,
- MethodParameterName,
- MethodParameterSingleDefaultArgument,
- MethodParameterDifferentDefaultArgument,
- MethodNoTemplateArguments,
- MethodDifferentNumberTemplateArguments,
- MethodDifferentTemplateArgument,
- MethodSingleBody,
- MethodDifferentBody,
- TypedefName,
- TypedefType,
- VarName,
- VarType,
- VarSingleInitializer,
- VarDifferentInitializer,
- VarConstexpr,
- FriendTypeFunction,
- FriendType,
- FriendFunction,
- FunctionTemplateDifferentNumberParameters,
- FunctionTemplateParameterDifferentKind,
- FunctionTemplateParameterName,
- FunctionTemplateParameterSingleDefaultArgument,
- FunctionTemplateParameterDifferentDefaultArgument,
- FunctionTemplateParameterDifferentType,
- FunctionTemplatePackParameter,
- };
-
- // These lambdas have the common portions of the ODR diagnostics. This
- // has the same return as Diag(), so addition parameters can be passed
- // in with operator<<
- auto ODRDiagError = [FirstRecord, &FirstModule, this](
- SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_diff)
- << FirstRecord << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagNote = [&SecondModule, this](
- SourceLocation Loc, SourceRange Range, ODRDeclDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_diff)
- << SecondModule << Range << DiffType;
- };
-
- switch (FirstDiffType) {
- case Other:
- case EndOfClass:
- case PublicSpecifer:
- case PrivateSpecifer:
- case ProtectedSpecifer:
- llvm_unreachable("Invalid diff type");
-
- case StaticAssert: {
- StaticAssertDecl *FirstSA = cast<StaticAssertDecl>(FirstDecl);
- StaticAssertDecl *SecondSA = cast<StaticAssertDecl>(SecondDecl);
-
- Expr *FirstExpr = FirstSA->getAssertExpr();
- Expr *SecondExpr = SecondSA->getAssertExpr();
- unsigned FirstODRHash = ComputeODRHash(FirstExpr);
- unsigned SecondODRHash = ComputeODRHash(SecondExpr);
- if (FirstODRHash != SecondODRHash) {
- ODRDiagError(FirstExpr->getBeginLoc(), FirstExpr->getSourceRange(),
- StaticAssertCondition);
- ODRDiagNote(SecondExpr->getBeginLoc(), SecondExpr->getSourceRange(),
- StaticAssertCondition);
- Diagnosed = true;
- break;
- }
-
- StringLiteral *FirstStr = FirstSA->getMessage();
- StringLiteral *SecondStr = SecondSA->getMessage();
- assert((FirstStr || SecondStr) && "Both messages cannot be empty");
- if ((FirstStr && !SecondStr) || (!FirstStr && SecondStr)) {
- SourceLocation FirstLoc, SecondLoc;
- SourceRange FirstRange, SecondRange;
- if (FirstStr) {
- FirstLoc = FirstStr->getBeginLoc();
- FirstRange = FirstStr->getSourceRange();
- } else {
- FirstLoc = FirstSA->getBeginLoc();
- FirstRange = FirstSA->getSourceRange();
- }
- if (SecondStr) {
- SecondLoc = SecondStr->getBeginLoc();
- SecondRange = SecondStr->getSourceRange();
- } else {
- SecondLoc = SecondSA->getBeginLoc();
- SecondRange = SecondSA->getSourceRange();
- }
- ODRDiagError(FirstLoc, FirstRange, StaticAssertOnlyMessage)
- << (FirstStr == nullptr);
- ODRDiagNote(SecondLoc, SecondRange, StaticAssertOnlyMessage)
- << (SecondStr == nullptr);
- Diagnosed = true;
- break;
- }
-
- if (FirstStr && SecondStr &&
- FirstStr->getString() != SecondStr->getString()) {
- ODRDiagError(FirstStr->getBeginLoc(), FirstStr->getSourceRange(),
- StaticAssertMessage);
- ODRDiagNote(SecondStr->getBeginLoc(), SecondStr->getSourceRange(),
- StaticAssertMessage);
- Diagnosed = true;
- break;
- }
- break;
- }
- case Field: {
- FieldDecl *FirstField = cast<FieldDecl>(FirstDecl);
- FieldDecl *SecondField = cast<FieldDecl>(SecondDecl);
- IdentifierInfo *FirstII = FirstField->getIdentifier();
- IdentifierInfo *SecondII = SecondField->getIdentifier();
- if (FirstII->getName() != SecondII->getName()) {
- ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
- FieldName)
- << FirstII;
- ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
- FieldName)
- << SecondII;
-
- Diagnosed = true;
- break;
- }
-
- assert(getContext().hasSameType(FirstField->getType(),
- SecondField->getType()));
-
- QualType FirstType = FirstField->getType();
- QualType SecondType = SecondField->getType();
- if (ComputeQualTypeODRHash(FirstType) !=
- ComputeQualTypeODRHash(SecondType)) {
- ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
- FieldTypeName)
- << FirstII << FirstType;
- ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
- FieldTypeName)
- << SecondII << SecondType;
-
- Diagnosed = true;
- break;
- }
-
- const bool IsFirstBitField = FirstField->isBitField();
- const bool IsSecondBitField = SecondField->isBitField();
- if (IsFirstBitField != IsSecondBitField) {
- ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
- FieldSingleBitField)
- << FirstII << IsFirstBitField;
- ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
- FieldSingleBitField)
- << SecondII << IsSecondBitField;
- Diagnosed = true;
- break;
- }
-
- if (IsFirstBitField && IsSecondBitField) {
- ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
- FieldDifferentWidthBitField)
- << FirstII << FirstField->getBitWidth()->getSourceRange();
- ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
- FieldDifferentWidthBitField)
- << SecondII << SecondField->getBitWidth()->getSourceRange();
- Diagnosed = true;
- break;
- }
-
- const bool IsFirstMutable = FirstField->isMutable();
- const bool IsSecondMutable = SecondField->isMutable();
- if (IsFirstMutable != IsSecondMutable) {
- ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
- FieldSingleMutable)
- << FirstII << IsFirstMutable;
- ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
- FieldSingleMutable)
- << SecondII << IsSecondMutable;
- Diagnosed = true;
- break;
- }
-
- const Expr *FirstInitializer = FirstField->getInClassInitializer();
- const Expr *SecondInitializer = SecondField->getInClassInitializer();
- if ((!FirstInitializer && SecondInitializer) ||
- (FirstInitializer && !SecondInitializer)) {
- ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
- FieldSingleInitializer)
- << FirstII << (FirstInitializer != nullptr);
- ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
- FieldSingleInitializer)
- << SecondII << (SecondInitializer != nullptr);
- Diagnosed = true;
- break;
- }
-
- if (FirstInitializer && SecondInitializer) {
- unsigned FirstInitHash = ComputeODRHash(FirstInitializer);
- unsigned SecondInitHash = ComputeODRHash(SecondInitializer);
- if (FirstInitHash != SecondInitHash) {
- ODRDiagError(FirstField->getLocation(),
- FirstField->getSourceRange(),
- FieldDifferentInitializers)
- << FirstII << FirstInitializer->getSourceRange();
- ODRDiagNote(SecondField->getLocation(),
- SecondField->getSourceRange(),
- FieldDifferentInitializers)
- << SecondII << SecondInitializer->getSourceRange();
- Diagnosed = true;
- break;
- }
- }
-
- break;
- }
- case CXXMethod: {
- enum {
- DiagMethod,
- DiagConstructor,
- DiagDestructor,
- } FirstMethodType,
- SecondMethodType;
- auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl* D) {
- if (isa<CXXConstructorDecl>(D)) return DiagConstructor;
- if (isa<CXXDestructorDecl>(D)) return DiagDestructor;
- return DiagMethod;
- };
- const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
- const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
- FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
- SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
- auto FirstName = FirstMethod->getDeclName();
- auto SecondName = SecondMethod->getDeclName();
- if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodName)
- << FirstMethodType << FirstName;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodName)
- << SecondMethodType << SecondName;
-
- Diagnosed = true;
- break;
- }
-
- const bool FirstDeleted = FirstMethod->isDeletedAsWritten();
- const bool SecondDeleted = SecondMethod->isDeletedAsWritten();
- if (FirstDeleted != SecondDeleted) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodDeleted)
- << FirstMethodType << FirstName << FirstDeleted;
-
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodDeleted)
- << SecondMethodType << SecondName << SecondDeleted;
- Diagnosed = true;
- break;
- }
-
- const bool FirstDefaulted = FirstMethod->isExplicitlyDefaulted();
- const bool SecondDefaulted = SecondMethod->isExplicitlyDefaulted();
- if (FirstDefaulted != SecondDefaulted) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodDefaulted)
- << FirstMethodType << FirstName << FirstDefaulted;
-
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodDefaulted)
- << SecondMethodType << SecondName << SecondDefaulted;
- Diagnosed = true;
- break;
- }
-
- const bool FirstVirtual = FirstMethod->isVirtualAsWritten();
- const bool SecondVirtual = SecondMethod->isVirtualAsWritten();
- const bool FirstPure = FirstMethod->isPure();
- const bool SecondPure = SecondMethod->isPure();
- if ((FirstVirtual || SecondVirtual) &&
- (FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodVirtual)
- << FirstMethodType << FirstName << FirstPure << FirstVirtual;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodVirtual)
- << SecondMethodType << SecondName << SecondPure << SecondVirtual;
- Diagnosed = true;
- break;
- }
-
- // CXXMethodDecl::isStatic uses the canonical Decl. With Decl merging,
- // FirstDecl is the canonical Decl of SecondDecl, so the storage
- // class needs to be checked instead.
- const auto FirstStorage = FirstMethod->getStorageClass();
- const auto SecondStorage = SecondMethod->getStorageClass();
- const bool FirstStatic = FirstStorage == SC_Static;
- const bool SecondStatic = SecondStorage == SC_Static;
- if (FirstStatic != SecondStatic) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodStatic)
- << FirstMethodType << FirstName << FirstStatic;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodStatic)
- << SecondMethodType << SecondName << SecondStatic;
- Diagnosed = true;
- break;
- }
-
- const bool FirstVolatile = FirstMethod->isVolatile();
- const bool SecondVolatile = SecondMethod->isVolatile();
- if (FirstVolatile != SecondVolatile) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodVolatile)
- << FirstMethodType << FirstName << FirstVolatile;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodVolatile)
- << SecondMethodType << SecondName << SecondVolatile;
- Diagnosed = true;
- break;
- }
-
- const bool FirstConst = FirstMethod->isConst();
- const bool SecondConst = SecondMethod->isConst();
- if (FirstConst != SecondConst) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodConst)
- << FirstMethodType << FirstName << FirstConst;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodConst)
- << SecondMethodType << SecondName << SecondConst;
- Diagnosed = true;
- break;
- }
-
- const bool FirstInline = FirstMethod->isInlineSpecified();
- const bool SecondInline = SecondMethod->isInlineSpecified();
- if (FirstInline != SecondInline) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodInline)
- << FirstMethodType << FirstName << FirstInline;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodInline)
- << SecondMethodType << SecondName << SecondInline;
- Diagnosed = true;
- break;
- }
-
- const unsigned FirstNumParameters = FirstMethod->param_size();
- const unsigned SecondNumParameters = SecondMethod->param_size();
- if (FirstNumParameters != SecondNumParameters) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodNumberParameters)
- << FirstMethodType << FirstName << FirstNumParameters;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodNumberParameters)
- << SecondMethodType << SecondName << SecondNumParameters;
- Diagnosed = true;
- break;
- }
-
- // Need this status boolean to know when break out of the switch.
- bool ParameterMismatch = false;
- for (unsigned I = 0; I < FirstNumParameters; ++I) {
- const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
- const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
-
- QualType FirstParamType = FirstParam->getType();
- QualType SecondParamType = SecondParam->getType();
- if (FirstParamType != SecondParamType &&
- ComputeQualTypeODRHash(FirstParamType) !=
- ComputeQualTypeODRHash(SecondParamType)) {
- if (const DecayedType *ParamDecayedType =
- FirstParamType->getAs<DecayedType>()) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodParameterType)
- << FirstMethodType << FirstName << (I + 1) << FirstParamType
- << true << ParamDecayedType->getOriginalType();
- } else {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodParameterType)
- << FirstMethodType << FirstName << (I + 1) << FirstParamType
- << false;
- }
-
- if (const DecayedType *ParamDecayedType =
- SecondParamType->getAs<DecayedType>()) {
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodParameterType)
- << SecondMethodType << SecondName << (I + 1)
- << SecondParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodParameterType)
- << SecondMethodType << SecondName << (I + 1)
- << SecondParamType << false;
- }
- ParameterMismatch = true;
- break;
- }
-
- DeclarationName FirstParamName = FirstParam->getDeclName();
- DeclarationName SecondParamName = SecondParam->getDeclName();
- if (FirstParamName != SecondParamName) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodParameterName)
- << FirstMethodType << FirstName << (I + 1) << FirstParamName;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodParameterName)
- << SecondMethodType << SecondName << (I + 1) << SecondParamName;
- ParameterMismatch = true;
- break;
- }
-
- const Expr *FirstInit = FirstParam->getInit();
- const Expr *SecondInit = SecondParam->getInit();
- if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(),
- MethodParameterSingleDefaultArgument)
- << FirstMethodType << FirstName << (I + 1)
- << (FirstInit == nullptr)
- << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(),
- MethodParameterSingleDefaultArgument)
- << SecondMethodType << SecondName << (I + 1)
- << (SecondInit == nullptr)
- << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
- ParameterMismatch = true;
- break;
- }
-
- if (FirstInit && SecondInit &&
- ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(),
- MethodParameterDifferentDefaultArgument)
- << FirstMethodType << FirstName << (I + 1)
- << FirstInit->getSourceRange();
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(),
- MethodParameterDifferentDefaultArgument)
- << SecondMethodType << SecondName << (I + 1)
- << SecondInit->getSourceRange();
- ParameterMismatch = true;
- break;
-
- }
- }
-
- if (ParameterMismatch) {
- Diagnosed = true;
- break;
- }
-
- const auto *FirstTemplateArgs =
- FirstMethod->getTemplateSpecializationArgs();
- const auto *SecondTemplateArgs =
- SecondMethod->getTemplateSpecializationArgs();
-
- if ((FirstTemplateArgs && !SecondTemplateArgs) ||
- (!FirstTemplateArgs && SecondTemplateArgs)) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodNoTemplateArguments)
- << FirstMethodType << FirstName << (FirstTemplateArgs != nullptr);
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodNoTemplateArguments)
- << SecondMethodType << SecondName
- << (SecondTemplateArgs != nullptr);
-
- Diagnosed = true;
- break;
- }
-
- if (FirstTemplateArgs && SecondTemplateArgs) {
- // Remove pack expansions from argument list.
- auto ExpandTemplateArgumentList =
- [](const TemplateArgumentList *TAL) {
- llvm::SmallVector<const TemplateArgument *, 8> ExpandedList;
- for (const TemplateArgument &TA : TAL->asArray()) {
- if (TA.getKind() != TemplateArgument::Pack) {
- ExpandedList.push_back(&TA);
- continue;
- }
- for (const TemplateArgument &PackTA : TA.getPackAsArray()) {
- ExpandedList.push_back(&PackTA);
- }
- }
- return ExpandedList;
- };
- llvm::SmallVector<const TemplateArgument *, 8> FirstExpandedList =
- ExpandTemplateArgumentList(FirstTemplateArgs);
- llvm::SmallVector<const TemplateArgument *, 8> SecondExpandedList =
- ExpandTemplateArgumentList(SecondTemplateArgs);
-
- if (FirstExpandedList.size() != SecondExpandedList.size()) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(),
- MethodDifferentNumberTemplateArguments)
- << FirstMethodType << FirstName
- << (unsigned)FirstExpandedList.size();
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(),
- MethodDifferentNumberTemplateArguments)
- << SecondMethodType << SecondName
- << (unsigned)SecondExpandedList.size();
-
- Diagnosed = true;
- break;
- }
-
- bool TemplateArgumentMismatch = false;
- for (unsigned i = 0, e = FirstExpandedList.size(); i != e; ++i) {
- const TemplateArgument &FirstTA = *FirstExpandedList[i],
- &SecondTA = *SecondExpandedList[i];
- if (ComputeTemplateArgumentODRHash(FirstTA) ==
- ComputeTemplateArgumentODRHash(SecondTA)) {
- continue;
- }
-
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(),
- MethodDifferentTemplateArgument)
- << FirstMethodType << FirstName << FirstTA << i + 1;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(),
- MethodDifferentTemplateArgument)
- << SecondMethodType << SecondName << SecondTA << i + 1;
-
- TemplateArgumentMismatch = true;
- break;
- }
-
- if (TemplateArgumentMismatch) {
- Diagnosed = true;
- break;
- }
- }
-
- // Compute the hash of the method as if it has no body.
- auto ComputeCXXMethodODRHash = [&Hash](const CXXMethodDecl *D) {
- Hash.clear();
- Hash.AddFunctionDecl(D, true /*SkipBody*/);
- return Hash.CalculateHash();
- };
-
- // Compare the hash generated to the hash stored. A difference means
- // that a body was present in the original source. Due to merging,
- // the stardard way of detecting a body will not work.
- const bool HasFirstBody =
- ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
- const bool HasSecondBody =
- ComputeCXXMethodODRHash(SecondMethod) != SecondMethod->getODRHash();
-
- if (HasFirstBody != HasSecondBody) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodSingleBody)
- << FirstMethodType << FirstName << HasFirstBody;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodSingleBody)
- << SecondMethodType << SecondName << HasSecondBody;
- Diagnosed = true;
- break;
- }
-
- if (HasFirstBody && HasSecondBody) {
- ODRDiagError(FirstMethod->getLocation(),
- FirstMethod->getSourceRange(), MethodDifferentBody)
- << FirstMethodType << FirstName;
- ODRDiagNote(SecondMethod->getLocation(),
- SecondMethod->getSourceRange(), MethodDifferentBody)
- << SecondMethodType << SecondName;
- Diagnosed = true;
- break;
- }
-
- break;
- }
- case TypeAlias:
- case TypeDef: {
- TypedefNameDecl *FirstTD = cast<TypedefNameDecl>(FirstDecl);
- TypedefNameDecl *SecondTD = cast<TypedefNameDecl>(SecondDecl);
- auto FirstName = FirstTD->getDeclName();
- auto SecondName = SecondTD->getDeclName();
- if (FirstName != SecondName) {
- ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
- TypedefName)
- << (FirstDiffType == TypeAlias) << FirstName;
- ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
- TypedefName)
- << (FirstDiffType == TypeAlias) << SecondName;
- Diagnosed = true;
- break;
- }
-
- QualType FirstType = FirstTD->getUnderlyingType();
- QualType SecondType = SecondTD->getUnderlyingType();
- if (ComputeQualTypeODRHash(FirstType) !=
- ComputeQualTypeODRHash(SecondType)) {
- ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
- TypedefType)
- << (FirstDiffType == TypeAlias) << FirstName << FirstType;
- ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
- TypedefType)
- << (FirstDiffType == TypeAlias) << SecondName << SecondType;
- Diagnosed = true;
- break;
- }
- break;
- }
- case Var: {
- VarDecl *FirstVD = cast<VarDecl>(FirstDecl);
- VarDecl *SecondVD = cast<VarDecl>(SecondDecl);
- auto FirstName = FirstVD->getDeclName();
- auto SecondName = SecondVD->getDeclName();
- if (FirstName != SecondName) {
- ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
- VarName)
- << FirstName;
- ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
- VarName)
- << SecondName;
- Diagnosed = true;
- break;
- }
-
- QualType FirstType = FirstVD->getType();
- QualType SecondType = SecondVD->getType();
- if (ComputeQualTypeODRHash(FirstType) !=
- ComputeQualTypeODRHash(SecondType)) {
- ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
- VarType)
- << FirstName << FirstType;
- ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
- VarType)
- << SecondName << SecondType;
- Diagnosed = true;
- break;
- }
-
- const Expr *FirstInit = FirstVD->getInit();
- const Expr *SecondInit = SecondVD->getInit();
- if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
- ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
- VarSingleInitializer)
- << FirstName << (FirstInit == nullptr)
- << (FirstInit ? FirstInit->getSourceRange(): SourceRange());
- ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
- VarSingleInitializer)
- << SecondName << (SecondInit == nullptr)
- << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
- Diagnosed = true;
- break;
- }
-
- if (FirstInit && SecondInit &&
- ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
- ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
- VarDifferentInitializer)
- << FirstName << FirstInit->getSourceRange();
- ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
- VarDifferentInitializer)
- << SecondName << SecondInit->getSourceRange();
- Diagnosed = true;
- break;
- }
-
- const bool FirstIsConstexpr = FirstVD->isConstexpr();
- const bool SecondIsConstexpr = SecondVD->isConstexpr();
- if (FirstIsConstexpr != SecondIsConstexpr) {
- ODRDiagError(FirstVD->getLocation(), FirstVD->getSourceRange(),
- VarConstexpr)
- << FirstName << FirstIsConstexpr;
- ODRDiagNote(SecondVD->getLocation(), SecondVD->getSourceRange(),
- VarConstexpr)
- << SecondName << SecondIsConstexpr;
- Diagnosed = true;
- break;
- }
- break;
- }
- case Friend: {
- FriendDecl *FirstFriend = cast<FriendDecl>(FirstDecl);
- FriendDecl *SecondFriend = cast<FriendDecl>(SecondDecl);
-
- NamedDecl *FirstND = FirstFriend->getFriendDecl();
- NamedDecl *SecondND = SecondFriend->getFriendDecl();
-
- TypeSourceInfo *FirstTSI = FirstFriend->getFriendType();
- TypeSourceInfo *SecondTSI = SecondFriend->getFriendType();
-
- if (FirstND && SecondND) {
- ODRDiagError(FirstFriend->getFriendLoc(),
- FirstFriend->getSourceRange(), FriendFunction)
- << FirstND;
- ODRDiagNote(SecondFriend->getFriendLoc(),
- SecondFriend->getSourceRange(), FriendFunction)
- << SecondND;
-
- Diagnosed = true;
- break;
- }
-
- if (FirstTSI && SecondTSI) {
- QualType FirstFriendType = FirstTSI->getType();
- QualType SecondFriendType = SecondTSI->getType();
- assert(ComputeQualTypeODRHash(FirstFriendType) !=
- ComputeQualTypeODRHash(SecondFriendType));
- ODRDiagError(FirstFriend->getFriendLoc(),
- FirstFriend->getSourceRange(), FriendType)
- << FirstFriendType;
- ODRDiagNote(SecondFriend->getFriendLoc(),
- SecondFriend->getSourceRange(), FriendType)
- << SecondFriendType;
- Diagnosed = true;
- break;
- }
-
- ODRDiagError(FirstFriend->getFriendLoc(), FirstFriend->getSourceRange(),
- FriendTypeFunction)
- << (FirstTSI == nullptr);
- ODRDiagNote(SecondFriend->getFriendLoc(),
- SecondFriend->getSourceRange(), FriendTypeFunction)
- << (SecondTSI == nullptr);
-
- Diagnosed = true;
- break;
- }
- case FunctionTemplate: {
- FunctionTemplateDecl *FirstTemplate =
- cast<FunctionTemplateDecl>(FirstDecl);
- FunctionTemplateDecl *SecondTemplate =
- cast<FunctionTemplateDecl>(SecondDecl);
-
- TemplateParameterList *FirstTPL =
- FirstTemplate->getTemplateParameters();
- TemplateParameterList *SecondTPL =
- SecondTemplate->getTemplateParameters();
-
- if (FirstTPL->size() != SecondTPL->size()) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateDifferentNumberParameters)
- << FirstTemplate << FirstTPL->size();
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateDifferentNumberParameters)
- << SecondTemplate << SecondTPL->size();
-
- Diagnosed = true;
- break;
- }
-
- bool ParameterMismatch = false;
- for (unsigned i = 0, e = FirstTPL->size(); i != e; ++i) {
- NamedDecl *FirstParam = FirstTPL->getParam(i);
- NamedDecl *SecondParam = SecondTPL->getParam(i);
-
- if (FirstParam->getKind() != SecondParam->getKind()) {
- enum {
- TemplateTypeParameter,
- NonTypeTemplateParameter,
- TemplateTemplateParameter,
- };
- auto GetParamType = [](NamedDecl *D) {
- switch (D->getKind()) {
- default:
- llvm_unreachable("Unexpected template parameter type");
- case Decl::TemplateTypeParm:
- return TemplateTypeParameter;
- case Decl::NonTypeTemplateParm:
- return NonTypeTemplateParameter;
- case Decl::TemplateTemplateParm:
- return TemplateTemplateParameter;
- }
- };
-
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentKind)
- << FirstTemplate << (i + 1) << GetParamType(FirstParam);
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentKind)
- << SecondTemplate << (i + 1) << GetParamType(SecondParam);
-
- ParameterMismatch = true;
- break;
- }
-
- if (FirstParam->getName() != SecondParam->getName()) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterName)
- << FirstTemplate << (i + 1) << (bool)FirstParam->getIdentifier()
- << FirstParam;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterName)
- << SecondTemplate << (i + 1)
- << (bool)SecondParam->getIdentifier() << SecondParam;
- ParameterMismatch = true;
- break;
- }
-
- if (isa<TemplateTypeParmDecl>(FirstParam) &&
- isa<TemplateTypeParmDecl>(SecondParam)) {
- TemplateTypeParmDecl *FirstTTPD =
- cast<TemplateTypeParmDecl>(FirstParam);
- TemplateTypeParmDecl *SecondTTPD =
- cast<TemplateTypeParmDecl>(SecondParam);
- bool HasFirstDefaultArgument =
- FirstTTPD->hasDefaultArgument() &&
- !FirstTTPD->defaultArgumentWasInherited();
- bool HasSecondDefaultArgument =
- SecondTTPD->hasDefaultArgument() &&
- !SecondTTPD->defaultArgumentWasInherited();
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterSingleDefaultArgument)
- << FirstTemplate << (i + 1) << HasFirstDefaultArgument;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterSingleDefaultArgument)
- << SecondTemplate << (i + 1) << HasSecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
-
- if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
- QualType FirstType = FirstTTPD->getDefaultArgument();
- QualType SecondType = SecondTTPD->getDefaultArgument();
- if (ComputeQualTypeODRHash(FirstType) !=
- ComputeQualTypeODRHash(SecondType)) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentDefaultArgument)
- << FirstTemplate << (i + 1) << FirstType;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentDefaultArgument)
- << SecondTemplate << (i + 1) << SecondType;
- ParameterMismatch = true;
- break;
- }
- }
-
- if (FirstTTPD->isParameterPack() !=
- SecondTTPD->isParameterPack()) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplatePackParameter)
- << FirstTemplate << (i + 1) << FirstTTPD->isParameterPack();
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplatePackParameter)
- << SecondTemplate << (i + 1) << SecondTTPD->isParameterPack();
- ParameterMismatch = true;
- break;
- }
- }
-
- if (isa<TemplateTemplateParmDecl>(FirstParam) &&
- isa<TemplateTemplateParmDecl>(SecondParam)) {
- TemplateTemplateParmDecl *FirstTTPD =
- cast<TemplateTemplateParmDecl>(FirstParam);
- TemplateTemplateParmDecl *SecondTTPD =
- cast<TemplateTemplateParmDecl>(SecondParam);
-
- TemplateParameterList *FirstTPL =
- FirstTTPD->getTemplateParameters();
- TemplateParameterList *SecondTPL =
- SecondTTPD->getTemplateParameters();
-
- if (ComputeTemplateParameterListODRHash(FirstTPL) !=
- ComputeTemplateParameterListODRHash(SecondTPL)) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentType)
- << FirstTemplate << (i + 1);
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentType)
- << SecondTemplate << (i + 1);
- ParameterMismatch = true;
- break;
- }
-
- bool HasFirstDefaultArgument =
- FirstTTPD->hasDefaultArgument() &&
- !FirstTTPD->defaultArgumentWasInherited();
- bool HasSecondDefaultArgument =
- SecondTTPD->hasDefaultArgument() &&
- !SecondTTPD->defaultArgumentWasInherited();
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterSingleDefaultArgument)
- << FirstTemplate << (i + 1) << HasFirstDefaultArgument;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterSingleDefaultArgument)
- << SecondTemplate << (i + 1) << HasSecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
-
- if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
- TemplateArgument FirstTA =
- FirstTTPD->getDefaultArgument().getArgument();
- TemplateArgument SecondTA =
- SecondTTPD->getDefaultArgument().getArgument();
- if (ComputeTemplateArgumentODRHash(FirstTA) !=
- ComputeTemplateArgumentODRHash(SecondTA)) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentDefaultArgument)
- << FirstTemplate << (i + 1) << FirstTA;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentDefaultArgument)
- << SecondTemplate << (i + 1) << SecondTA;
- ParameterMismatch = true;
- break;
- }
- }
-
- if (FirstTTPD->isParameterPack() !=
- SecondTTPD->isParameterPack()) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplatePackParameter)
- << FirstTemplate << (i + 1) << FirstTTPD->isParameterPack();
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplatePackParameter)
- << SecondTemplate << (i + 1) << SecondTTPD->isParameterPack();
- ParameterMismatch = true;
- break;
- }
- }
-
- if (isa<NonTypeTemplateParmDecl>(FirstParam) &&
- isa<NonTypeTemplateParmDecl>(SecondParam)) {
- NonTypeTemplateParmDecl *FirstNTTPD =
- cast<NonTypeTemplateParmDecl>(FirstParam);
- NonTypeTemplateParmDecl *SecondNTTPD =
- cast<NonTypeTemplateParmDecl>(SecondParam);
-
- QualType FirstType = FirstNTTPD->getType();
- QualType SecondType = SecondNTTPD->getType();
- if (ComputeQualTypeODRHash(FirstType) !=
- ComputeQualTypeODRHash(SecondType)) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentType)
- << FirstTemplate << (i + 1);
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentType)
- << SecondTemplate << (i + 1);
- ParameterMismatch = true;
- break;
- }
-
- bool HasFirstDefaultArgument =
- FirstNTTPD->hasDefaultArgument() &&
- !FirstNTTPD->defaultArgumentWasInherited();
- bool HasSecondDefaultArgument =
- SecondNTTPD->hasDefaultArgument() &&
- !SecondNTTPD->defaultArgumentWasInherited();
- if (HasFirstDefaultArgument != HasSecondDefaultArgument) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterSingleDefaultArgument)
- << FirstTemplate << (i + 1) << HasFirstDefaultArgument;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterSingleDefaultArgument)
- << SecondTemplate << (i + 1) << HasSecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
-
- if (HasFirstDefaultArgument && HasSecondDefaultArgument) {
- Expr *FirstDefaultArgument = FirstNTTPD->getDefaultArgument();
- Expr *SecondDefaultArgument = SecondNTTPD->getDefaultArgument();
- if (ComputeODRHash(FirstDefaultArgument) !=
- ComputeODRHash(SecondDefaultArgument)) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentDefaultArgument)
- << FirstTemplate << (i + 1) << FirstDefaultArgument;
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplateParameterDifferentDefaultArgument)
- << SecondTemplate << (i + 1) << SecondDefaultArgument;
- ParameterMismatch = true;
- break;
- }
- }
-
- if (FirstNTTPD->isParameterPack() !=
- SecondNTTPD->isParameterPack()) {
- ODRDiagError(FirstTemplate->getLocation(),
- FirstTemplate->getSourceRange(),
- FunctionTemplatePackParameter)
- << FirstTemplate << (i + 1) << FirstNTTPD->isParameterPack();
- ODRDiagNote(SecondTemplate->getLocation(),
- SecondTemplate->getSourceRange(),
- FunctionTemplatePackParameter)
- << SecondTemplate << (i + 1)
- << SecondNTTPD->isParameterPack();
- ParameterMismatch = true;
- break;
- }
- }
- }
-
- if (ParameterMismatch) {
- Diagnosed = true;
- break;
- }
-
- break;
- }
- }
-
- if (Diagnosed)
- continue;
-
- Diag(FirstDecl->getLocation(),
- diag::err_module_odr_violation_mismatch_decl_unknown)
- << FirstRecord << FirstModule.empty() << FirstModule << FirstDiffType
- << FirstDecl->getSourceRange();
- Diag(SecondDecl->getLocation(),
- diag::note_module_odr_violation_mismatch_decl_unknown)
- << SecondModule << FirstDiffType << SecondDecl->getSourceRange();
- Diagnosed = true;
- }
-
- if (!Diagnosed) {
- // All definitions are updates to the same declaration. This happens if a
- // module instantiates the declaration of a class template specialization
- // and two or more other modules instantiate its definition.
- //
- // FIXME: Indicate which modules had instantiations of this definition.
- // FIXME: How can this even happen?
- Diag(Merge.first->getLocation(),
- diag::err_module_odr_violation_different_instantiations)
- << Merge.first;
- }
- }
-
- // Issue ODR failures diagnostics for functions.
- for (auto &Merge : FunctionOdrMergeFailures) {
- enum ODRFunctionDifference {
- ReturnType,
- ParameterName,
- ParameterType,
- ParameterSingleDefaultArgument,
- ParameterDifferentDefaultArgument,
- FunctionBody,
- };
-
- FunctionDecl *FirstFunction = Merge.first;
- std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);
-
- bool Diagnosed = false;
- for (auto &SecondFunction : Merge.second) {
-
- if (FirstFunction == SecondFunction)
- continue;
-
- std::string SecondModule =
- getOwningModuleNameForDiagnostic(SecondFunction);
-
- auto ODRDiagError = [FirstFunction, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODRFunctionDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_function)
- << FirstFunction << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagNote = [&SecondModule, this](SourceLocation Loc,
- SourceRange Range,
- ODRFunctionDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_function)
- << SecondModule << Range << DiffType;
- };
-
- if (ComputeQualTypeODRHash(FirstFunction->getReturnType()) !=
- ComputeQualTypeODRHash(SecondFunction->getReturnType())) {
- ODRDiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),
- FirstFunction->getReturnTypeSourceRange(), ReturnType)
- << FirstFunction->getReturnType();
- ODRDiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),
- SecondFunction->getReturnTypeSourceRange(), ReturnType)
- << SecondFunction->getReturnType();
- Diagnosed = true;
- break;
- }
-
- assert(FirstFunction->param_size() == SecondFunction->param_size() &&
- "Merged functions with different number of parameters");
-
- auto ParamSize = FirstFunction->param_size();
- bool ParameterMismatch = false;
- for (unsigned I = 0; I < ParamSize; ++I) {
- auto *FirstParam = FirstFunction->getParamDecl(I);
- auto *SecondParam = SecondFunction->getParamDecl(I);
-
- assert(getContext().hasSameType(FirstParam->getType(),
- SecondParam->getType()) &&
- "Merged function has different parameter types.");
-
- if (FirstParam->getDeclName() != SecondParam->getDeclName()) {
- ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
- ParameterName)
- << I + 1 << FirstParam->getDeclName();
- ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
- ParameterName)
- << I + 1 << SecondParam->getDeclName();
- ParameterMismatch = true;
- break;
- };
-
- QualType FirstParamType = FirstParam->getType();
- QualType SecondParamType = SecondParam->getType();
- if (FirstParamType != SecondParamType &&
- ComputeQualTypeODRHash(FirstParamType) !=
- ComputeQualTypeODRHash(SecondParamType)) {
- if (const DecayedType *ParamDecayedType =
- FirstParamType->getAs<DecayedType>()) {
- ODRDiagError(FirstParam->getLocation(),
- FirstParam->getSourceRange(), ParameterType)
- << (I + 1) << FirstParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- ODRDiagError(FirstParam->getLocation(),
- FirstParam->getSourceRange(), ParameterType)
- << (I + 1) << FirstParamType << false;
- }
-
- if (const DecayedType *ParamDecayedType =
- SecondParamType->getAs<DecayedType>()) {
- ODRDiagNote(SecondParam->getLocation(),
- SecondParam->getSourceRange(), ParameterType)
- << (I + 1) << SecondParamType << true
- << ParamDecayedType->getOriginalType();
- } else {
- ODRDiagNote(SecondParam->getLocation(),
- SecondParam->getSourceRange(), ParameterType)
- << (I + 1) << SecondParamType << false;
- }
- ParameterMismatch = true;
- break;
- }
-
- const Expr *FirstInit = FirstParam->getInit();
- const Expr *SecondInit = SecondParam->getInit();
- if ((FirstInit == nullptr) != (SecondInit == nullptr)) {
- ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
- ParameterSingleDefaultArgument)
- << (I + 1) << (FirstInit == nullptr)
- << (FirstInit ? FirstInit->getSourceRange() : SourceRange());
- ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
- ParameterSingleDefaultArgument)
- << (I + 1) << (SecondInit == nullptr)
- << (SecondInit ? SecondInit->getSourceRange() : SourceRange());
- ParameterMismatch = true;
- break;
- }
-
- if (FirstInit && SecondInit &&
- ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
- ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),
- ParameterDifferentDefaultArgument)
- << (I + 1) << FirstInit->getSourceRange();
- ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),
- ParameterDifferentDefaultArgument)
- << (I + 1) << SecondInit->getSourceRange();
- ParameterMismatch = true;
- break;
- }
-
- assert(ComputeSubDeclODRHash(FirstParam) ==
- ComputeSubDeclODRHash(SecondParam) &&
- "Undiagnosed parameter difference.");
- }
-
- if (ParameterMismatch) {
- Diagnosed = true;
- break;
- }
-
- // If no error has been generated before now, assume the problem is in
- // the body and generate a message.
- ODRDiagError(FirstFunction->getLocation(),
- FirstFunction->getSourceRange(), FunctionBody);
- ODRDiagNote(SecondFunction->getLocation(),
- SecondFunction->getSourceRange(), FunctionBody);
- Diagnosed = true;
- break;
- }
- (void)Diagnosed;
- assert(Diagnosed && "Unable to emit ODR diagnostic.");
- }
-
- // Issue ODR failures diagnostics for enums.
- for (auto &Merge : EnumOdrMergeFailures) {
- enum ODREnumDifference {
- SingleScopedEnum,
- EnumTagKeywordMismatch,
- SingleSpecifiedType,
- DifferentSpecifiedTypes,
- DifferentNumberEnumConstants,
- EnumConstantName,
- EnumConstantSingleInitilizer,
- EnumConstantDifferentInitilizer,
- };
-
- // If we've already pointed out a specific problem with this enum, don't
- // bother issuing a general "something's different" diagnostic.
- if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)
- continue;
-
- EnumDecl *FirstEnum = Merge.first;
- std::string FirstModule = getOwningModuleNameForDiagnostic(FirstEnum);
-
- using DeclHashes =
- llvm::SmallVector<std::pair<EnumConstantDecl *, unsigned>, 4>;
- auto PopulateHashes = [&ComputeSubDeclODRHash, FirstEnum](
- DeclHashes &Hashes, EnumDecl *Enum) {
- for (auto *D : Enum->decls()) {
- // Due to decl merging, the first EnumDecl is the parent of
- // Decls in both records.
- if (!ODRHash::isWhitelistedDecl(D, FirstEnum))
- continue;
- assert(isa<EnumConstantDecl>(D) && "Unexpected Decl kind");
- Hashes.emplace_back(cast<EnumConstantDecl>(D),
- ComputeSubDeclODRHash(D));
- }
- };
- DeclHashes FirstHashes;
- PopulateHashes(FirstHashes, FirstEnum);
- bool Diagnosed = false;
- for (auto &SecondEnum : Merge.second) {
-
- if (FirstEnum == SecondEnum)
- continue;
-
- std::string SecondModule =
- getOwningModuleNameForDiagnostic(SecondEnum);
-
- auto ODRDiagError = [FirstEnum, &FirstModule,
- this](SourceLocation Loc, SourceRange Range,
- ODREnumDifference DiffType) {
- return Diag(Loc, diag::err_module_odr_violation_enum)
- << FirstEnum << FirstModule.empty() << FirstModule << Range
- << DiffType;
- };
- auto ODRDiagNote = [&SecondModule, this](SourceLocation Loc,
- SourceRange Range,
- ODREnumDifference DiffType) {
- return Diag(Loc, diag::note_module_odr_violation_enum)
- << SecondModule << Range << DiffType;
- };
-
- if (FirstEnum->isScoped() != SecondEnum->isScoped()) {
- ODRDiagError(FirstEnum->getLocation(), FirstEnum->getSourceRange(),
- SingleScopedEnum)
- << FirstEnum->isScoped();
- ODRDiagNote(SecondEnum->getLocation(), SecondEnum->getSourceRange(),
- SingleScopedEnum)
- << SecondEnum->isScoped();
- Diagnosed = true;
- continue;
- }
-
- if (FirstEnum->isScoped() && SecondEnum->isScoped()) {
- if (FirstEnum->isScopedUsingClassTag() !=
- SecondEnum->isScopedUsingClassTag()) {
- ODRDiagError(FirstEnum->getLocation(), FirstEnum->getSourceRange(),
- EnumTagKeywordMismatch)
- << FirstEnum->isScopedUsingClassTag();
- ODRDiagNote(SecondEnum->getLocation(), SecondEnum->getSourceRange(),
- EnumTagKeywordMismatch)
- << SecondEnum->isScopedUsingClassTag();
- Diagnosed = true;
- continue;
- }
- }
-
- QualType FirstUnderlyingType =
- FirstEnum->getIntegerTypeSourceInfo()
- ? FirstEnum->getIntegerTypeSourceInfo()->getType()
- : QualType();
- QualType SecondUnderlyingType =
- SecondEnum->getIntegerTypeSourceInfo()
- ? SecondEnum->getIntegerTypeSourceInfo()->getType()
- : QualType();
- if (FirstUnderlyingType.isNull() != SecondUnderlyingType.isNull()) {
- ODRDiagError(FirstEnum->getLocation(), FirstEnum->getSourceRange(),
- SingleSpecifiedType)
- << !FirstUnderlyingType.isNull();
- ODRDiagNote(SecondEnum->getLocation(), SecondEnum->getSourceRange(),
- SingleSpecifiedType)
- << !SecondUnderlyingType.isNull();
- Diagnosed = true;
- continue;
- }
-
- if (!FirstUnderlyingType.isNull() && !SecondUnderlyingType.isNull()) {
- if (ComputeQualTypeODRHash(FirstUnderlyingType) !=
- ComputeQualTypeODRHash(SecondUnderlyingType)) {
- ODRDiagError(FirstEnum->getLocation(), FirstEnum->getSourceRange(),
- DifferentSpecifiedTypes)
- << FirstUnderlyingType;
- ODRDiagNote(SecondEnum->getLocation(), SecondEnum->getSourceRange(),
- DifferentSpecifiedTypes)
- << SecondUnderlyingType;
- Diagnosed = true;
- continue;
- }
- }
-
- DeclHashes SecondHashes;
- PopulateHashes(SecondHashes, SecondEnum);
-
- if (FirstHashes.size() != SecondHashes.size()) {
- ODRDiagError(FirstEnum->getLocation(), FirstEnum->getSourceRange(),
- DifferentNumberEnumConstants)
- << (int)FirstHashes.size();
- ODRDiagNote(SecondEnum->getLocation(), SecondEnum->getSourceRange(),
- DifferentNumberEnumConstants)
- << (int)SecondHashes.size();
- Diagnosed = true;
- continue;
- }
-
- for (unsigned I = 0; I < FirstHashes.size(); ++I) {
- if (FirstHashes[I].second == SecondHashes[I].second)
- continue;
- const EnumConstantDecl *FirstEnumConstant = FirstHashes[I].first;
- const EnumConstantDecl *SecondEnumConstant = SecondHashes[I].first;
-
- if (FirstEnumConstant->getDeclName() !=
- SecondEnumConstant->getDeclName()) {
-
- ODRDiagError(FirstEnumConstant->getLocation(),
- FirstEnumConstant->getSourceRange(), EnumConstantName)
- << I + 1 << FirstEnumConstant;
- ODRDiagNote(SecondEnumConstant->getLocation(),
- SecondEnumConstant->getSourceRange(), EnumConstantName)
- << I + 1 << SecondEnumConstant;
- Diagnosed = true;
- break;
- }
-
- const Expr *FirstInit = FirstEnumConstant->getInitExpr();
- const Expr *SecondInit = SecondEnumConstant->getInitExpr();
- if (!FirstInit && !SecondInit)
- continue;
-
- if (!FirstInit || !SecondInit) {
- ODRDiagError(FirstEnumConstant->getLocation(),
- FirstEnumConstant->getSourceRange(),
- EnumConstantSingleInitilizer)
- << I + 1 << FirstEnumConstant << (FirstInit != nullptr);
- ODRDiagNote(SecondEnumConstant->getLocation(),
- SecondEnumConstant->getSourceRange(),
- EnumConstantSingleInitilizer)
- << I + 1 << SecondEnumConstant << (SecondInit != nullptr);
- Diagnosed = true;
- break;
- }
-
- if (ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
- ODRDiagError(FirstEnumConstant->getLocation(),
- FirstEnumConstant->getSourceRange(),
- EnumConstantDifferentInitilizer)
- << I + 1 << FirstEnumConstant;
- ODRDiagNote(SecondEnumConstant->getLocation(),
- SecondEnumConstant->getSourceRange(),
- EnumConstantDifferentInitilizer)
- << I + 1 << SecondEnumConstant;
- Diagnosed = true;
- break;
- }
- }
- }
-
- (void)Diagnosed;
- assert(Diagnosed && "Unable to emit ODR diagnostic.");
- }
-}
-
-void ASTReader::StartedDeserializing() {
- if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get())
- ReadTimer->startTimer();
-}
-
-void ASTReader::FinishedDeserializing() {
- assert(NumCurrentElementsDeserializing &&
- "FinishedDeserializing not paired with StartedDeserializing");
- if (NumCurrentElementsDeserializing == 1) {
- // We decrease NumCurrentElementsDeserializing only after pending actions
- // are finished, to avoid recursively re-calling finishPendingActions().
- finishPendingActions();
- }
- --NumCurrentElementsDeserializing;
-
- if (NumCurrentElementsDeserializing == 0) {
- // Propagate exception specification and deduced type updates along
- // redeclaration chains.
- //
- // We do this now rather than in finishPendingActions because we want to
- // be able to walk the complete redeclaration chains of the updated decls.
- while (!PendingExceptionSpecUpdates.empty() ||
- !PendingDeducedTypeUpdates.empty()) {
- auto ESUpdates = std::move(PendingExceptionSpecUpdates);
- PendingExceptionSpecUpdates.clear();
- for (auto Update : ESUpdates) {
- ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
- auto *FPT = Update.second->getType()->castAs<FunctionProtoType>();
- auto ESI = FPT->getExtProtoInfo().ExceptionSpec;
- if (auto *Listener = getContext().getASTMutationListener())
- Listener->ResolvedExceptionSpec(cast<FunctionDecl>(Update.second));
- for (auto *Redecl : Update.second->redecls())
- getContext().adjustExceptionSpec(cast<FunctionDecl>(Redecl), ESI);
- }
-
- auto DTUpdates = std::move(PendingDeducedTypeUpdates);
- PendingDeducedTypeUpdates.clear();
- for (auto Update : DTUpdates) {
- ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
- // FIXME: If the return type is already deduced, check that it matches.
- getContext().adjustDeducedFunctionResultType(Update.first,
- Update.second);
- }
- }
-
- if (ReadTimer)
- ReadTimer->stopTimer();
-
- diagnoseOdrViolations();
-
- // We are not in recursive loading, so it's safe to pass the "interesting"
- // decls to the consumer.
- if (Consumer)
- PassInterestingDeclsToConsumer();
- }
-}
-
-void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
- if (IdentifierInfo *II = Name.getAsIdentifierInfo()) {
- // Remove any fake results before adding any real ones.
- auto It = PendingFakeLookupResults.find(II);
- if (It != PendingFakeLookupResults.end()) {
- for (auto *ND : It->second)
- SemaObj->IdResolver.RemoveDecl(ND);
- // FIXME: this works around module+PCH performance issue.
- // Rather than erase the result from the map, which is O(n), just clear
- // the vector of NamedDecls.
- It->second.clear();
- }
- }
-
- if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) {
- SemaObj->TUScope->AddDecl(D);
- } else if (SemaObj->TUScope) {
- // Adding the decl to IdResolver may have failed because it was already in
- // (even though it was not added in scope). If it is already in, make sure
- // it gets in the scope as well.
- if (std::find(SemaObj->IdResolver.begin(Name),
- SemaObj->IdResolver.end(), D) != SemaObj->IdResolver.end())
- SemaObj->TUScope->AddDecl(D);
- }
-}
-
-ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
- const PCHContainerReader &PCHContainerRdr,
- ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- StringRef isysroot, bool DisableValidation,
- bool AllowASTWithCompilerErrors,
- bool AllowConfigurationMismatch, bool ValidateSystemInputs,
- bool UseGlobalIndex,
- std::unique_ptr<llvm::Timer> ReadTimer)
- : Listener(DisableValidation
- ? cast<ASTReaderListener>(new SimpleASTReaderListener(PP))
- : cast<ASTReaderListener>(new PCHValidator(PP, *this))),
- SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
- PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
- ContextObj(Context),
- ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr,
- PP.getHeaderSearchInfo()),
- PCMCache(PP.getPCMCache()), DummyIdResolver(PP),
- ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
- DisableValidation(DisableValidation),
- AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
- AllowConfigurationMismatch(AllowConfigurationMismatch),
- ValidateSystemInputs(ValidateSystemInputs),
- UseGlobalIndex(UseGlobalIndex), CurrSwitchCaseStmts(&SwitchCaseStmts) {
- SourceMgr.setExternalSLocEntrySource(this);
-
- for (const auto &Ext : Extensions) {
- auto BlockName = Ext->getExtensionMetadata().BlockName;
- auto Known = ModuleFileExtensions.find(BlockName);
- if (Known != ModuleFileExtensions.end()) {
- Diags.Report(diag::warn_duplicate_module_file_extension)
- << BlockName;
- continue;
- }
-
- ModuleFileExtensions.insert({BlockName, Ext});
- }
-}
-
-ASTReader::~ASTReader() {
- if (OwnsDeserializationListener)
- delete DeserializationListener;
-}
-
-IdentifierResolver &ASTReader::getIdResolver() {
- return SemaObj ? SemaObj->IdResolver : DummyIdResolver;
-}
-
-unsigned ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor,
- unsigned AbbrevID) {
- Idx = 0;
- Record.clear();
- return Cursor.readRecord(AbbrevID, Record);
-}
-//===----------------------------------------------------------------------===//
-//// OMPClauseReader implementation
-////===----------------------------------------------------------------------===//
-
-OMPClause *OMPClauseReader::readClause() {
- OMPClause *C;
- switch (Record.readInt()) {
- case OMPC_if:
- C = new (Context) OMPIfClause();
- break;
- case OMPC_final:
- C = new (Context) OMPFinalClause();
- break;
- case OMPC_num_threads:
- C = new (Context) OMPNumThreadsClause();
- break;
- case OMPC_safelen:
- C = new (Context) OMPSafelenClause();
- break;
- case OMPC_simdlen:
- C = new (Context) OMPSimdlenClause();
- break;
- case OMPC_collapse:
- C = new (Context) OMPCollapseClause();
- break;
- case OMPC_default:
- C = new (Context) OMPDefaultClause();
- break;
- case OMPC_proc_bind:
- C = new (Context) OMPProcBindClause();
- break;
- case OMPC_schedule:
- C = new (Context) OMPScheduleClause();
- break;
- case OMPC_ordered:
- C = OMPOrderedClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_nowait:
- C = new (Context) OMPNowaitClause();
- break;
- case OMPC_untied:
- C = new (Context) OMPUntiedClause();
- break;
- case OMPC_mergeable:
- C = new (Context) OMPMergeableClause();
- break;
- case OMPC_read:
- C = new (Context) OMPReadClause();
- break;
- case OMPC_write:
- C = new (Context) OMPWriteClause();
- break;
- case OMPC_update:
- C = new (Context) OMPUpdateClause();
- break;
- case OMPC_capture:
- C = new (Context) OMPCaptureClause();
- break;
- case OMPC_seq_cst:
- C = new (Context) OMPSeqCstClause();
- break;
- case OMPC_threads:
- C = new (Context) OMPThreadsClause();
- break;
- case OMPC_simd:
- C = new (Context) OMPSIMDClause();
- break;
- case OMPC_nogroup:
- C = new (Context) OMPNogroupClause();
- break;
- case OMPC_unified_address:
- C = new (Context) OMPUnifiedAddressClause();
- break;
- case OMPC_unified_shared_memory:
- C = new (Context) OMPUnifiedSharedMemoryClause();
- break;
- case OMPC_reverse_offload:
- C = new (Context) OMPReverseOffloadClause();
- break;
- case OMPC_dynamic_allocators:
- C = new (Context) OMPDynamicAllocatorsClause();
- break;
- case OMPC_atomic_default_mem_order:
- C = new (Context) OMPAtomicDefaultMemOrderClause();
- break;
- case OMPC_private:
- C = OMPPrivateClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_firstprivate:
- C = OMPFirstprivateClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_lastprivate:
- C = OMPLastprivateClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_shared:
- C = OMPSharedClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_reduction:
- C = OMPReductionClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_task_reduction:
- C = OMPTaskReductionClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_in_reduction:
- C = OMPInReductionClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_linear:
- C = OMPLinearClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_aligned:
- C = OMPAlignedClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_copyin:
- C = OMPCopyinClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_copyprivate:
- C = OMPCopyprivateClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_flush:
- C = OMPFlushClause::CreateEmpty(Context, Record.readInt());
- break;
- case OMPC_depend: {
- unsigned NumVars = Record.readInt();
- unsigned NumLoops = Record.readInt();
- C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops);
- break;
- }
- case OMPC_device:
- C = new (Context) OMPDeviceClause();
- break;
- case OMPC_map: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPMapClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
- NumComponents);
- break;
- }
- case OMPC_num_teams:
- C = new (Context) OMPNumTeamsClause();
- break;
- case OMPC_thread_limit:
- C = new (Context) OMPThreadLimitClause();
- break;
- case OMPC_priority:
- C = new (Context) OMPPriorityClause();
- break;
- case OMPC_grainsize:
- C = new (Context) OMPGrainsizeClause();
- break;
- case OMPC_num_tasks:
- C = new (Context) OMPNumTasksClause();
- break;
- case OMPC_hint:
- C = new (Context) OMPHintClause();
- break;
- case OMPC_dist_schedule:
- C = new (Context) OMPDistScheduleClause();
- break;
- case OMPC_defaultmap:
- C = new (Context) OMPDefaultmapClause();
- break;
- case OMPC_to: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPToClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
- NumComponents);
- break;
- }
- case OMPC_from: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPFromClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
- NumComponents);
- break;
- }
- case OMPC_use_device_ptr: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPUseDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations,
- NumLists, NumComponents);
- break;
- }
- case OMPC_is_device_ptr: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPIsDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations,
- NumLists, NumComponents);
- break;
- }
- }
- Visit(C);
- C->setLocStart(Record.readSourceLocation());
- C->setLocEnd(Record.readSourceLocation());
-
- return C;
-}
-
-void OMPClauseReader::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
- C->setPreInitStmt(Record.readSubStmt(),
- static_cast<OpenMPDirectiveKind>(Record.readInt()));
-}
-
-void OMPClauseReader::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) {
- VisitOMPClauseWithPreInit(C);
- C->setPostUpdateExpr(Record.readSubExpr());
-}
-
-void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setNameModifier(static_cast<OpenMPDirectiveKind>(Record.readInt()));
- C->setNameModifierLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- C->setCondition(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPFinalClause(OMPFinalClause *C) {
- C->setCondition(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setNumThreads(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPSafelenClause(OMPSafelenClause *C) {
- C->setSafelen(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
- C->setSimdlen(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) {
- C->setNumForLoops(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) {
- C->setDefaultKind(
- static_cast<OpenMPDefaultClauseKind>(Record.readInt()));
- C->setLParenLoc(Record.readSourceLocation());
- C->setDefaultKindKwLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
- C->setProcBindKind(
- static_cast<OpenMPProcBindClauseKind>(Record.readInt()));
- C->setLParenLoc(Record.readSourceLocation());
- C->setProcBindKindKwLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setScheduleKind(
- static_cast<OpenMPScheduleClauseKind>(Record.readInt()));
- C->setFirstScheduleModifier(
- static_cast<OpenMPScheduleClauseModifier>(Record.readInt()));
- C->setSecondScheduleModifier(
- static_cast<OpenMPScheduleClauseModifier>(Record.readInt()));
- C->setChunkSize(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
- C->setFirstScheduleModifierLoc(Record.readSourceLocation());
- C->setSecondScheduleModifierLoc(Record.readSourceLocation());
- C->setScheduleKindLoc(Record.readSourceLocation());
- C->setCommaLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *C) {
- C->setNumForLoops(Record.readSubExpr());
- for (unsigned I = 0, E = C->NumberOfLoops; I < E; ++I)
- C->setLoopNumIterations(I, Record.readSubExpr());
- for (unsigned I = 0, E = C->NumberOfLoops; I < E; ++I)
- C->setLoopCounter(I, Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *) {}
-
-void OMPClauseReader::VisitOMPUntiedClause(OMPUntiedClause *) {}
-
-void OMPClauseReader::VisitOMPMergeableClause(OMPMergeableClause *) {}
-
-void OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {}
-
-void OMPClauseReader::VisitOMPWriteClause(OMPWriteClause *) {}
-
-void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *) {}
-
-void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {}
-
-void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
-
-void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
-
-void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
-
-void OMPClauseReader::VisitOMPNogroupClause(OMPNogroupClause *) {}
-
-void OMPClauseReader::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
-
-void OMPClauseReader::VisitOMPUnifiedSharedMemoryClause(
- OMPUnifiedSharedMemoryClause *) {}
-
-void OMPClauseReader::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {}
-
-void
-OMPClauseReader::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) {
-}
-
-void OMPClauseReader::VisitOMPAtomicDefaultMemOrderClause(
- OMPAtomicDefaultMemOrderClause *C) {
- C->setAtomicDefaultMemOrderKind(
- static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Record.readInt()));
- C->setLParenLoc(Record.readSourceLocation());
- C->setAtomicDefaultMemOrderKindKwLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setPrivateCopies(Vars);
-}
-
-void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setPrivateCopies(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setInits(Vars);
-}
-
-void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
- VisitOMPClauseWithPostUpdate(C);
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setPrivateCopies(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setSourceExprs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setDestinationExprs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setAssignmentOps(Vars);
-}
-
-void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
-}
-
-void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
- VisitOMPClauseWithPostUpdate(C);
- C->setLParenLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- NestedNameSpecifierLoc NNSL = Record.readNestedNameSpecifierLoc();
- DeclarationNameInfo DNI;
- Record.readDeclarationNameInfo(DNI);
- C->setQualifierLoc(NNSL);
- C->setNameInfo(DNI);
-
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setPrivates(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setLHSExprs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setRHSExprs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setReductionOps(Vars);
-}
-
-void OMPClauseReader::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
- VisitOMPClauseWithPostUpdate(C);
- C->setLParenLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- NestedNameSpecifierLoc NNSL = Record.readNestedNameSpecifierLoc();
- DeclarationNameInfo DNI;
- Record.readDeclarationNameInfo(DNI);
- C->setQualifierLoc(NNSL);
- C->setNameInfo(DNI);
-
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setPrivates(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setLHSExprs(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setRHSExprs(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setReductionOps(Vars);
-}
-
-void OMPClauseReader::VisitOMPInReductionClause(OMPInReductionClause *C) {
- VisitOMPClauseWithPostUpdate(C);
- C->setLParenLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- NestedNameSpecifierLoc NNSL = Record.readNestedNameSpecifierLoc();
- DeclarationNameInfo DNI;
- Record.readDeclarationNameInfo(DNI);
- C->setQualifierLoc(NNSL);
- C->setNameInfo(DNI);
-
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setPrivates(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setLHSExprs(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setRHSExprs(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setReductionOps(Vars);
- Vars.clear();
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setTaskgroupDescriptors(Vars);
-}
-
-void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
- VisitOMPClauseWithPostUpdate(C);
- C->setLParenLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- C->setModifier(static_cast<OpenMPLinearClauseKind>(Record.readInt()));
- C->setModifierLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setPrivates(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setInits(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setUpdates(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setFinals(Vars);
- C->setStep(Record.readSubExpr());
- C->setCalcStep(Record.readSubExpr());
-}
-
-void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- C->setAlignment(Record.readSubExpr());
-}
-
-void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Exprs;
- Exprs.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setVarRefs(Exprs);
- Exprs.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setSourceExprs(Exprs);
- Exprs.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setDestinationExprs(Exprs);
- Exprs.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setAssignmentOps(Exprs);
-}
-
-void OMPClauseReader::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Exprs;
- Exprs.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setVarRefs(Exprs);
- Exprs.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setSourceExprs(Exprs);
- Exprs.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setDestinationExprs(Exprs);
- Exprs.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Exprs.push_back(Record.readSubExpr());
- C->setAssignmentOps(Exprs);
-}
-
-void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
-}
-
-void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- C->setDependencyKind(
- static_cast<OpenMPDependClauseKind>(Record.readInt()));
- C->setDependencyLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- unsigned NumVars = C->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned I = 0; I != NumVars; ++I)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
- C->setLoopData(I, Record.readSubExpr());
-}
-
-void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setDevice(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) {
- C->setMapTypeModifier(
- I, static_cast<OpenMPMapModifierKind>(Record.readInt()));
- C->setMapTypeModifierLoc(I, Record.readSourceLocation());
- }
- C->setMapType(
- static_cast<OpenMPMapClauseKind>(Record.readInt()));
- C->setMapLoc(Record.readSourceLocation());
- C->setColonLoc(Record.readSourceLocation());
- auto NumVars = C->varlist_size();
- auto UniqueDecls = C->getUniqueDeclarationsNum();
- auto TotalLists = C->getTotalComponentListNum();
- auto TotalComponents = C->getTotalComponentsNum();
-
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
-
- SmallVector<ValueDecl *, 16> Decls;
- Decls.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- Decls.push_back(Record.readDeclAs<ValueDecl>());
- C->setUniqueDecls(Decls);
-
- SmallVector<unsigned, 16> ListsPerDecl;
- ListsPerDecl.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- ListsPerDecl.push_back(Record.readInt());
- C->setDeclNumLists(ListsPerDecl);
-
- SmallVector<unsigned, 32> ListSizes;
- ListSizes.reserve(TotalLists);
- for (unsigned i = 0; i < TotalLists; ++i)
- ListSizes.push_back(Record.readInt());
- C->setComponentListSizes(ListSizes);
-
- SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
- Components.reserve(TotalComponents);
- for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
- auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
- Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
- AssociatedExpr, AssociatedDecl));
- }
- C->setComponents(Components, ListSizes);
-}
-
-void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setNumTeams(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setThreadLimit(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPPriorityClause(OMPPriorityClause *C) {
- C->setPriority(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
- C->setGrainsize(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
- C->setNumTasks(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPHintClause(OMPHintClause *C) {
- C->setHint(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) {
- VisitOMPClauseWithPreInit(C);
- C->setDistScheduleKind(
- static_cast<OpenMPDistScheduleClauseKind>(Record.readInt()));
- C->setChunkSize(Record.readSubExpr());
- C->setLParenLoc(Record.readSourceLocation());
- C->setDistScheduleKindLoc(Record.readSourceLocation());
- C->setCommaLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
- C->setDefaultmapKind(
- static_cast<OpenMPDefaultmapClauseKind>(Record.readInt()));
- C->setDefaultmapModifier(
- static_cast<OpenMPDefaultmapClauseModifier>(Record.readInt()));
- C->setLParenLoc(Record.readSourceLocation());
- C->setDefaultmapModifierLoc(Record.readSourceLocation());
- C->setDefaultmapKindLoc(Record.readSourceLocation());
-}
-
-void OMPClauseReader::VisitOMPToClause(OMPToClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- auto NumVars = C->varlist_size();
- auto UniqueDecls = C->getUniqueDeclarationsNum();
- auto TotalLists = C->getTotalComponentListNum();
- auto TotalComponents = C->getTotalComponentsNum();
-
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
-
- SmallVector<ValueDecl *, 16> Decls;
- Decls.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- Decls.push_back(Record.readDeclAs<ValueDecl>());
- C->setUniqueDecls(Decls);
-
- SmallVector<unsigned, 16> ListsPerDecl;
- ListsPerDecl.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- ListsPerDecl.push_back(Record.readInt());
- C->setDeclNumLists(ListsPerDecl);
-
- SmallVector<unsigned, 32> ListSizes;
- ListSizes.reserve(TotalLists);
- for (unsigned i = 0; i < TotalLists; ++i)
- ListSizes.push_back(Record.readInt());
- C->setComponentListSizes(ListSizes);
-
- SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
- Components.reserve(TotalComponents);
- for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
- auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
- Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
- AssociatedExpr, AssociatedDecl));
- }
- C->setComponents(Components, ListSizes);
-}
-
-void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- auto NumVars = C->varlist_size();
- auto UniqueDecls = C->getUniqueDeclarationsNum();
- auto TotalLists = C->getTotalComponentListNum();
- auto TotalComponents = C->getTotalComponentsNum();
-
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
-
- SmallVector<ValueDecl *, 16> Decls;
- Decls.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- Decls.push_back(Record.readDeclAs<ValueDecl>());
- C->setUniqueDecls(Decls);
-
- SmallVector<unsigned, 16> ListsPerDecl;
- ListsPerDecl.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- ListsPerDecl.push_back(Record.readInt());
- C->setDeclNumLists(ListsPerDecl);
-
- SmallVector<unsigned, 32> ListSizes;
- ListSizes.reserve(TotalLists);
- for (unsigned i = 0; i < TotalLists; ++i)
- ListSizes.push_back(Record.readInt());
- C->setComponentListSizes(ListSizes);
-
- SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
- Components.reserve(TotalComponents);
- for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
- auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
- Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
- AssociatedExpr, AssociatedDecl));
- }
- C->setComponents(Components, ListSizes);
-}
-
-void OMPClauseReader::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- auto NumVars = C->varlist_size();
- auto UniqueDecls = C->getUniqueDeclarationsNum();
- auto TotalLists = C->getTotalComponentListNum();
- auto TotalComponents = C->getTotalComponentsNum();
-
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setPrivateCopies(Vars);
- Vars.clear();
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setInits(Vars);
-
- SmallVector<ValueDecl *, 16> Decls;
- Decls.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- Decls.push_back(Record.readDeclAs<ValueDecl>());
- C->setUniqueDecls(Decls);
-
- SmallVector<unsigned, 16> ListsPerDecl;
- ListsPerDecl.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- ListsPerDecl.push_back(Record.readInt());
- C->setDeclNumLists(ListsPerDecl);
-
- SmallVector<unsigned, 32> ListSizes;
- ListSizes.reserve(TotalLists);
- for (unsigned i = 0; i < TotalLists; ++i)
- ListSizes.push_back(Record.readInt());
- C->setComponentListSizes(ListSizes);
-
- SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
- Components.reserve(TotalComponents);
- for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
- auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
- Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
- AssociatedExpr, AssociatedDecl));
- }
- C->setComponents(Components, ListSizes);
-}
-
-void OMPClauseReader::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
- C->setLParenLoc(Record.readSourceLocation());
- auto NumVars = C->varlist_size();
- auto UniqueDecls = C->getUniqueDeclarationsNum();
- auto TotalLists = C->getTotalComponentListNum();
- auto TotalComponents = C->getTotalComponentsNum();
-
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
- C->setVarRefs(Vars);
- Vars.clear();
-
- SmallVector<ValueDecl *, 16> Decls;
- Decls.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- Decls.push_back(Record.readDeclAs<ValueDecl>());
- C->setUniqueDecls(Decls);
-
- SmallVector<unsigned, 16> ListsPerDecl;
- ListsPerDecl.reserve(UniqueDecls);
- for (unsigned i = 0; i < UniqueDecls; ++i)
- ListsPerDecl.push_back(Record.readInt());
- C->setDeclNumLists(ListsPerDecl);
-
- SmallVector<unsigned, 32> ListSizes;
- ListSizes.reserve(TotalLists);
- for (unsigned i = 0; i < TotalLists; ++i)
- ListSizes.push_back(Record.readInt());
- C->setComponentListSizes(ListSizes);
-
- SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
- Components.reserve(TotalComponents);
- for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
- auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
- Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
- AssociatedExpr, AssociatedDecl));
- }
- C->setComponents(Components, ListSizes);
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp
deleted file mode 100644
index 763ab527570..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp
+++ /dev/null
@@ -1,4471 +0,0 @@
-//===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the ASTReader::ReadDeclRecord method, which is the
-// entrypoint for loading a decl.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTCommon.h"
-#include "ASTReaderInternals.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/AttrIterator.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/LambdaCapture.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/OpenMPClause.h"
-#include "clang/AST/Redeclarable.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/AttrKinds.h"
-#include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Lambda.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/PragmaKinds.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Sema/IdentifierResolver.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/ASTReader.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "clang/Serialization/Module.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/SaveAndRestore.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-#include <string>
-#include <utility>
-
-using namespace clang;
-using namespace serialization;
-
-//===----------------------------------------------------------------------===//
-// Declaration deserialization
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-
- class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
- ASTReader &Reader;
- ASTRecordReader &Record;
- ASTReader::RecordLocation Loc;
- const DeclID ThisDeclID;
- const SourceLocation ThisDeclLoc;
-
- using RecordData = ASTReader::RecordData;
-
- TypeID DeferredTypeID = 0;
- unsigned AnonymousDeclNumber;
- GlobalDeclID NamedDeclForTagDecl = 0;
- IdentifierInfo *TypedefNameForLinkage = nullptr;
-
- bool HasPendingBody = false;
-
- ///A flag to carry the information for a decl from the entity is
- /// used. We use it to delay the marking of the canonical decl as used until
- /// the entire declaration is deserialized and merged.
- bool IsDeclMarkedUsed = false;
-
- uint64_t GetCurrentCursorOffset();
-
- uint64_t ReadLocalOffset() {
- uint64_t LocalOffset = Record.readInt();
- assert(LocalOffset < Loc.Offset && "offset point after current record");
- return LocalOffset ? Loc.Offset - LocalOffset : 0;
- }
-
- uint64_t ReadGlobalOffset() {
- uint64_t Local = ReadLocalOffset();
- return Local ? Record.getGlobalBitOffset(Local) : 0;
- }
-
- SourceLocation ReadSourceLocation() {
- return Record.readSourceLocation();
- }
-
- SourceRange ReadSourceRange() {
- return Record.readSourceRange();
- }
-
- TypeSourceInfo *GetTypeSourceInfo() {
- return Record.getTypeSourceInfo();
- }
-
- serialization::DeclID ReadDeclID() {
- return Record.readDeclID();
- }
-
- std::string ReadString() {
- return Record.readString();
- }
-
- void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) {
- for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I)
- IDs.push_back(ReadDeclID());
- }
-
- Decl *ReadDecl() {
- return Record.readDecl();
- }
-
- template<typename T>
- T *ReadDeclAs() {
- return Record.readDeclAs<T>();
- }
-
- void ReadQualifierInfo(QualifierInfo &Info) {
- Record.readQualifierInfo(Info);
- }
-
- void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) {
- Record.readDeclarationNameLoc(DNLoc, Name);
- }
-
- serialization::SubmoduleID readSubmoduleID() {
- if (Record.getIdx() == Record.size())
- return 0;
-
- return Record.getGlobalSubmoduleID(Record.readInt());
- }
-
- Module *readModule() {
- return Record.getSubmodule(readSubmoduleID());
- }
-
- void ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update);
- void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,
- const CXXRecordDecl *D);
- void MergeDefinitionData(CXXRecordDecl *D,
- struct CXXRecordDecl::DefinitionData &&NewDD);
- void ReadObjCDefinitionData(struct ObjCInterfaceDecl::DefinitionData &Data);
- void MergeDefinitionData(ObjCInterfaceDecl *D,
- struct ObjCInterfaceDecl::DefinitionData &&NewDD);
- void ReadObjCDefinitionData(struct ObjCProtocolDecl::DefinitionData &Data);
- void MergeDefinitionData(ObjCProtocolDecl *D,
- struct ObjCProtocolDecl::DefinitionData &&NewDD);
-
- static DeclContext *getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC);
-
- static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader,
- DeclContext *DC,
- unsigned Index);
- static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC,
- unsigned Index, NamedDecl *D);
-
- /// Results from loading a RedeclarableDecl.
- class RedeclarableResult {
- Decl *MergeWith;
- GlobalDeclID FirstID;
- bool IsKeyDecl;
-
- public:
- RedeclarableResult(Decl *MergeWith, GlobalDeclID FirstID, bool IsKeyDecl)
- : MergeWith(MergeWith), FirstID(FirstID), IsKeyDecl(IsKeyDecl) {}
-
- /// Retrieve the first ID.
- GlobalDeclID getFirstID() const { return FirstID; }
-
- /// Is this declaration a key declaration?
- bool isKeyDecl() const { return IsKeyDecl; }
-
- /// Get a known declaration that this should be merged with, if
- /// any.
- Decl *getKnownMergeTarget() const { return MergeWith; }
- };
-
- /// Class used to capture the result of searching for an existing
- /// declaration of a specific kind and name, along with the ability
- /// to update the place where this result was found (the declaration
- /// chain hanging off an identifier or the DeclContext we searched in)
- /// if requested.
- class FindExistingResult {
- ASTReader &Reader;
- NamedDecl *New = nullptr;
- NamedDecl *Existing = nullptr;
- bool AddResult = false;
- unsigned AnonymousDeclNumber = 0;
- IdentifierInfo *TypedefNameForLinkage = nullptr;
-
- public:
- FindExistingResult(ASTReader &Reader) : Reader(Reader) {}
-
- FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing,
- unsigned AnonymousDeclNumber,
- IdentifierInfo *TypedefNameForLinkage)
- : Reader(Reader), New(New), Existing(Existing), AddResult(true),
- AnonymousDeclNumber(AnonymousDeclNumber),
- TypedefNameForLinkage(TypedefNameForLinkage) {}
-
- FindExistingResult(FindExistingResult &&Other)
- : Reader(Other.Reader), New(Other.New), Existing(Other.Existing),
- AddResult(Other.AddResult),
- AnonymousDeclNumber(Other.AnonymousDeclNumber),
- TypedefNameForLinkage(Other.TypedefNameForLinkage) {
- Other.AddResult = false;
- }
-
- FindExistingResult &operator=(FindExistingResult &&) = delete;
- ~FindExistingResult();
-
- /// Suppress the addition of this result into the known set of
- /// names.
- void suppress() { AddResult = false; }
-
- operator NamedDecl*() const { return Existing; }
-
- template<typename T>
- operator T*() const { return dyn_cast_or_null<T>(Existing); }
- };
-
- static DeclContext *getPrimaryContextForMerging(ASTReader &Reader,
- DeclContext *DC);
- FindExistingResult findExisting(NamedDecl *D);
-
- public:
- ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record,
- ASTReader::RecordLocation Loc,
- DeclID thisDeclID, SourceLocation ThisDeclLoc)
- : Reader(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID),
- ThisDeclLoc(ThisDeclLoc) {}
-
- template <typename T> static
- void AddLazySpecializations(T *D,
- SmallVectorImpl<serialization::DeclID>& IDs) {
- if (IDs.empty())
- return;
-
- // FIXME: We should avoid this pattern of getting the ASTContext.
- ASTContext &C = D->getASTContext();
-
- auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations;
-
- if (auto &Old = LazySpecializations) {
- IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
- llvm::sort(IDs);
- IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
- }
-
- auto *Result = new (C) serialization::DeclID[1 + IDs.size()];
- *Result = IDs.size();
- std::copy(IDs.begin(), IDs.end(), Result + 1);
-
- LazySpecializations = Result;
- }
-
- template <typename DeclT>
- static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
- static Decl *getMostRecentDeclImpl(...);
- static Decl *getMostRecentDecl(Decl *D);
-
- template <typename DeclT>
- static void attachPreviousDeclImpl(ASTReader &Reader,
- Redeclarable<DeclT> *D, Decl *Previous,
- Decl *Canon);
- static void attachPreviousDeclImpl(ASTReader &Reader, ...);
- static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous,
- Decl *Canon);
-
- template <typename DeclT>
- static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest);
- static void attachLatestDeclImpl(...);
- static void attachLatestDecl(Decl *D, Decl *latest);
-
- template <typename DeclT>
- static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
- static void markIncompleteDeclChainImpl(...);
-
- /// Determine whether this declaration has a pending body.
- bool hasPendingBody() const { return HasPendingBody; }
-
- void ReadFunctionDefinition(FunctionDecl *FD);
- void Visit(Decl *D);
-
- void UpdateDecl(Decl *D, SmallVectorImpl<serialization::DeclID> &);
-
- static void setNextObjCCategory(ObjCCategoryDecl *Cat,
- ObjCCategoryDecl *Next) {
- Cat->NextClassCategory = Next;
- }
-
- void VisitDecl(Decl *D);
- void VisitPragmaCommentDecl(PragmaCommentDecl *D);
- void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D);
- void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
- void VisitNamedDecl(NamedDecl *ND);
- void VisitLabelDecl(LabelDecl *LD);
- void VisitNamespaceDecl(NamespaceDecl *D);
- void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
- void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- void VisitTypeDecl(TypeDecl *TD);
- RedeclarableResult VisitTypedefNameDecl(TypedefNameDecl *TD);
- void VisitTypedefDecl(TypedefDecl *TD);
- void VisitTypeAliasDecl(TypeAliasDecl *TD);
- void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
- RedeclarableResult VisitTagDecl(TagDecl *TD);
- void VisitEnumDecl(EnumDecl *ED);
- RedeclarableResult VisitRecordDeclImpl(RecordDecl *RD);
- void VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); }
- RedeclarableResult VisitCXXRecordDeclImpl(CXXRecordDecl *D);
- void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); }
- RedeclarableResult VisitClassTemplateSpecializationDeclImpl(
- ClassTemplateSpecializationDecl *D);
-
- void VisitClassTemplateSpecializationDecl(
- ClassTemplateSpecializationDecl *D) {
- VisitClassTemplateSpecializationDeclImpl(D);
- }
-
- void VisitClassTemplatePartialSpecializationDecl(
- ClassTemplatePartialSpecializationDecl *D);
- void VisitClassScopeFunctionSpecializationDecl(
- ClassScopeFunctionSpecializationDecl *D);
- RedeclarableResult
- VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl *D);
-
- void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) {
- VisitVarTemplateSpecializationDeclImpl(D);
- }
-
- void VisitVarTemplatePartialSpecializationDecl(
- VarTemplatePartialSpecializationDecl *D);
- void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- void VisitValueDecl(ValueDecl *VD);
- void VisitEnumConstantDecl(EnumConstantDecl *ECD);
- void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
- void VisitDeclaratorDecl(DeclaratorDecl *DD);
- void VisitFunctionDecl(FunctionDecl *FD);
- void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *GD);
- void VisitCXXMethodDecl(CXXMethodDecl *D);
- void VisitCXXConstructorDecl(CXXConstructorDecl *D);
- void VisitCXXDestructorDecl(CXXDestructorDecl *D);
- void VisitCXXConversionDecl(CXXConversionDecl *D);
- void VisitFieldDecl(FieldDecl *FD);
- void VisitMSPropertyDecl(MSPropertyDecl *FD);
- void VisitIndirectFieldDecl(IndirectFieldDecl *FD);
- RedeclarableResult VisitVarDeclImpl(VarDecl *D);
- void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); }
- void VisitImplicitParamDecl(ImplicitParamDecl *PD);
- void VisitParmVarDecl(ParmVarDecl *PD);
- void VisitDecompositionDecl(DecompositionDecl *DD);
- void VisitBindingDecl(BindingDecl *BD);
- void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- DeclID VisitTemplateDecl(TemplateDecl *D);
- RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
- void VisitClassTemplateDecl(ClassTemplateDecl *D);
- void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
- void VisitVarTemplateDecl(VarTemplateDecl *D);
- void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
- void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
- void VisitUsingDecl(UsingDecl *D);
- void VisitUsingPackDecl(UsingPackDecl *D);
- void VisitUsingShadowDecl(UsingShadowDecl *D);
- void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
- void VisitLinkageSpecDecl(LinkageSpecDecl *D);
- void VisitExportDecl(ExportDecl *D);
- void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
- void VisitImportDecl(ImportDecl *D);
- void VisitAccessSpecDecl(AccessSpecDecl *D);
- void VisitFriendDecl(FriendDecl *D);
- void VisitFriendTemplateDecl(FriendTemplateDecl *D);
- void VisitStaticAssertDecl(StaticAssertDecl *D);
- void VisitBlockDecl(BlockDecl *BD);
- void VisitCapturedDecl(CapturedDecl *CD);
- void VisitEmptyDecl(EmptyDecl *D);
-
- std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
-
- template<typename T>
- RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
-
- template<typename T>
- void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl,
- DeclID TemplatePatternID = 0);
-
- template<typename T>
- void mergeRedeclarable(Redeclarable<T> *D, T *Existing,
- RedeclarableResult &Redecl,
- DeclID TemplatePatternID = 0);
-
- template<typename T>
- void mergeMergeable(Mergeable<T> *D);
-
- void mergeTemplatePattern(RedeclarableTemplateDecl *D,
- RedeclarableTemplateDecl *Existing,
- DeclID DsID, bool IsKeyDecl);
-
- ObjCTypeParamList *ReadObjCTypeParamList();
-
- // FIXME: Reorder according to DeclNodes.td?
- void VisitObjCMethodDecl(ObjCMethodDecl *D);
- void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
- void VisitObjCContainerDecl(ObjCContainerDecl *D);
- void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
- void VisitObjCIvarDecl(ObjCIvarDecl *D);
- void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
- void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
- void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
- void VisitObjCImplDecl(ObjCImplDecl *D);
- void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
- void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
- void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
- void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
- void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
- void VisitOMPRequiresDecl(OMPRequiresDecl *D);
- void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
- };
-
-} // namespace clang
-
-namespace {
-
-/// Iterator over the redeclarations of a declaration that have already
-/// been merged into the same redeclaration chain.
-template<typename DeclT>
-class MergedRedeclIterator {
- DeclT *Start;
- DeclT *Canonical = nullptr;
- DeclT *Current = nullptr;
-
-public:
- MergedRedeclIterator() = default;
- MergedRedeclIterator(DeclT *Start) : Start(Start), Current(Start) {}
-
- DeclT *operator*() { return Current; }
-
- MergedRedeclIterator &operator++() {
- if (Current->isFirstDecl()) {
- Canonical = Current;
- Current = Current->getMostRecentDecl();
- } else
- Current = Current->getPreviousDecl();
-
- // If we started in the merged portion, we'll reach our start position
- // eventually. Otherwise, we'll never reach it, but the second declaration
- // we reached was the canonical declaration, so stop when we see that one
- // again.
- if (Current == Start || Current == Canonical)
- Current = nullptr;
- return *this;
- }
-
- friend bool operator!=(const MergedRedeclIterator &A,
- const MergedRedeclIterator &B) {
- return A.Current != B.Current;
- }
-};
-
-} // namespace
-
-template <typename DeclT>
-static llvm::iterator_range<MergedRedeclIterator<DeclT>>
-merged_redecls(DeclT *D) {
- return llvm::make_range(MergedRedeclIterator<DeclT>(D),
- MergedRedeclIterator<DeclT>());
-}
-
-uint64_t ASTDeclReader::GetCurrentCursorOffset() {
- return Loc.F->DeclsCursor.GetCurrentBitNo() + Loc.F->GlobalBitOffset;
-}
-
-void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
- if (Record.readInt())
- Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
- if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
- CD->setNumCtorInitializers(Record.readInt());
- if (CD->getNumCtorInitializers())
- CD->CtorInitializers = ReadGlobalOffset();
- }
- // Store the offset of the body so we can lazily load it later.
- Reader.PendingBodies[FD] = GetCurrentCursorOffset();
- HasPendingBody = true;
-}
-
-void ASTDeclReader::Visit(Decl *D) {
- DeclVisitor<ASTDeclReader, void>::Visit(D);
-
- // At this point we have deserialized and merged the decl and it is safe to
- // update its canonical decl to signal that the entire entity is used.
- D->getCanonicalDecl()->Used |= IsDeclMarkedUsed;
- IsDeclMarkedUsed = false;
-
- if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
- if (auto *TInfo = DD->getTypeSourceInfo())
- Record.readTypeLoc(TInfo->getTypeLoc());
- }
-
- if (auto *TD = dyn_cast<TypeDecl>(D)) {
- // We have a fully initialized TypeDecl. Read its type now.
- TD->setTypeForDecl(Reader.GetType(DeferredTypeID).getTypePtrOrNull());
-
- // If this is a tag declaration with a typedef name for linkage, it's safe
- // to load that typedef now.
- if (NamedDeclForTagDecl)
- cast<TagDecl>(D)->TypedefNameDeclOrQualifier =
- cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl));
- } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
- // if we have a fully initialized TypeDecl, we can safely read its type now.
- ID->TypeForDecl = Reader.GetType(DeferredTypeID).getTypePtrOrNull();
- } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
- // FunctionDecl's body was written last after all other Stmts/Exprs.
- // We only read it if FD doesn't already have a body (e.g., from another
- // module).
- // FIXME: Can we diagnose ODR violations somehow?
- if (Record.readInt())
- ReadFunctionDefinition(FD);
- }
-}
-
-void ASTDeclReader::VisitDecl(Decl *D) {
- if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
- isa<ParmVarDecl>(D)) {
- // We don't want to deserialize the DeclContext of a template
- // parameter or of a parameter of a function template immediately. These
- // entities might be used in the formulation of its DeclContext (for
- // example, a function parameter can be used in decltype() in trailing
- // return type of the function). Use the translation unit DeclContext as a
- // placeholder.
- GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID();
- GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID();
- if (!LexicalDCIDForTemplateParmDecl)
- LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl;
- Reader.addPendingDeclContextInfo(D,
- SemaDCIDForTemplateParmDecl,
- LexicalDCIDForTemplateParmDecl);
- D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
- } else {
- auto *SemaDC = ReadDeclAs<DeclContext>();
- auto *LexicalDC = ReadDeclAs<DeclContext>();
- if (!LexicalDC)
- LexicalDC = SemaDC;
- DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
- // Avoid calling setLexicalDeclContext() directly because it uses
- // Decl::getASTContext() internally which is unsafe during derialization.
- D->setDeclContextsImpl(MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC,
- Reader.getContext());
- }
- D->setLocation(ThisDeclLoc);
- D->setInvalidDecl(Record.readInt());
- if (Record.readInt()) { // hasAttrs
- AttrVec Attrs;
- Record.readAttributes(Attrs);
- // Avoid calling setAttrs() directly because it uses Decl::getASTContext()
- // internally which is unsafe during derialization.
- D->setAttrsImpl(Attrs, Reader.getContext());
- }
- D->setImplicit(Record.readInt());
- D->Used = Record.readInt();
- IsDeclMarkedUsed |= D->Used;
- D->setReferenced(Record.readInt());
- D->setTopLevelDeclInObjCContainer(Record.readInt());
- D->setAccess((AccessSpecifier)Record.readInt());
- D->FromASTFile = true;
- bool ModulePrivate = Record.readInt();
-
- // Determine whether this declaration is part of a (sub)module. If so, it
- // may not yet be visible.
- if (unsigned SubmoduleID = readSubmoduleID()) {
- // Store the owning submodule ID in the declaration.
- D->setModuleOwnershipKind(
- ModulePrivate ? Decl::ModuleOwnershipKind::ModulePrivate
- : Decl::ModuleOwnershipKind::VisibleWhenImported);
- D->setOwningModuleID(SubmoduleID);
-
- if (ModulePrivate) {
- // Module-private declarations are never visible, so there is no work to
- // do.
- } else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) {
- // If local visibility is being tracked, this declaration will become
- // hidden and visible as the owning module does.
- } else if (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
- // Mark the declaration as visible when its owning module becomes visible.
- if (Owner->NameVisibility == Module::AllVisible)
- D->setVisibleDespiteOwningModule();
- else
- Reader.HiddenNamesMap[Owner].push_back(D);
- }
- } else if (ModulePrivate) {
- D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
- }
-}
-
-void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
- VisitDecl(D);
- D->setLocation(ReadSourceLocation());
- D->CommentKind = (PragmaMSCommentKind)Record.readInt();
- std::string Arg = ReadString();
- memcpy(D->getTrailingObjects<char>(), Arg.data(), Arg.size());
- D->getTrailingObjects<char>()[Arg.size()] = '\0';
-}
-
-void ASTDeclReader::VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D) {
- VisitDecl(D);
- D->setLocation(ReadSourceLocation());
- std::string Name = ReadString();
- memcpy(D->getTrailingObjects<char>(), Name.data(), Name.size());
- D->getTrailingObjects<char>()[Name.size()] = '\0';
-
- D->ValueStart = Name.size() + 1;
- std::string Value = ReadString();
- memcpy(D->getTrailingObjects<char>() + D->ValueStart, Value.data(),
- Value.size());
- D->getTrailingObjects<char>()[D->ValueStart + Value.size()] = '\0';
-}
-
-void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
- llvm_unreachable("Translation units are not serialized");
-}
-
-void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
- VisitDecl(ND);
- ND->setDeclName(Record.readDeclarationName());
- AnonymousDeclNumber = Record.readInt();
-}
-
-void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
- VisitNamedDecl(TD);
- TD->setLocStart(ReadSourceLocation());
- // Delay type reading until after we have fully initialized the decl.
- DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
-}
-
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
- RedeclarableResult Redecl = VisitRedeclarable(TD);
- VisitTypeDecl(TD);
- TypeSourceInfo *TInfo = GetTypeSourceInfo();
- if (Record.readInt()) { // isModed
- QualType modedT = Record.readType();
- TD->setModedTypeSourceInfo(TInfo, modedT);
- } else
- TD->setTypeSourceInfo(TInfo);
- // Read and discard the declaration for which this is a typedef name for
- // linkage, if it exists. We cannot rely on our type to pull in this decl,
- // because it might have been merged with a type from another module and
- // thus might not refer to our version of the declaration.
- ReadDecl();
- return Redecl;
-}
-
-void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
- RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
- mergeRedeclarable(TD, Redecl);
-}
-
-void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
- RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
- if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>())
- // Merged when we merge the template.
- TD->setDescribedAliasTemplate(Template);
- else
- mergeRedeclarable(TD, Redecl);
-}
-
-ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {
- RedeclarableResult Redecl = VisitRedeclarable(TD);
- VisitTypeDecl(TD);
-
- TD->IdentifierNamespace = Record.readInt();
- TD->setTagKind((TagDecl::TagKind)Record.readInt());
- if (!isa<CXXRecordDecl>(TD))
- TD->setCompleteDefinition(Record.readInt());
- TD->setEmbeddedInDeclarator(Record.readInt());
- TD->setFreeStanding(Record.readInt());
- TD->setCompleteDefinitionRequired(Record.readInt());
- TD->setBraceRange(ReadSourceRange());
-
- switch (Record.readInt()) {
- case 0:
- break;
- case 1: { // ExtInfo
- auto *Info = new (Reader.getContext()) TagDecl::ExtInfo();
- ReadQualifierInfo(*Info);
- TD->TypedefNameDeclOrQualifier = Info;
- break;
- }
- case 2: // TypedefNameForAnonDecl
- NamedDeclForTagDecl = ReadDeclID();
- TypedefNameForLinkage = Record.getIdentifierInfo();
- break;
- default:
- llvm_unreachable("unexpected tag info kind");
- }
-
- if (!isa<CXXRecordDecl>(TD))
- mergeRedeclarable(TD, Redecl);
- return Redecl;
-}
-
-void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
- VisitTagDecl(ED);
- if (TypeSourceInfo *TI = GetTypeSourceInfo())
- ED->setIntegerTypeSourceInfo(TI);
- else
- ED->setIntegerType(Record.readType());
- ED->setPromotionType(Record.readType());
- ED->setNumPositiveBits(Record.readInt());
- ED->setNumNegativeBits(Record.readInt());
- ED->setScoped(Record.readInt());
- ED->setScopedUsingClassTag(Record.readInt());
- ED->setFixed(Record.readInt());
-
- ED->setHasODRHash(true);
- ED->ODRHash = Record.readInt();
-
- // If this is a definition subject to the ODR, and we already have a
- // definition, merge this one into it.
- if (ED->isCompleteDefinition() &&
- Reader.getContext().getLangOpts().Modules &&
- Reader.getContext().getLangOpts().CPlusPlus) {
- EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
- if (!OldDef) {
- // This is the first time we've seen an imported definition. Look for a
- // local definition before deciding that we are the first definition.
- for (auto *D : merged_redecls(ED->getCanonicalDecl())) {
- if (!D->isFromASTFile() && D->isCompleteDefinition()) {
- OldDef = D;
- break;
- }
- }
- }
- if (OldDef) {
- Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
- ED->setCompleteDefinition(false);
- Reader.mergeDefinitionVisibility(OldDef, ED);
- if (OldDef->getODRHash() != ED->getODRHash())
- Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
- } else {
- OldDef = ED;
- }
- }
-
- if (auto *InstED = ReadDeclAs<EnumDecl>()) {
- auto TSK = (TemplateSpecializationKind)Record.readInt();
- SourceLocation POI = ReadSourceLocation();
- ED->setInstantiationOfMemberEnum(Reader.getContext(), InstED, TSK);
- ED->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
- }
-}
-
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
- RedeclarableResult Redecl = VisitTagDecl(RD);
- RD->setHasFlexibleArrayMember(Record.readInt());
- RD->setAnonymousStructOrUnion(Record.readInt());
- RD->setHasObjectMember(Record.readInt());
- RD->setHasVolatileMember(Record.readInt());
- RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt());
- RD->setNonTrivialToPrimitiveCopy(Record.readInt());
- RD->setNonTrivialToPrimitiveDestroy(Record.readInt());
- RD->setParamDestroyedInCallee(Record.readInt());
- RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt());
- return Redecl;
-}
-
-void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
- VisitNamedDecl(VD);
- // For function declarations, defer reading the type in case the function has
- // a deduced return type that references an entity declared within the
- // function.
- if (isa<FunctionDecl>(VD))
- DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
- else
- VD->setType(Record.readType());
-}
-
-void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
- VisitValueDecl(ECD);
- if (Record.readInt())
- ECD->setInitExpr(Record.readExpr());
- ECD->setInitVal(Record.readAPSInt());
- mergeMergeable(ECD);
-}
-
-void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
- VisitValueDecl(DD);
- DD->setInnerLocStart(ReadSourceLocation());
- if (Record.readInt()) { // hasExtInfo
- auto *Info = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
- ReadQualifierInfo(*Info);
- DD->DeclInfo = Info;
- }
- QualType TSIType = Record.readType();
- DD->setTypeSourceInfo(
- TSIType.isNull() ? nullptr
- : Reader.getContext().CreateTypeSourceInfo(TSIType));
-}
-
-void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
- RedeclarableResult Redecl = VisitRedeclarable(FD);
- VisitDeclaratorDecl(FD);
-
- // Attach a type to this function. Use the real type if possible, but fall
- // back to the type as written if it involves a deduced return type.
- if (FD->getTypeSourceInfo() &&
- FD->getTypeSourceInfo()->getType()->castAs<FunctionType>()
- ->getReturnType()->getContainedAutoType()) {
- // We'll set up the real type in Visit, once we've finished loading the
- // function.
- FD->setType(FD->getTypeSourceInfo()->getType());
- Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID});
- } else {
- FD->setType(Reader.GetType(DeferredTypeID));
- }
- DeferredTypeID = 0;
-
- ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName());
- FD->IdentifierNamespace = Record.readInt();
-
- // FunctionDecl's body is handled last at ASTDeclReader::Visit,
- // after everything else is read.
-
- FD->setStorageClass(static_cast<StorageClass>(Record.readInt()));
- FD->setInlineSpecified(Record.readInt());
- FD->setImplicitlyInline(Record.readInt());
- FD->setExplicitSpecified(Record.readInt());
- FD->setVirtualAsWritten(Record.readInt());
- FD->setPure(Record.readInt());
- FD->setHasInheritedPrototype(Record.readInt());
- FD->setHasWrittenPrototype(Record.readInt());
- FD->setDeletedAsWritten(Record.readInt());
- FD->setTrivial(Record.readInt());
- FD->setTrivialForCall(Record.readInt());
- FD->setDefaulted(Record.readInt());
- FD->setExplicitlyDefaulted(Record.readInt());
- FD->setHasImplicitReturnZero(Record.readInt());
- FD->setConstexpr(Record.readInt());
- FD->setUsesSEHTry(Record.readInt());
- FD->setHasSkippedBody(Record.readInt());
- FD->setIsMultiVersion(Record.readInt());
- FD->setLateTemplateParsed(Record.readInt());
-
- FD->setCachedLinkage(static_cast<Linkage>(Record.readInt()));
- FD->EndRangeLoc = ReadSourceLocation();
-
- FD->ODRHash = Record.readInt();
- FD->setHasODRHash(true);
-
- switch ((FunctionDecl::TemplatedKind)Record.readInt()) {
- case FunctionDecl::TK_NonTemplate:
- mergeRedeclarable(FD, Redecl);
- break;
- case FunctionDecl::TK_FunctionTemplate:
- // Merged when we merge the template.
- FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>());
- break;
- case FunctionDecl::TK_MemberSpecialization: {
- auto *InstFD = ReadDeclAs<FunctionDecl>();
- auto TSK = (TemplateSpecializationKind)Record.readInt();
- SourceLocation POI = ReadSourceLocation();
- FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
- FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
- mergeRedeclarable(FD, Redecl);
- break;
- }
- case FunctionDecl::TK_FunctionTemplateSpecialization: {
- auto *Template = ReadDeclAs<FunctionTemplateDecl>();
- auto TSK = (TemplateSpecializationKind)Record.readInt();
-
- // Template arguments.
- SmallVector<TemplateArgument, 8> TemplArgs;
- Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
-
- // Template args as written.
- SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
- SourceLocation LAngleLoc, RAngleLoc;
- bool HasTemplateArgumentsAsWritten = Record.readInt();
- if (HasTemplateArgumentsAsWritten) {
- unsigned NumTemplateArgLocs = Record.readInt();
- TemplArgLocs.reserve(NumTemplateArgLocs);
- for (unsigned i = 0; i != NumTemplateArgLocs; ++i)
- TemplArgLocs.push_back(Record.readTemplateArgumentLoc());
-
- LAngleLoc = ReadSourceLocation();
- RAngleLoc = ReadSourceLocation();
- }
-
- SourceLocation POI = ReadSourceLocation();
-
- ASTContext &C = Reader.getContext();
- TemplateArgumentList *TemplArgList
- = TemplateArgumentList::CreateCopy(C, TemplArgs);
- TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
- for (unsigned i = 0, e = TemplArgLocs.size(); i != e; ++i)
- TemplArgsInfo.addArgument(TemplArgLocs[i]);
- FunctionTemplateSpecializationInfo *FTInfo
- = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
- TemplArgList,
- HasTemplateArgumentsAsWritten ? &TemplArgsInfo
- : nullptr,
- POI);
- FD->TemplateOrSpecialization = FTInfo;
-
- if (FD->isCanonicalDecl()) { // if canonical add to template's set.
- // The template that contains the specializations set. It's not safe to
- // use getCanonicalDecl on Template since it may still be initializing.
- auto *CanonTemplate = ReadDeclAs<FunctionTemplateDecl>();
- // Get the InsertPos by FindNodeOrInsertPos() instead of calling
- // InsertNode(FTInfo) directly to avoid the getASTContext() call in
- // FunctionTemplateSpecializationInfo's Profile().
- // We avoid getASTContext because a decl in the parent hierarchy may
- // be initializing.
- llvm::FoldingSetNodeID ID;
- FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C);
- void *InsertPos = nullptr;
- FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
- FunctionTemplateSpecializationInfo *ExistingInfo =
- CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
- if (InsertPos)
- CommonPtr->Specializations.InsertNode(FTInfo, InsertPos);
- else {
- assert(Reader.getContext().getLangOpts().Modules &&
- "already deserialized this template specialization");
- mergeRedeclarable(FD, ExistingInfo->Function, Redecl);
- }
- }
- break;
- }
- case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
- // Templates.
- UnresolvedSet<8> TemplDecls;
- unsigned NumTemplates = Record.readInt();
- while (NumTemplates--)
- TemplDecls.addDecl(ReadDeclAs<NamedDecl>());
-
- // Templates args.
- TemplateArgumentListInfo TemplArgs;
- unsigned NumArgs = Record.readInt();
- while (NumArgs--)
- TemplArgs.addArgument(Record.readTemplateArgumentLoc());
- TemplArgs.setLAngleLoc(ReadSourceLocation());
- TemplArgs.setRAngleLoc(ReadSourceLocation());
-
- FD->setDependentTemplateSpecialization(Reader.getContext(),
- TemplDecls, TemplArgs);
- // These are not merged; we don't need to merge redeclarations of dependent
- // template friends.
- break;
- }
- }
-
- // Read in the parameters.
- unsigned NumParams = Record.readInt();
- SmallVector<ParmVarDecl *, 16> Params;
- Params.reserve(NumParams);
- for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(ReadDeclAs<ParmVarDecl>());
- FD->setParams(Reader.getContext(), Params);
-}
-
-void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
- VisitNamedDecl(MD);
- if (Record.readInt()) {
- // Load the body on-demand. Most clients won't care, because method
- // definitions rarely show up in headers.
- Reader.PendingBodies[MD] = GetCurrentCursorOffset();
- HasPendingBody = true;
- MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>());
- MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>());
- }
- MD->setInstanceMethod(Record.readInt());
- MD->setVariadic(Record.readInt());
- MD->setPropertyAccessor(Record.readInt());
- MD->setDefined(Record.readInt());
- MD->setOverriding(Record.readInt());
- MD->setHasSkippedBody(Record.readInt());
-
- MD->setIsRedeclaration(Record.readInt());
- MD->setHasRedeclaration(Record.readInt());
- if (MD->hasRedeclaration())
- Reader.getContext().setObjCMethodRedeclaration(MD,
- ReadDeclAs<ObjCMethodDecl>());
-
- MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt());
- MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt());
- MD->setRelatedResultType(Record.readInt());
- MD->setReturnType(Record.readType());
- MD->setReturnTypeSourceInfo(GetTypeSourceInfo());
- MD->DeclEndLoc = ReadSourceLocation();
- unsigned NumParams = Record.readInt();
- SmallVector<ParmVarDecl *, 16> Params;
- Params.reserve(NumParams);
- for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(ReadDeclAs<ParmVarDecl>());
-
- MD->setSelLocsKind((SelectorLocationsKind)Record.readInt());
- unsigned NumStoredSelLocs = Record.readInt();
- SmallVector<SourceLocation, 16> SelLocs;
- SelLocs.reserve(NumStoredSelLocs);
- for (unsigned i = 0; i != NumStoredSelLocs; ++i)
- SelLocs.push_back(ReadSourceLocation());
-
- MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
-}
-
-void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
- VisitTypedefNameDecl(D);
-
- D->Variance = Record.readInt();
- D->Index = Record.readInt();
- D->VarianceLoc = ReadSourceLocation();
- D->ColonLoc = ReadSourceLocation();
-}
-
-void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
- VisitNamedDecl(CD);
- CD->setAtStartLoc(ReadSourceLocation());
- CD->setAtEndRange(ReadSourceRange());
-}
-
-ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() {
- unsigned numParams = Record.readInt();
- if (numParams == 0)
- return nullptr;
-
- SmallVector<ObjCTypeParamDecl *, 4> typeParams;
- typeParams.reserve(numParams);
- for (unsigned i = 0; i != numParams; ++i) {
- auto *typeParam = ReadDeclAs<ObjCTypeParamDecl>();
- if (!typeParam)
- return nullptr;
-
- typeParams.push_back(typeParam);
- }
-
- SourceLocation lAngleLoc = ReadSourceLocation();
- SourceLocation rAngleLoc = ReadSourceLocation();
-
- return ObjCTypeParamList::create(Reader.getContext(), lAngleLoc,
- typeParams, rAngleLoc);
-}
-
-void ASTDeclReader::ReadObjCDefinitionData(
- struct ObjCInterfaceDecl::DefinitionData &Data) {
- // Read the superclass.
- Data.SuperClassTInfo = GetTypeSourceInfo();
-
- Data.EndLoc = ReadSourceLocation();
- Data.HasDesignatedInitializers = Record.readInt();
-
- // Read the directly referenced protocols and their SourceLocations.
- unsigned NumProtocols = Record.readInt();
- SmallVector<ObjCProtocolDecl *, 16> Protocols;
- Protocols.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>());
- SmallVector<SourceLocation, 16> ProtoLocs;
- ProtoLocs.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- ProtoLocs.push_back(ReadSourceLocation());
- Data.ReferencedProtocols.set(Protocols.data(), NumProtocols, ProtoLocs.data(),
- Reader.getContext());
-
- // Read the transitive closure of protocols referenced by this class.
- NumProtocols = Record.readInt();
- Protocols.clear();
- Protocols.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>());
- Data.AllReferencedProtocols.set(Protocols.data(), NumProtocols,
- Reader.getContext());
-}
-
-void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D,
- struct ObjCInterfaceDecl::DefinitionData &&NewDD) {
- // FIXME: odr checking?
-}
-
-void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
- RedeclarableResult Redecl = VisitRedeclarable(ID);
- VisitObjCContainerDecl(ID);
- DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
- mergeRedeclarable(ID, Redecl);
-
- ID->TypeParamList = ReadObjCTypeParamList();
- if (Record.readInt()) {
- // Read the definition.
- ID->allocateDefinitionData();
-
- ReadObjCDefinitionData(ID->data());
- ObjCInterfaceDecl *Canon = ID->getCanonicalDecl();
- if (Canon->Data.getPointer()) {
- // If we already have a definition, keep the definition invariant and
- // merge the data.
- MergeDefinitionData(Canon, std::move(ID->data()));
- ID->Data = Canon->Data;
- } else {
- // Set the definition data of the canonical declaration, so other
- // redeclarations will see it.
- ID->getCanonicalDecl()->Data = ID->Data;
-
- // We will rebuild this list lazily.
- ID->setIvarList(nullptr);
- }
-
- // Note that we have deserialized a definition.
- Reader.PendingDefinitions.insert(ID);
-
- // Note that we've loaded this Objective-C class.
- Reader.ObjCClassesLoaded.push_back(ID);
- } else {
- ID->Data = ID->getCanonicalDecl()->Data;
- }
-}
-
-void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
- VisitFieldDecl(IVD);
- IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record.readInt());
- // This field will be built lazily.
- IVD->setNextIvar(nullptr);
- bool synth = Record.readInt();
- IVD->setSynthesize(synth);
-}
-
-void ASTDeclReader::ReadObjCDefinitionData(
- struct ObjCProtocolDecl::DefinitionData &Data) {
- unsigned NumProtoRefs = Record.readInt();
- SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
- ProtoRefs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>());
- SmallVector<SourceLocation, 16> ProtoLocs;
- ProtoLocs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoLocs.push_back(ReadSourceLocation());
- Data.ReferencedProtocols.set(ProtoRefs.data(), NumProtoRefs,
- ProtoLocs.data(), Reader.getContext());
-}
-
-void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D,
- struct ObjCProtocolDecl::DefinitionData &&NewDD) {
- // FIXME: odr checking?
-}
-
-void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
- RedeclarableResult Redecl = VisitRedeclarable(PD);
- VisitObjCContainerDecl(PD);
- mergeRedeclarable(PD, Redecl);
-
- if (Record.readInt()) {
- // Read the definition.
- PD->allocateDefinitionData();
-
- ReadObjCDefinitionData(PD->data());
-
- ObjCProtocolDecl *Canon = PD->getCanonicalDecl();
- if (Canon->Data.getPointer()) {
- // If we already have a definition, keep the definition invariant and
- // merge the data.
- MergeDefinitionData(Canon, std::move(PD->data()));
- PD->Data = Canon->Data;
- } else {
- // Set the definition data of the canonical declaration, so other
- // redeclarations will see it.
- PD->getCanonicalDecl()->Data = PD->Data;
- }
- // Note that we have deserialized a definition.
- Reader.PendingDefinitions.insert(PD);
- } else {
- PD->Data = PD->getCanonicalDecl()->Data;
- }
-}
-
-void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
- VisitFieldDecl(FD);
-}
-
-void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
- VisitObjCContainerDecl(CD);
- CD->setCategoryNameLoc(ReadSourceLocation());
- CD->setIvarLBraceLoc(ReadSourceLocation());
- CD->setIvarRBraceLoc(ReadSourceLocation());
-
- // Note that this category has been deserialized. We do this before
- // deserializing the interface declaration, so that it will consider this
- /// category.
- Reader.CategoriesDeserialized.insert(CD);
-
- CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>();
- CD->TypeParamList = ReadObjCTypeParamList();
- unsigned NumProtoRefs = Record.readInt();
- SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
- ProtoRefs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>());
- SmallVector<SourceLocation, 16> ProtoLocs;
- ProtoLocs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoLocs.push_back(ReadSourceLocation());
- CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
- Reader.getContext());
-
- // Protocols in the class extension belong to the class.
- if (NumProtoRefs > 0 && CD->ClassInterface && CD->IsClassExtension())
- CD->ClassInterface->mergeClassExtensionProtocolList(
- (ObjCProtocolDecl *const *)ProtoRefs.data(), NumProtoRefs,
- Reader.getContext());
-}
-
-void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
- VisitNamedDecl(CAD);
- CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
-}
-
-void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
- VisitNamedDecl(D);
- D->setAtLoc(ReadSourceLocation());
- D->setLParenLoc(ReadSourceLocation());
- QualType T = Record.readType();
- TypeSourceInfo *TSI = GetTypeSourceInfo();
- D->setType(T, TSI);
- D->setPropertyAttributes(
- (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
- D->setPropertyAttributesAsWritten(
- (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
- D->setPropertyImplementation(
- (ObjCPropertyDecl::PropertyControl)Record.readInt());
- DeclarationName GetterName = Record.readDeclarationName();
- SourceLocation GetterLoc = ReadSourceLocation();
- D->setGetterName(GetterName.getObjCSelector(), GetterLoc);
- DeclarationName SetterName = Record.readDeclarationName();
- SourceLocation SetterLoc = ReadSourceLocation();
- D->setSetterName(SetterName.getObjCSelector(), SetterLoc);
- D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
- D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
- D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>());
-}
-
-void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
- VisitObjCContainerDecl(D);
- D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
-}
-
-void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
- VisitObjCImplDecl(D);
- D->CategoryNameLoc = ReadSourceLocation();
-}
-
-void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
- VisitObjCImplDecl(D);
- D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>());
- D->SuperLoc = ReadSourceLocation();
- D->setIvarLBraceLoc(ReadSourceLocation());
- D->setIvarRBraceLoc(ReadSourceLocation());
- D->setHasNonZeroConstructors(Record.readInt());
- D->setHasDestructors(Record.readInt());
- D->NumIvarInitializers = Record.readInt();
- if (D->NumIvarInitializers)
- D->IvarInitializers = ReadGlobalOffset();
-}
-
-void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
- VisitDecl(D);
- D->setAtLoc(ReadSourceLocation());
- D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>());
- D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>();
- D->IvarLoc = ReadSourceLocation();
- D->setGetterCXXConstructor(Record.readExpr());
- D->setSetterCXXAssignment(Record.readExpr());
-}
-
-void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
- VisitDeclaratorDecl(FD);
- FD->Mutable = Record.readInt();
-
- if (auto ISK = static_cast<FieldDecl::InitStorageKind>(Record.readInt())) {
- FD->InitStorage.setInt(ISK);
- FD->InitStorage.setPointer(ISK == FieldDecl::ISK_CapturedVLAType
- ? Record.readType().getAsOpaquePtr()
- : Record.readExpr());
- }
-
- if (auto *BW = Record.readExpr())
- FD->setBitWidth(BW);
-
- if (!FD->getDeclName()) {
- if (auto *Tmpl = ReadDeclAs<FieldDecl>())
- Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
- }
- mergeMergeable(FD);
-}
-
-void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) {
- VisitDeclaratorDecl(PD);
- PD->GetterId = Record.getIdentifierInfo();
- PD->SetterId = Record.getIdentifierInfo();
-}
-
-void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
- VisitValueDecl(FD);
-
- FD->ChainingSize = Record.readInt();
- assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2");
- FD->Chaining = new (Reader.getContext())NamedDecl*[FD->ChainingSize];
-
- for (unsigned I = 0; I != FD->ChainingSize; ++I)
- FD->Chaining[I] = ReadDeclAs<NamedDecl>();
-
- mergeMergeable(FD);
-}
-
-ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
- RedeclarableResult Redecl = VisitRedeclarable(VD);
- VisitDeclaratorDecl(VD);
-
- VD->VarDeclBits.SClass = (StorageClass)Record.readInt();
- VD->VarDeclBits.TSCSpec = Record.readInt();
- VD->VarDeclBits.InitStyle = Record.readInt();
- VD->VarDeclBits.ARCPseudoStrong = Record.readInt();
- if (!isa<ParmVarDecl>(VD)) {
- VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition =
- Record.readInt();
- VD->NonParmVarDeclBits.ExceptionVar = Record.readInt();
- VD->NonParmVarDeclBits.NRVOVariable = Record.readInt();
- VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt();
- VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt();
- VD->NonParmVarDeclBits.IsInline = Record.readInt();
- VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
- VD->NonParmVarDeclBits.IsConstexpr = Record.readInt();
- VD->NonParmVarDeclBits.IsInitCapture = Record.readInt();
- VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt();
- VD->NonParmVarDeclBits.ImplicitParamKind = Record.readInt();
- VD->NonParmVarDeclBits.EscapingByref = Record.readInt();
- }
- auto VarLinkage = Linkage(Record.readInt());
- VD->setCachedLinkage(VarLinkage);
-
- // Reconstruct the one piece of the IdentifierNamespace that we need.
- if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage &&
- VD->getLexicalDeclContext()->isFunctionOrMethod())
- VD->setLocalExternDecl();
-
- if (uint64_t Val = Record.readInt()) {
- VD->setInit(Record.readExpr());
- if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3
- EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
- Eval->CheckedICE = true;
- Eval->IsICE = Val == 3;
- }
- }
-
- if (VD->hasAttr<BlocksAttr>() && VD->getType()->getAsCXXRecordDecl()) {
- Expr *CopyExpr = Record.readExpr();
- if (CopyExpr)
- Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt());
- }
-
- if (VD->getStorageDuration() == SD_Static && Record.readInt())
- Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile;
-
- enum VarKind {
- VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
- };
- switch ((VarKind)Record.readInt()) {
- case VarNotTemplate:
- // Only true variables (not parameters or implicit parameters) can be
- // merged; the other kinds are not really redeclarable at all.
- if (!isa<ParmVarDecl>(VD) && !isa<ImplicitParamDecl>(VD) &&
- !isa<VarTemplateSpecializationDecl>(VD))
- mergeRedeclarable(VD, Redecl);
- break;
- case VarTemplate:
- // Merged when we merge the template.
- VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>());
- break;
- case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo.
- auto *Tmpl = ReadDeclAs<VarDecl>();
- auto TSK = (TemplateSpecializationKind)Record.readInt();
- SourceLocation POI = ReadSourceLocation();
- Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
- mergeRedeclarable(VD, Redecl);
- break;
- }
- }
-
- return Redecl;
-}
-
-void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
- VisitVarDecl(PD);
-}
-
-void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
- VisitVarDecl(PD);
- unsigned isObjCMethodParam = Record.readInt();
- unsigned scopeDepth = Record.readInt();
- unsigned scopeIndex = Record.readInt();
- unsigned declQualifier = Record.readInt();
- if (isObjCMethodParam) {
- assert(scopeDepth == 0);
- PD->setObjCMethodScopeInfo(scopeIndex);
- PD->ParmVarDeclBits.ScopeDepthOrObjCQuals = declQualifier;
- } else {
- PD->setScopeInfo(scopeDepth, scopeIndex);
- }
- PD->ParmVarDeclBits.IsKNRPromoted = Record.readInt();
- PD->ParmVarDeclBits.HasInheritedDefaultArg = Record.readInt();
- if (Record.readInt()) // hasUninstantiatedDefaultArg.
- PD->setUninstantiatedDefaultArg(Record.readExpr());
-
- // FIXME: If this is a redeclaration of a function from another module, handle
- // inheritance of default arguments.
-}
-
-void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) {
- VisitVarDecl(DD);
- auto **BDs = DD->getTrailingObjects<BindingDecl *>();
- for (unsigned I = 0; I != DD->NumBindings; ++I)
- BDs[I] = ReadDeclAs<BindingDecl>();
-}
-
-void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) {
- VisitValueDecl(BD);
- BD->Binding = Record.readExpr();
-}
-
-void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
- VisitDecl(AD);
- AD->setAsmString(cast<StringLiteral>(Record.readExpr()));
- AD->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
- VisitDecl(BD);
- BD->setBody(cast_or_null<CompoundStmt>(Record.readStmt()));
- BD->setSignatureAsWritten(GetTypeSourceInfo());
- unsigned NumParams = Record.readInt();
- SmallVector<ParmVarDecl *, 16> Params;
- Params.reserve(NumParams);
- for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(ReadDeclAs<ParmVarDecl>());
- BD->setParams(Params);
-
- BD->setIsVariadic(Record.readInt());
- BD->setBlockMissingReturnType(Record.readInt());
- BD->setIsConversionFromLambda(Record.readInt());
- BD->setDoesNotEscape(Record.readInt());
-
- bool capturesCXXThis = Record.readInt();
- unsigned numCaptures = Record.readInt();
- SmallVector<BlockDecl::Capture, 16> captures;
- captures.reserve(numCaptures);
- for (unsigned i = 0; i != numCaptures; ++i) {
- auto *decl = ReadDeclAs<VarDecl>();
- unsigned flags = Record.readInt();
- bool byRef = (flags & 1);
- bool nested = (flags & 2);
- Expr *copyExpr = ((flags & 4) ? Record.readExpr() : nullptr);
-
- captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
- }
- BD->setCaptures(Reader.getContext(), captures, capturesCXXThis);
-}
-
-void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {
- VisitDecl(CD);
- unsigned ContextParamPos = Record.readInt();
- CD->setNothrow(Record.readInt() != 0);
- // Body is set by VisitCapturedStmt.
- for (unsigned I = 0; I < CD->NumParams; ++I) {
- if (I != ContextParamPos)
- CD->setParam(I, ReadDeclAs<ImplicitParamDecl>());
- else
- CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>());
- }
-}
-
-void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
- VisitDecl(D);
- D->setLanguage((LinkageSpecDecl::LanguageIDs)Record.readInt());
- D->setExternLoc(ReadSourceLocation());
- D->setRBraceLoc(ReadSourceLocation());
-}
-
-void ASTDeclReader::VisitExportDecl(ExportDecl *D) {
- VisitDecl(D);
- D->RBraceLoc = ReadSourceLocation();
-}
-
-void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
- VisitNamedDecl(D);
- D->setLocStart(ReadSourceLocation());
-}
-
-void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarable(D);
- VisitNamedDecl(D);
- D->setInline(Record.readInt());
- D->LocStart = ReadSourceLocation();
- D->RBraceLoc = ReadSourceLocation();
-
- // Defer loading the anonymous namespace until we've finished merging
- // this namespace; loading it might load a later declaration of the
- // same namespace, and we have an invariant that older declarations
- // get merged before newer ones try to merge.
- GlobalDeclID AnonNamespace = 0;
- if (Redecl.getFirstID() == ThisDeclID) {
- AnonNamespace = ReadDeclID();
- } else {
- // Link this namespace back to the first declaration, which has already
- // been deserialized.
- D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl());
- }
-
- mergeRedeclarable(D, Redecl);
-
- if (AnonNamespace) {
- // Each module has its own anonymous namespace, which is disjoint from
- // any other module's anonymous namespaces, so don't attach the anonymous
- // namespace at all.
- auto *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace));
- if (!Record.isModule())
- D->setAnonymousNamespace(Anon);
- }
-}
-
-void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarable(D);
- VisitNamedDecl(D);
- D->NamespaceLoc = ReadSourceLocation();
- D->IdentLoc = ReadSourceLocation();
- D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- D->Namespace = ReadDeclAs<NamedDecl>();
- mergeRedeclarable(D, Redecl);
-}
-
-void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
- VisitNamedDecl(D);
- D->setUsingLoc(ReadSourceLocation());
- D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- ReadDeclarationNameLoc(D->DNLoc, D->getDeclName());
- D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>());
- D->setTypename(Record.readInt());
- if (auto *Pattern = ReadDeclAs<NamedDecl>())
- Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern);
- mergeMergeable(D);
-}
-
-void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) {
- VisitNamedDecl(D);
- D->InstantiatedFrom = ReadDeclAs<NamedDecl>();
- auto **Expansions = D->getTrailingObjects<NamedDecl *>();
- for (unsigned I = 0; I != D->NumExpansions; ++I)
- Expansions[I] = ReadDeclAs<NamedDecl>();
- mergeMergeable(D);
-}
-
-void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarable(D);
- VisitNamedDecl(D);
- D->Underlying = ReadDeclAs<NamedDecl>();
- D->IdentifierNamespace = Record.readInt();
- D->UsingOrNextShadow = ReadDeclAs<NamedDecl>();
- auto *Pattern = ReadDeclAs<UsingShadowDecl>();
- if (Pattern)
- Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
- mergeRedeclarable(D, Redecl);
-}
-
-void ASTDeclReader::VisitConstructorUsingShadowDecl(
- ConstructorUsingShadowDecl *D) {
- VisitUsingShadowDecl(D);
- D->NominatedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>();
- D->ConstructedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>();
- D->IsVirtual = Record.readInt();
-}
-
-void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
- VisitNamedDecl(D);
- D->UsingLoc = ReadSourceLocation();
- D->NamespaceLoc = ReadSourceLocation();
- D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- D->NominatedNamespace = ReadDeclAs<NamedDecl>();
- D->CommonAncestor = ReadDeclAs<DeclContext>();
-}
-
-void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
- VisitValueDecl(D);
- D->setUsingLoc(ReadSourceLocation());
- D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- ReadDeclarationNameLoc(D->DNLoc, D->getDeclName());
- D->EllipsisLoc = ReadSourceLocation();
- mergeMergeable(D);
-}
-
-void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
- UnresolvedUsingTypenameDecl *D) {
- VisitTypeDecl(D);
- D->TypenameLocation = ReadSourceLocation();
- D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- D->EllipsisLoc = ReadSourceLocation();
- mergeMergeable(D);
-}
-
-void ASTDeclReader::ReadCXXDefinitionData(
- struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D) {
- // Note: the caller has deserialized the IsLambda bit already.
- Data.UserDeclaredConstructor = Record.readInt();
- Data.UserDeclaredSpecialMembers = Record.readInt();
- Data.Aggregate = Record.readInt();
- Data.PlainOldData = Record.readInt();
- Data.Empty = Record.readInt();
- Data.Polymorphic = Record.readInt();
- Data.Abstract = Record.readInt();
- Data.IsStandardLayout = Record.readInt();
- Data.IsCXX11StandardLayout = Record.readInt();
- Data.HasBasesWithFields = Record.readInt();
- Data.HasBasesWithNonStaticDataMembers = Record.readInt();
- Data.HasPrivateFields = Record.readInt();
- Data.HasProtectedFields = Record.readInt();
- Data.HasPublicFields = Record.readInt();
- Data.HasMutableFields = Record.readInt();
- Data.HasVariantMembers = Record.readInt();
- Data.HasOnlyCMembers = Record.readInt();
- Data.HasInClassInitializer = Record.readInt();
- Data.HasUninitializedReferenceMember = Record.readInt();
- Data.HasUninitializedFields = Record.readInt();
- Data.HasInheritedConstructor = Record.readInt();
- Data.HasInheritedAssignment = Record.readInt();
- Data.NeedOverloadResolutionForCopyConstructor = Record.readInt();
- Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
- Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
- Data.NeedOverloadResolutionForDestructor = Record.readInt();
- Data.DefaultedCopyConstructorIsDeleted = Record.readInt();
- Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
- Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
- Data.DefaultedDestructorIsDeleted = Record.readInt();
- Data.HasTrivialSpecialMembers = Record.readInt();
- Data.HasTrivialSpecialMembersForCall = Record.readInt();
- Data.DeclaredNonTrivialSpecialMembers = Record.readInt();
- Data.DeclaredNonTrivialSpecialMembersForCall = Record.readInt();
- Data.HasIrrelevantDestructor = Record.readInt();
- Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
- Data.HasDefaultedDefaultConstructor = Record.readInt();
- Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
- Data.HasConstexprDefaultConstructor = Record.readInt();
- Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
- Data.ComputedVisibleConversions = Record.readInt();
- Data.UserProvidedDefaultConstructor = Record.readInt();
- Data.DeclaredSpecialMembers = Record.readInt();
- Data.ImplicitCopyConstructorCanHaveConstParamForVBase = Record.readInt();
- Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase = Record.readInt();
- Data.ImplicitCopyAssignmentHasConstParam = Record.readInt();
- Data.HasDeclaredCopyConstructorWithConstParam = Record.readInt();
- Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt();
- Data.ODRHash = Record.readInt();
- Data.HasODRHash = true;
-
- if (Record.readInt())
- Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile;
-
- Data.NumBases = Record.readInt();
- if (Data.NumBases)
- Data.Bases = ReadGlobalOffset();
- Data.NumVBases = Record.readInt();
- if (Data.NumVBases)
- Data.VBases = ReadGlobalOffset();
-
- Record.readUnresolvedSet(Data.Conversions);
- Record.readUnresolvedSet(Data.VisibleConversions);
- assert(Data.Definition && "Data.Definition should be already set!");
- Data.FirstFriend = ReadDeclID();
-
- if (Data.IsLambda) {
- using Capture = LambdaCapture;
-
- auto &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
- Lambda.Dependent = Record.readInt();
- Lambda.IsGenericLambda = Record.readInt();
- Lambda.CaptureDefault = Record.readInt();
- Lambda.NumCaptures = Record.readInt();
- Lambda.NumExplicitCaptures = Record.readInt();
- Lambda.ManglingNumber = Record.readInt();
- Lambda.ContextDecl = ReadDeclID();
- Lambda.Captures = (Capture *)Reader.getContext().Allocate(
- sizeof(Capture) * Lambda.NumCaptures);
- Capture *ToCapture = Lambda.Captures;
- Lambda.MethodTyInfo = GetTypeSourceInfo();
- for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
- SourceLocation Loc = ReadSourceLocation();
- bool IsImplicit = Record.readInt();
- auto Kind = static_cast<LambdaCaptureKind>(Record.readInt());
- switch (Kind) {
- case LCK_StarThis:
- case LCK_This:
- case LCK_VLAType:
- *ToCapture++ = Capture(Loc, IsImplicit, Kind, nullptr,SourceLocation());
- break;
- case LCK_ByCopy:
- case LCK_ByRef:
- auto *Var = ReadDeclAs<VarDecl>();
- SourceLocation EllipsisLoc = ReadSourceLocation();
- *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc);
- break;
- }
- }
- }
-}
-
-void ASTDeclReader::MergeDefinitionData(
- CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &&MergeDD) {
- assert(D->DefinitionData &&
- "merging class definition into non-definition");
- auto &DD = *D->DefinitionData;
-
- if (DD.Definition != MergeDD.Definition) {
- // Track that we merged the definitions.
- Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
- DD.Definition));
- Reader.PendingDefinitions.erase(MergeDD.Definition);
- MergeDD.Definition->setCompleteDefinition(false);
- Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
- assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
- "already loaded pending lookups for merged definition");
- }
-
- auto PFDI = Reader.PendingFakeDefinitionData.find(&DD);
- if (PFDI != Reader.PendingFakeDefinitionData.end() &&
- PFDI->second == ASTReader::PendingFakeDefinitionKind::Fake) {
- // We faked up this definition data because we found a class for which we'd
- // not yet loaded the definition. Replace it with the real thing now.
- assert(!DD.IsLambda && !MergeDD.IsLambda && "faked up lambda definition?");
- PFDI->second = ASTReader::PendingFakeDefinitionKind::FakeLoaded;
-
- // Don't change which declaration is the definition; that is required
- // to be invariant once we select it.
- auto *Def = DD.Definition;
- DD = std::move(MergeDD);
- DD.Definition = Def;
- return;
- }
-
- // FIXME: Move this out into a .def file?
- bool DetectedOdrViolation = false;
-#define OR_FIELD(Field) DD.Field |= MergeDD.Field;
-#define MATCH_FIELD(Field) \
- DetectedOdrViolation |= DD.Field != MergeDD.Field; \
- OR_FIELD(Field)
- MATCH_FIELD(UserDeclaredConstructor)
- MATCH_FIELD(UserDeclaredSpecialMembers)
- MATCH_FIELD(Aggregate)
- MATCH_FIELD(PlainOldData)
- MATCH_FIELD(Empty)
- MATCH_FIELD(Polymorphic)
- MATCH_FIELD(Abstract)
- MATCH_FIELD(IsStandardLayout)
- MATCH_FIELD(IsCXX11StandardLayout)
- MATCH_FIELD(HasBasesWithFields)
- MATCH_FIELD(HasBasesWithNonStaticDataMembers)
- MATCH_FIELD(HasPrivateFields)
- MATCH_FIELD(HasProtectedFields)
- MATCH_FIELD(HasPublicFields)
- MATCH_FIELD(HasMutableFields)
- MATCH_FIELD(HasVariantMembers)
- MATCH_FIELD(HasOnlyCMembers)
- MATCH_FIELD(HasInClassInitializer)
- MATCH_FIELD(HasUninitializedReferenceMember)
- MATCH_FIELD(HasUninitializedFields)
- MATCH_FIELD(HasInheritedConstructor)
- MATCH_FIELD(HasInheritedAssignment)
- MATCH_FIELD(NeedOverloadResolutionForCopyConstructor)
- MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
- MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
- MATCH_FIELD(NeedOverloadResolutionForDestructor)
- MATCH_FIELD(DefaultedCopyConstructorIsDeleted)
- MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
- MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
- MATCH_FIELD(DefaultedDestructorIsDeleted)
- OR_FIELD(HasTrivialSpecialMembers)
- OR_FIELD(HasTrivialSpecialMembersForCall)
- OR_FIELD(DeclaredNonTrivialSpecialMembers)
- OR_FIELD(DeclaredNonTrivialSpecialMembersForCall)
- MATCH_FIELD(HasIrrelevantDestructor)
- OR_FIELD(HasConstexprNonCopyMoveConstructor)
- OR_FIELD(HasDefaultedDefaultConstructor)
- MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
- OR_FIELD(HasConstexprDefaultConstructor)
- MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
- // ComputedVisibleConversions is handled below.
- MATCH_FIELD(UserProvidedDefaultConstructor)
- OR_FIELD(DeclaredSpecialMembers)
- MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForVBase)
- MATCH_FIELD(ImplicitCopyConstructorCanHaveConstParamForNonVBase)
- MATCH_FIELD(ImplicitCopyAssignmentHasConstParam)
- OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
- OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
- MATCH_FIELD(IsLambda)
-#undef OR_FIELD
-#undef MATCH_FIELD
-
- if (DD.NumBases != MergeDD.NumBases || DD.NumVBases != MergeDD.NumVBases)
- DetectedOdrViolation = true;
- // FIXME: Issue a diagnostic if the base classes don't match when we come
- // to lazily load them.
-
- // FIXME: Issue a diagnostic if the list of conversion functions doesn't
- // match when we come to lazily load them.
- if (MergeDD.ComputedVisibleConversions && !DD.ComputedVisibleConversions) {
- DD.VisibleConversions = std::move(MergeDD.VisibleConversions);
- DD.ComputedVisibleConversions = true;
- }
-
- // FIXME: Issue a diagnostic if FirstFriend doesn't match when we come to
- // lazily load it.
-
- if (DD.IsLambda) {
- // FIXME: ODR-checking for merging lambdas (this happens, for instance,
- // when they occur within the body of a function template specialization).
- }
-
- if (D->getODRHash() != MergeDD.ODRHash) {
- DetectedOdrViolation = true;
- }
-
- if (DetectedOdrViolation)
- Reader.PendingOdrMergeFailures[DD.Definition].push_back(
- {MergeDD.Definition, &MergeDD});
-}
-
-void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) {
- struct CXXRecordDecl::DefinitionData *DD;
- ASTContext &C = Reader.getContext();
-
- // Determine whether this is a lambda closure type, so that we can
- // allocate the appropriate DefinitionData structure.
- bool IsLambda = Record.readInt();
- if (IsLambda)
- DD = new (C) CXXRecordDecl::LambdaDefinitionData(D, nullptr, false, false,
- LCD_None);
- else
- DD = new (C) struct CXXRecordDecl::DefinitionData(D);
-
- CXXRecordDecl *Canon = D->getCanonicalDecl();
- // Set decl definition data before reading it, so that during deserialization
- // when we read CXXRecordDecl, it already has definition data and we don't
- // set fake one.
- if (!Canon->DefinitionData)
- Canon->DefinitionData = DD;
- D->DefinitionData = Canon->DefinitionData;
- ReadCXXDefinitionData(*DD, D);
-
- // We might already have a different definition for this record. This can
- // happen either because we're reading an update record, or because we've
- // already done some merging. Either way, just merge into it.
- if (Canon->DefinitionData != DD) {
- MergeDefinitionData(Canon, std::move(*DD));
- return;
- }
-
- // Mark this declaration as being a definition.
- D->setCompleteDefinition(true);
-
- // If this is not the first declaration or is an update record, we can have
- // other redeclarations already. Make a note that we need to propagate the
- // DefinitionData pointer onto them.
- if (Update || Canon != D)
- Reader.PendingDefinitions.insert(D);
-}
-
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
- RedeclarableResult Redecl = VisitRecordDeclImpl(D);
-
- ASTContext &C = Reader.getContext();
-
- enum CXXRecKind {
- CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
- };
- switch ((CXXRecKind)Record.readInt()) {
- case CXXRecNotTemplate:
- // Merged when we merge the folding set entry in the primary template.
- if (!isa<ClassTemplateSpecializationDecl>(D))
- mergeRedeclarable(D, Redecl);
- break;
- case CXXRecTemplate: {
- // Merged when we merge the template.
- auto *Template = ReadDeclAs<ClassTemplateDecl>();
- D->TemplateOrInstantiation = Template;
- if (!Template->getTemplatedDecl()) {
- // We've not actually loaded the ClassTemplateDecl yet, because we're
- // currently being loaded as its pattern. Rely on it to set up our
- // TypeForDecl (see VisitClassTemplateDecl).
- //
- // Beware: we do not yet know our canonical declaration, and may still
- // get merged once the surrounding class template has got off the ground.
- DeferredTypeID = 0;
- }
- break;
- }
- case CXXRecMemberSpecialization: {
- auto *RD = ReadDeclAs<CXXRecordDecl>();
- auto TSK = (TemplateSpecializationKind)Record.readInt();
- SourceLocation POI = ReadSourceLocation();
- MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
- MSI->setPointOfInstantiation(POI);
- D->TemplateOrInstantiation = MSI;
- mergeRedeclarable(D, Redecl);
- break;
- }
- }
-
- bool WasDefinition = Record.readInt();
- if (WasDefinition)
- ReadCXXRecordDefinition(D, /*Update*/false);
- else
- // Propagate DefinitionData pointer from the canonical declaration.
- D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
-
- // Lazily load the key function to avoid deserializing every method so we can
- // compute it.
- if (WasDefinition) {
- DeclID KeyFn = ReadDeclID();
- if (KeyFn && D->isCompleteDefinition())
- // FIXME: This is wrong for the ARM ABI, where some other module may have
- // made this function no longer be a key function. We need an update
- // record or similar for that case.
- C.KeyFunctions[D] = KeyFn;
- }
-
- return Redecl;
-}
-
-void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
- VisitFunctionDecl(D);
- D->setIsCopyDeductionCandidate(Record.readInt());
-}
-
-void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
- VisitFunctionDecl(D);
-
- unsigned NumOverridenMethods = Record.readInt();
- if (D->isCanonicalDecl()) {
- while (NumOverridenMethods--) {
- // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
- // MD may be initializing.
- if (auto *MD = ReadDeclAs<CXXMethodDecl>())
- Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl());
- }
- } else {
- // We don't care about which declarations this used to override; we get
- // the relevant information from the canonical declaration.
- Record.skipInts(NumOverridenMethods);
- }
-}
-
-void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- // We need the inherited constructor information to merge the declaration,
- // so we have to read it before we call VisitCXXMethodDecl.
- if (D->isInheritingConstructor()) {
- auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>();
- auto *Ctor = ReadDeclAs<CXXConstructorDecl>();
- *D->getTrailingObjects<InheritedConstructor>() =
- InheritedConstructor(Shadow, Ctor);
- }
-
- VisitCXXMethodDecl(D);
-}
-
-void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
- VisitCXXMethodDecl(D);
-
- if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>()) {
- CXXDestructorDecl *Canon = D->getCanonicalDecl();
- auto *ThisArg = Record.readExpr();
- // FIXME: Check consistency if we have an old and new operator delete.
- if (!Canon->OperatorDelete) {
- Canon->OperatorDelete = OperatorDelete;
- Canon->OperatorDeleteThisArg = ThisArg;
- }
- }
-}
-
-void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
- VisitCXXMethodDecl(D);
-}
-
-void ASTDeclReader::VisitImportDecl(ImportDecl *D) {
- VisitDecl(D);
- D->ImportedAndComplete.setPointer(readModule());
- D->ImportedAndComplete.setInt(Record.readInt());
- auto *StoredLocs = D->getTrailingObjects<SourceLocation>();
- for (unsigned I = 0, N = Record.back(); I != N; ++I)
- StoredLocs[I] = ReadSourceLocation();
- Record.skipInts(1); // The number of stored source locations.
-}
-
-void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
- VisitDecl(D);
- D->setColonLoc(ReadSourceLocation());
-}
-
-void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
- VisitDecl(D);
- if (Record.readInt()) // hasFriendDecl
- D->Friend = ReadDeclAs<NamedDecl>();
- else
- D->Friend = GetTypeSourceInfo();
- for (unsigned i = 0; i != D->NumTPLists; ++i)
- D->getTrailingObjects<TemplateParameterList *>()[i] =
- Record.readTemplateParameterList();
- D->NextFriend = ReadDeclID();
- D->UnsupportedFriend = (Record.readInt() != 0);
- D->FriendLoc = ReadSourceLocation();
-}
-
-void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
- VisitDecl(D);
- unsigned NumParams = Record.readInt();
- D->NumParams = NumParams;
- D->Params = new TemplateParameterList*[NumParams];
- for (unsigned i = 0; i != NumParams; ++i)
- D->Params[i] = Record.readTemplateParameterList();
- if (Record.readInt()) // HasFriendDecl
- D->Friend = ReadDeclAs<NamedDecl>();
- else
- D->Friend = GetTypeSourceInfo();
- D->FriendLoc = ReadSourceLocation();
-}
-
-DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
- VisitNamedDecl(D);
-
- DeclID PatternID = ReadDeclID();
- auto *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
- TemplateParameterList *TemplateParams = Record.readTemplateParameterList();
- // FIXME handle associated constraints
- D->init(TemplatedDecl, TemplateParams);
-
- return PatternID;
-}
-
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarable(D);
-
- // Make sure we've allocated the Common pointer first. We do this before
- // VisitTemplateDecl so that getCommonPtr() can be used during initialization.
- RedeclarableTemplateDecl *CanonD = D->getCanonicalDecl();
- if (!CanonD->Common) {
- CanonD->Common = CanonD->newCommon(Reader.getContext());
- Reader.PendingDefinitions.insert(CanonD);
- }
- D->Common = CanonD->Common;
-
- // If this is the first declaration of the template, fill in the information
- // for the 'common' pointer.
- if (ThisDeclID == Redecl.getFirstID()) {
- if (auto *RTD = ReadDeclAs<RedeclarableTemplateDecl>()) {
- assert(RTD->getKind() == D->getKind() &&
- "InstantiatedFromMemberTemplate kind mismatch");
- D->setInstantiatedFromMemberTemplate(RTD);
- if (Record.readInt())
- D->setMemberSpecialization();
- }
- }
-
- DeclID PatternID = VisitTemplateDecl(D);
- D->IdentifierNamespace = Record.readInt();
-
- mergeRedeclarable(D, Redecl, PatternID);
-
- // If we merged the template with a prior declaration chain, merge the common
- // pointer.
- // FIXME: Actually merge here, don't just overwrite.
- D->Common = D->getCanonicalDecl()->Common;
-
- return Redecl;
-}
-
-void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
-
- if (ThisDeclID == Redecl.getFirstID()) {
- // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
- // the specializations.
- SmallVector<serialization::DeclID, 32> SpecIDs;
- ReadDeclIDList(SpecIDs);
- ASTDeclReader::AddLazySpecializations(D, SpecIDs);
- }
-
- if (D->getTemplatedDecl()->TemplateOrInstantiation) {
- // We were loaded before our templated declaration was. We've not set up
- // its corresponding type yet (see VisitCXXRecordDeclImpl), so reconstruct
- // it now.
- Reader.getContext().getInjectedClassNameType(
- D->getTemplatedDecl(), D->getInjectedClassNameSpecialization());
- }
-}
-
-void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
- llvm_unreachable("BuiltinTemplates are not serialized");
-}
-
-/// TODO: Unify with ClassTemplateDecl version?
-/// May require unifying ClassTemplateDecl and
-/// VarTemplateDecl beyond TemplateDecl...
-void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
-
- if (ThisDeclID == Redecl.getFirstID()) {
- // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of
- // the specializations.
- SmallVector<serialization::DeclID, 32> SpecIDs;
- ReadDeclIDList(SpecIDs);
- ASTDeclReader::AddLazySpecializations(D, SpecIDs);
- }
-}
-
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
- ClassTemplateSpecializationDecl *D) {
- RedeclarableResult Redecl = VisitCXXRecordDeclImpl(D);
-
- ASTContext &C = Reader.getContext();
- if (Decl *InstD = ReadDecl()) {
- if (auto *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
- D->SpecializedTemplate = CTD;
- } else {
- SmallVector<TemplateArgument, 8> TemplArgs;
- Record.readTemplateArgumentList(TemplArgs);
- TemplateArgumentList *ArgList
- = TemplateArgumentList::CreateCopy(C, TemplArgs);
- auto *PS =
- new (C) ClassTemplateSpecializationDecl::
- SpecializedPartialSpecialization();
- PS->PartialSpecialization
- = cast<ClassTemplatePartialSpecializationDecl>(InstD);
- PS->TemplateArgs = ArgList;
- D->SpecializedTemplate = PS;
- }
- }
-
- SmallVector<TemplateArgument, 8> TemplArgs;
- Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
- D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
- D->PointOfInstantiation = ReadSourceLocation();
- D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
-
- bool writtenAsCanonicalDecl = Record.readInt();
- if (writtenAsCanonicalDecl) {
- auto *CanonPattern = ReadDeclAs<ClassTemplateDecl>();
- if (D->isCanonicalDecl()) { // It's kept in the folding set.
- // Set this as, or find, the canonical declaration for this specialization
- ClassTemplateSpecializationDecl *CanonSpec;
- if (auto *Partial = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
- CanonSpec = CanonPattern->getCommonPtr()->PartialSpecializations
- .GetOrInsertNode(Partial);
- } else {
- CanonSpec =
- CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
- }
- // If there was already a canonical specialization, merge into it.
- if (CanonSpec != D) {
- mergeRedeclarable<TagDecl>(D, CanonSpec, Redecl);
-
- // This declaration might be a definition. Merge with any existing
- // definition.
- if (auto *DDD = D->DefinitionData) {
- if (CanonSpec->DefinitionData)
- MergeDefinitionData(CanonSpec, std::move(*DDD));
- else
- CanonSpec->DefinitionData = D->DefinitionData;
- }
- D->DefinitionData = CanonSpec->DefinitionData;
- }
- }
- }
-
- // Explicit info.
- if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) {
- auto *ExplicitInfo =
- new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = TyInfo;
- ExplicitInfo->ExternLoc = ReadSourceLocation();
- ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation();
- D->ExplicitInfo = ExplicitInfo;
- }
-
- return Redecl;
-}
-
-void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
- ClassTemplatePartialSpecializationDecl *D) {
- RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
-
- D->TemplateParams = Record.readTemplateParameterList();
- D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
-
- // These are read/set from/to the first declaration.
- if (ThisDeclID == Redecl.getFirstID()) {
- D->InstantiatedFromMember.setPointer(
- ReadDeclAs<ClassTemplatePartialSpecializationDecl>());
- D->InstantiatedFromMember.setInt(Record.readInt());
- }
-}
-
-void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
- ClassScopeFunctionSpecializationDecl *D) {
- VisitDecl(D);
- D->Specialization = ReadDeclAs<CXXMethodDecl>();
-}
-
-void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
-
- if (ThisDeclID == Redecl.getFirstID()) {
- // This FunctionTemplateDecl owns a CommonPtr; read it.
- SmallVector<serialization::DeclID, 32> SpecIDs;
- ReadDeclIDList(SpecIDs);
- ASTDeclReader::AddLazySpecializations(D, SpecIDs);
- }
-}
-
-/// TODO: Unify with ClassTemplateSpecializationDecl version?
-/// May require unifying ClassTemplate(Partial)SpecializationDecl and
-/// VarTemplate(Partial)SpecializationDecl with a new data
-/// structure Template(Partial)SpecializationDecl, and
-/// using Template(Partial)SpecializationDecl as input type.
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
- VarTemplateSpecializationDecl *D) {
- RedeclarableResult Redecl = VisitVarDeclImpl(D);
-
- ASTContext &C = Reader.getContext();
- if (Decl *InstD = ReadDecl()) {
- if (auto *VTD = dyn_cast<VarTemplateDecl>(InstD)) {
- D->SpecializedTemplate = VTD;
- } else {
- SmallVector<TemplateArgument, 8> TemplArgs;
- Record.readTemplateArgumentList(TemplArgs);
- TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy(
- C, TemplArgs);
- auto *PS =
- new (C)
- VarTemplateSpecializationDecl::SpecializedPartialSpecialization();
- PS->PartialSpecialization =
- cast<VarTemplatePartialSpecializationDecl>(InstD);
- PS->TemplateArgs = ArgList;
- D->SpecializedTemplate = PS;
- }
- }
-
- // Explicit info.
- if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) {
- auto *ExplicitInfo =
- new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = TyInfo;
- ExplicitInfo->ExternLoc = ReadSourceLocation();
- ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation();
- D->ExplicitInfo = ExplicitInfo;
- }
-
- SmallVector<TemplateArgument, 8> TemplArgs;
- Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
- D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
- D->PointOfInstantiation = ReadSourceLocation();
- D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
- D->IsCompleteDefinition = Record.readInt();
-
- bool writtenAsCanonicalDecl = Record.readInt();
- if (writtenAsCanonicalDecl) {
- auto *CanonPattern = ReadDeclAs<VarTemplateDecl>();
- if (D->isCanonicalDecl()) { // It's kept in the folding set.
- // FIXME: If it's already present, merge it.
- if (auto *Partial = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
- CanonPattern->getCommonPtr()->PartialSpecializations
- .GetOrInsertNode(Partial);
- } else {
- CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
- }
- }
- }
-
- return Redecl;
-}
-
-/// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
-/// May require unifying ClassTemplate(Partial)SpecializationDecl and
-/// VarTemplate(Partial)SpecializationDecl with a new data
-/// structure Template(Partial)SpecializationDecl, and
-/// using Template(Partial)SpecializationDecl as input type.
-void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl(
- VarTemplatePartialSpecializationDecl *D) {
- RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
-
- D->TemplateParams = Record.readTemplateParameterList();
- D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
-
- // These are read/set from/to the first declaration.
- if (ThisDeclID == Redecl.getFirstID()) {
- D->InstantiatedFromMember.setPointer(
- ReadDeclAs<VarTemplatePartialSpecializationDecl>());
- D->InstantiatedFromMember.setInt(Record.readInt());
- }
-}
-
-void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
- VisitTypeDecl(D);
-
- D->setDeclaredWithTypename(Record.readInt());
-
- if (Record.readInt())
- D->setDefaultArgument(GetTypeSourceInfo());
-}
-
-void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
- VisitDeclaratorDecl(D);
- // TemplateParmPosition.
- D->setDepth(Record.readInt());
- D->setPosition(Record.readInt());
- if (D->isExpandedParameterPack()) {
- auto TypesAndInfos =
- D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
- new (&TypesAndInfos[I].first) QualType(Record.readType());
- TypesAndInfos[I].second = GetTypeSourceInfo();
- }
- } else {
- // Rest of NonTypeTemplateParmDecl.
- D->ParameterPack = Record.readInt();
- if (Record.readInt())
- D->setDefaultArgument(Record.readExpr());
- }
-}
-
-void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
- VisitTemplateDecl(D);
- // TemplateParmPosition.
- D->setDepth(Record.readInt());
- D->setPosition(Record.readInt());
- if (D->isExpandedParameterPack()) {
- auto **Data = D->getTrailingObjects<TemplateParameterList *>();
- for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
- I != N; ++I)
- Data[I] = Record.readTemplateParameterList();
- } else {
- // Rest of TemplateTemplateParmDecl.
- D->ParameterPack = Record.readInt();
- if (Record.readInt())
- D->setDefaultArgument(Reader.getContext(),
- Record.readTemplateArgumentLoc());
- }
-}
-
-void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
-}
-
-void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
- VisitDecl(D);
- D->AssertExprAndFailed.setPointer(Record.readExpr());
- D->AssertExprAndFailed.setInt(Record.readInt());
- D->Message = cast_or_null<StringLiteral>(Record.readExpr());
- D->RParenLoc = ReadSourceLocation();
-}
-
-void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {
- VisitDecl(D);
-}
-
-std::pair<uint64_t, uint64_t>
-ASTDeclReader::VisitDeclContext(DeclContext *DC) {
- uint64_t LexicalOffset = ReadLocalOffset();
- uint64_t VisibleOffset = ReadLocalOffset();
- return std::make_pair(LexicalOffset, VisibleOffset);
-}
-
-template <typename T>
-ASTDeclReader::RedeclarableResult
-ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
- DeclID FirstDeclID = ReadDeclID();
- Decl *MergeWith = nullptr;
-
- bool IsKeyDecl = ThisDeclID == FirstDeclID;
- bool IsFirstLocalDecl = false;
-
- uint64_t RedeclOffset = 0;
-
- // 0 indicates that this declaration was the only declaration of its entity,
- // and is used for space optimization.
- if (FirstDeclID == 0) {
- FirstDeclID = ThisDeclID;
- IsKeyDecl = true;
- IsFirstLocalDecl = true;
- } else if (unsigned N = Record.readInt()) {
- // This declaration was the first local declaration, but may have imported
- // other declarations.
- IsKeyDecl = N == 1;
- IsFirstLocalDecl = true;
-
- // We have some declarations that must be before us in our redeclaration
- // chain. Read them now, and remember that we ought to merge with one of
- // them.
- // FIXME: Provide a known merge target to the second and subsequent such
- // declaration.
- for (unsigned I = 0; I != N - 1; ++I)
- MergeWith = ReadDecl();
-
- RedeclOffset = ReadLocalOffset();
- } else {
- // This declaration was not the first local declaration. Read the first
- // local declaration now, to trigger the import of other redeclarations.
- (void)ReadDecl();
- }
-
- auto *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
- if (FirstDecl != D) {
- // We delay loading of the redeclaration chain to avoid deeply nested calls.
- // We temporarily set the first (canonical) declaration as the previous one
- // which is the one that matters and mark the real previous DeclID to be
- // loaded & attached later on.
- D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl);
- D->First = FirstDecl->getCanonicalDecl();
- }
-
- auto *DAsT = static_cast<T *>(D);
-
- // Note that we need to load local redeclarations of this decl and build a
- // decl chain for them. This must happen *after* we perform the preloading
- // above; this ensures that the redeclaration chain is built in the correct
- // order.
- if (IsFirstLocalDecl)
- Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset));
-
- return RedeclarableResult(MergeWith, FirstDeclID, IsKeyDecl);
-}
-
-/// Attempts to merge the given declaration (D) with another declaration
-/// of the same entity.
-template<typename T>
-void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
- RedeclarableResult &Redecl,
- DeclID TemplatePatternID) {
- // If modules are not available, there is no reason to perform this merge.
- if (!Reader.getContext().getLangOpts().Modules)
- return;
-
- // If we're not the canonical declaration, we don't need to merge.
- if (!DBase->isFirstDecl())
- return;
-
- auto *D = static_cast<T *>(DBase);
-
- if (auto *Existing = Redecl.getKnownMergeTarget())
- // We already know of an existing declaration we should merge with.
- mergeRedeclarable(D, cast<T>(Existing), Redecl, TemplatePatternID);
- else if (FindExistingResult ExistingRes = findExisting(D))
- if (T *Existing = ExistingRes)
- mergeRedeclarable(D, Existing, Redecl, TemplatePatternID);
-}
-
-/// "Cast" to type T, asserting if we don't have an implicit conversion.
-/// We use this to put code in a template that will only be valid for certain
-/// instantiations.
-template<typename T> static T assert_cast(T t) { return t; }
-template<typename T> static T assert_cast(...) {
- llvm_unreachable("bad assert_cast");
-}
-
-/// Merge together the pattern declarations from two template
-/// declarations.
-void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
- RedeclarableTemplateDecl *Existing,
- DeclID DsID, bool IsKeyDecl) {
- auto *DPattern = D->getTemplatedDecl();
- auto *ExistingPattern = Existing->getTemplatedDecl();
- RedeclarableResult Result(/*MergeWith*/ ExistingPattern,
- DPattern->getCanonicalDecl()->getGlobalID(),
- IsKeyDecl);
-
- if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
- // Merge with any existing definition.
- // FIXME: This is duplicated in several places. Refactor.
- auto *ExistingClass =
- cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();
- if (auto *DDD = DClass->DefinitionData) {
- if (ExistingClass->DefinitionData) {
- MergeDefinitionData(ExistingClass, std::move(*DDD));
- } else {
- ExistingClass->DefinitionData = DClass->DefinitionData;
- // We may have skipped this before because we thought that DClass
- // was the canonical declaration.
- Reader.PendingDefinitions.insert(DClass);
- }
- }
- DClass->DefinitionData = ExistingClass->DefinitionData;
-
- return mergeRedeclarable(DClass, cast<TagDecl>(ExistingPattern),
- Result);
- }
- if (auto *DFunction = dyn_cast<FunctionDecl>(DPattern))
- return mergeRedeclarable(DFunction, cast<FunctionDecl>(ExistingPattern),
- Result);
- if (auto *DVar = dyn_cast<VarDecl>(DPattern))
- return mergeRedeclarable(DVar, cast<VarDecl>(ExistingPattern), Result);
- if (auto *DAlias = dyn_cast<TypeAliasDecl>(DPattern))
- return mergeRedeclarable(DAlias, cast<TypedefNameDecl>(ExistingPattern),
- Result);
- llvm_unreachable("merged an unknown kind of redeclarable template");
-}
-
-/// Attempts to merge the given declaration (D) with another declaration
-/// of the same entity.
-template<typename T>
-void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
- RedeclarableResult &Redecl,
- DeclID TemplatePatternID) {
- auto *D = static_cast<T *>(DBase);
- T *ExistingCanon = Existing->getCanonicalDecl();
- T *DCanon = D->getCanonicalDecl();
- if (ExistingCanon != DCanon) {
- assert(DCanon->getGlobalID() == Redecl.getFirstID() &&
- "already merged this declaration");
-
- // Have our redeclaration link point back at the canonical declaration
- // of the existing declaration, so that this declaration has the
- // appropriate canonical declaration.
- D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon);
- D->First = ExistingCanon;
- ExistingCanon->Used |= D->Used;
- D->Used = false;
-
- // When we merge a namespace, update its pointer to the first namespace.
- // We cannot have loaded any redeclarations of this declaration yet, so
- // there's nothing else that needs to be updated.
- if (auto *Namespace = dyn_cast<NamespaceDecl>(D))
- Namespace->AnonOrFirstNamespaceAndInline.setPointer(
- assert_cast<NamespaceDecl*>(ExistingCanon));
-
- // When we merge a template, merge its pattern.
- if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
- mergeTemplatePattern(
- DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
- TemplatePatternID, Redecl.isKeyDecl());
-
- // If this declaration is a key declaration, make a note of that.
- if (Redecl.isKeyDecl())
- Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID());
- }
-}
-
-/// ODR-like semantics for C/ObjC allow us to merge tag types and a structural
-/// check in Sema guarantees the types can be merged (see C11 6.2.7/1 or C89
-/// 6.1.2.6/1). Although most merging is done in Sema, we need to guarantee
-/// that some types are mergeable during deserialization, otherwise name
-/// lookup fails. This is the case for EnumConstantDecl.
-static bool allowODRLikeMergeInC(NamedDecl *ND) {
- if (!ND)
- return false;
- // TODO: implement merge for other necessary decls.
- if (isa<EnumConstantDecl>(ND))
- return true;
- return false;
-}
-
-/// Attempts to merge the given declaration (D) with another declaration
-/// of the same entity, for the case where the entity is not actually
-/// redeclarable. This happens, for instance, when merging the fields of
-/// identical class definitions from two different modules.
-template<typename T>
-void ASTDeclReader::mergeMergeable(Mergeable<T> *D) {
- // If modules are not available, there is no reason to perform this merge.
- if (!Reader.getContext().getLangOpts().Modules)
- return;
-
- // ODR-based merging is performed in C++ and in some cases (tag types) in C.
- // Note that C identically-named things in different translation units are
- // not redeclarations, but may still have compatible types, where ODR-like
- // semantics may apply.
- if (!Reader.getContext().getLangOpts().CPlusPlus &&
- !allowODRLikeMergeInC(dyn_cast<NamedDecl>(static_cast<T*>(D))))
- return;
-
- if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D)))
- if (T *Existing = ExistingRes)
- Reader.getContext().setPrimaryMergedDecl(static_cast<T *>(D),
- Existing->getCanonicalDecl());
-}
-
-void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
- VisitDecl(D);
- unsigned NumVars = D->varlist_size();
- SmallVector<Expr *, 16> Vars;
- Vars.reserve(NumVars);
- for (unsigned i = 0; i != NumVars; ++i) {
- Vars.push_back(Record.readExpr());
- }
- D->setVars(Vars);
-}
-
-void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
- VisitDecl(D);
- unsigned NumClauses = D->clauselist_size();
- SmallVector<OMPClause *, 8> Clauses;
- Clauses.reserve(NumClauses);
- OMPClauseReader ClauseReader(Record);
- for (unsigned I = 0; I != NumClauses; ++I)
- Clauses.push_back(ClauseReader.readClause());
- D->setClauses(Clauses);
-}
-
-void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
- VisitValueDecl(D);
- D->setLocation(ReadSourceLocation());
- Expr *In = Record.readExpr();
- Expr *Out = Record.readExpr();
- D->setCombinerData(In, Out);
- Expr *Combiner = Record.readExpr();
- D->setCombiner(Combiner);
- Expr *Orig = Record.readExpr();
- Expr *Priv = Record.readExpr();
- D->setInitializerData(Orig, Priv);
- Expr *Init = Record.readExpr();
- auto IK = static_cast<OMPDeclareReductionDecl::InitKind>(Record.readInt());
- D->setInitializer(Init, IK);
- D->PrevDeclInScope = ReadDeclID();
-}
-
-void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
- VisitVarDecl(D);
-}
-
-//===----------------------------------------------------------------------===//
-// Attribute Reading
-//===----------------------------------------------------------------------===//
-
-namespace {
-class AttrReader {
- ModuleFile *F;
- ASTReader *Reader;
- const ASTReader::RecordData &Record;
- unsigned &Idx;
-
-public:
- AttrReader(ModuleFile &F, ASTReader &Reader,
- const ASTReader::RecordData &Record, unsigned &Idx)
- : F(&F), Reader(&Reader), Record(Record), Idx(Idx) {}
-
- const uint64_t &readInt() { return Record[Idx++]; }
-
- SourceRange readSourceRange() {
- return Reader->ReadSourceRange(*F, Record, Idx);
- }
-
- Expr *readExpr() { return Reader->ReadExpr(*F); }
-
- std::string readString() {
- return Reader->ReadString(Record, Idx);
- }
-
- TypeSourceInfo *getTypeSourceInfo() {
- return Reader->GetTypeSourceInfo(*F, Record, Idx);
- }
-
- IdentifierInfo *getIdentifierInfo() {
- return Reader->GetIdentifierInfo(*F, Record, Idx);
- }
-
- VersionTuple readVersionTuple() {
- return ASTReader::ReadVersionTuple(Record, Idx);
- }
-
- template <typename T> T *GetLocalDeclAs(uint32_t LocalID) {
- return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
- }
-};
-}
-
-Attr *ASTReader::ReadAttr(ModuleFile &M, const RecordData &Rec,
- unsigned &Idx) {
- AttrReader Record(M, *this, Rec, Idx);
- auto V = Record.readInt();
- if (!V)
- return nullptr;
-
- Attr *New = nullptr;
- // Kind is stored as a 1-based integer because 0 is used to indicate a null
- // Attr pointer.
- auto Kind = static_cast<attr::Kind>(V - 1);
- SourceRange Range = Record.readSourceRange();
- ASTContext &Context = getContext();
-
-#include "clang/Serialization/AttrPCHRead.inc"
-
- assert(New && "Unable to decode attribute?");
- return New;
-}
-
-/// Reads attributes from the current stream position.
-void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) {
- for (unsigned I = 0, E = Record.readInt(); I != E; ++I)
- Attrs.push_back(Record.readAttr());
-}
-
-//===----------------------------------------------------------------------===//
-// ASTReader Implementation
-//===----------------------------------------------------------------------===//
-
-/// Note that we have loaded the declaration with the given
-/// Index.
-///
-/// This routine notes that this declaration has already been loaded,
-/// so that future GetDecl calls will return this declaration rather
-/// than trying to load a new declaration.
-inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) {
- assert(!DeclsLoaded[Index] && "Decl loaded twice?");
- DeclsLoaded[Index] = D;
-}
-
-/// Determine whether the consumer will be interested in seeing
-/// this declaration (via HandleTopLevelDecl).
-///
-/// This routine should return true for anything that might affect
-/// code generation, e.g., inline function definitions, Objective-C
-/// declarations with metadata, etc.
-static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
- // An ObjCMethodDecl is never considered as "interesting" because its
- // implementation container always is.
-
- // An ImportDecl or VarDecl imported from a module map module will get
- // emitted when we import the relevant module.
- if (isa<ImportDecl>(D) || isa<VarDecl>(D)) {
- auto *M = D->getImportedOwningModule();
- if (M && M->Kind == Module::ModuleMapModule &&
- Ctx.DeclMustBeEmitted(D))
- return false;
- }
-
- if (isa<FileScopeAsmDecl>(D) ||
- isa<ObjCProtocolDecl>(D) ||
- isa<ObjCImplDecl>(D) ||
- isa<ImportDecl>(D) ||
- isa<PragmaCommentDecl>(D) ||
- isa<PragmaDetectMismatchDecl>(D))
- return true;
- if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D))
- return !D->getDeclContext()->isFunctionOrMethod();
- if (const auto *Var = dyn_cast<VarDecl>(D))
- return Var->isFileVarDecl() &&
- (Var->isThisDeclarationADefinition() == VarDecl::Definition ||
- OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var));
- if (const auto *Func = dyn_cast<FunctionDecl>(D))
- return Func->doesThisDeclarationHaveABody() || HasBody;
-
- if (auto *ES = D->getASTContext().getExternalSource())
- if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
- return true;
-
- return false;
-}
-
-/// Get the correct cursor and offset for loading a declaration.
-ASTReader::RecordLocation
-ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) {
- GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
- assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
- ModuleFile *M = I->second;
- const DeclOffset &DOffs =
- M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS];
- Loc = TranslateSourceLocation(*M, DOffs.getLocation());
- return RecordLocation(M, DOffs.BitOffset);
-}
-
-ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) {
- auto I = GlobalBitOffsetsMap.find(GlobalOffset);
-
- assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map");
- return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset);
-}
-
-uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) {
- return LocalOffset + M.GlobalBitOffset;
-}
-
-static bool isSameTemplateParameterList(const TemplateParameterList *X,
- const TemplateParameterList *Y);
-
-/// Determine whether two template parameters are similar enough
-/// that they may be used in declarations of the same template.
-static bool isSameTemplateParameter(const NamedDecl *X,
- const NamedDecl *Y) {
- if (X->getKind() != Y->getKind())
- return false;
-
- if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) {
- const auto *TY = cast<TemplateTypeParmDecl>(Y);
- return TX->isParameterPack() == TY->isParameterPack();
- }
-
- if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) {
- const auto *TY = cast<NonTypeTemplateParmDecl>(Y);
- return TX->isParameterPack() == TY->isParameterPack() &&
- TX->getASTContext().hasSameType(TX->getType(), TY->getType());
- }
-
- const auto *TX = cast<TemplateTemplateParmDecl>(X);
- const auto *TY = cast<TemplateTemplateParmDecl>(Y);
- return TX->isParameterPack() == TY->isParameterPack() &&
- isSameTemplateParameterList(TX->getTemplateParameters(),
- TY->getTemplateParameters());
-}
-
-static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) {
- if (auto *NS = X->getAsNamespace())
- return NS;
- if (auto *NAS = X->getAsNamespaceAlias())
- return NAS->getNamespace();
- return nullptr;
-}
-
-static bool isSameQualifier(const NestedNameSpecifier *X,
- const NestedNameSpecifier *Y) {
- if (auto *NSX = getNamespace(X)) {
- auto *NSY = getNamespace(Y);
- if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl())
- return false;
- } else if (X->getKind() != Y->getKind())
- return false;
-
- // FIXME: For namespaces and types, we're permitted to check that the entity
- // is named via the same tokens. We should probably do so.
- switch (X->getKind()) {
- case NestedNameSpecifier::Identifier:
- if (X->getAsIdentifier() != Y->getAsIdentifier())
- return false;
- break;
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- // We've already checked that we named the same namespace.
- break;
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- if (X->getAsType()->getCanonicalTypeInternal() !=
- Y->getAsType()->getCanonicalTypeInternal())
- return false;
- break;
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
- }
-
- // Recurse into earlier portion of NNS, if any.
- auto *PX = X->getPrefix();
- auto *PY = Y->getPrefix();
- if (PX && PY)
- return isSameQualifier(PX, PY);
- return !PX && !PY;
-}
-
-/// Determine whether two template parameter lists are similar enough
-/// that they may be used in declarations of the same template.
-static bool isSameTemplateParameterList(const TemplateParameterList *X,
- const TemplateParameterList *Y) {
- if (X->size() != Y->size())
- return false;
-
- for (unsigned I = 0, N = X->size(); I != N; ++I)
- if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I)))
- return false;
-
- return true;
-}
-
-/// Determine whether the attributes we can overload on are identical for A and
-/// B. Will ignore any overloadable attrs represented in the type of A and B.
-static bool hasSameOverloadableAttrs(const FunctionDecl *A,
- const FunctionDecl *B) {
- // Note that pass_object_size attributes are represented in the function's
- // ExtParameterInfo, so we don't need to check them here.
-
- llvm::FoldingSetNodeID Cand1ID, Cand2ID;
- auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>();
- auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>();
-
- for (auto Pair : zip_longest(AEnableIfAttrs, BEnableIfAttrs)) {
- Optional<EnableIfAttr *> Cand1A = std::get<0>(Pair);
- Optional<EnableIfAttr *> Cand2A = std::get<1>(Pair);
-
- // Return false if the number of enable_if attributes is different.
- if (!Cand1A || !Cand2A)
- return false;
-
- Cand1ID.clear();
- Cand2ID.clear();
-
- (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true);
- (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true);
-
- // Return false if any of the enable_if expressions of A and B are
- // different.
- if (Cand1ID != Cand2ID)
- return false;
- }
- return true;
-}
-
-/// Determine whether the two declarations refer to the same entity.
-static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
- assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
-
- if (X == Y)
- return true;
-
- // Must be in the same context.
- //
- // Note that we can't use DeclContext::Equals here, because the DeclContexts
- // could be two different declarations of the same function. (We will fix the
- // semantic DC to refer to the primary definition after merging.)
- if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()),
- cast<Decl>(Y->getDeclContext()->getRedeclContext())))
- return false;
-
- // Two typedefs refer to the same entity if they have the same underlying
- // type.
- if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X))
- if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y))
- return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(),
- TypedefY->getUnderlyingType());
-
- // Must have the same kind.
- if (X->getKind() != Y->getKind())
- return false;
-
- // Objective-C classes and protocols with the same name always match.
- if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))
- return true;
-
- if (isa<ClassTemplateSpecializationDecl>(X)) {
- // No need to handle these here: we merge them when adding them to the
- // template.
- return false;
- }
-
- // Compatible tags match.
- if (const auto *TagX = dyn_cast<TagDecl>(X)) {
- const auto *TagY = cast<TagDecl>(Y);
- return (TagX->getTagKind() == TagY->getTagKind()) ||
- ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class ||
- TagX->getTagKind() == TTK_Interface) &&
- (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class ||
- TagY->getTagKind() == TTK_Interface));
- }
-
- // Functions with the same type and linkage match.
- // FIXME: This needs to cope with merging of prototyped/non-prototyped
- // functions, etc.
- if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) {
- const auto *FuncY = cast<FunctionDecl>(Y);
- if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) {
- const auto *CtorY = cast<CXXConstructorDecl>(Y);
- if (CtorX->getInheritedConstructor() &&
- !isSameEntity(CtorX->getInheritedConstructor().getConstructor(),
- CtorY->getInheritedConstructor().getConstructor()))
- return false;
- }
-
- if (FuncX->isMultiVersion() != FuncY->isMultiVersion())
- return false;
-
- // Multiversioned functions with different feature strings are represented
- // as separate declarations.
- if (FuncX->isMultiVersion()) {
- const auto *TAX = FuncX->getAttr<TargetAttr>();
- const auto *TAY = FuncY->getAttr<TargetAttr>();
- assert(TAX && TAY && "Multiversion Function without target attribute");
-
- if (TAX->getFeaturesStr() != TAY->getFeaturesStr())
- return false;
- }
-
- ASTContext &C = FuncX->getASTContext();
- auto GetTypeAsWritten = [](const FunctionDecl *FD) {
- // Map to the first declaration that we've already merged into this one.
- // The TSI of redeclarations might not match (due to calling conventions
- // being inherited onto the type but not the TSI), but the TSI type of
- // the first declaration of the function should match across modules.
- FD = FD->getCanonicalDecl();
- return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType()
- : FD->getType();
- };
- QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY);
- if (!C.hasSameType(XT, YT)) {
- // We can get functions with different types on the redecl chain in C++17
- // if they have differing exception specifications and at least one of
- // the excpetion specs is unresolved.
- auto *XFPT = XT->getAs<FunctionProtoType>();
- auto *YFPT = YT->getAs<FunctionProtoType>();
- if (C.getLangOpts().CPlusPlus17 && XFPT && YFPT &&
- (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||
- isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&
- C.hasSameFunctionTypeIgnoringExceptionSpec(XT, YT))
- return true;
- return false;
- }
- return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
- hasSameOverloadableAttrs(FuncX, FuncY);
- }
-
- // Variables with the same type and linkage match.
- if (const auto *VarX = dyn_cast<VarDecl>(X)) {
- const auto *VarY = cast<VarDecl>(Y);
- if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) {
- ASTContext &C = VarX->getASTContext();
- if (C.hasSameType(VarX->getType(), VarY->getType()))
- return true;
-
- // We can get decls with different types on the redecl chain. Eg.
- // template <typename T> struct S { static T Var[]; }; // #1
- // template <typename T> T S<T>::Var[sizeof(T)]; // #2
- // Only? happens when completing an incomplete array type. In this case
- // when comparing #1 and #2 we should go through their element type.
- const ArrayType *VarXTy = C.getAsArrayType(VarX->getType());
- const ArrayType *VarYTy = C.getAsArrayType(VarY->getType());
- if (!VarXTy || !VarYTy)
- return false;
- if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType())
- return C.hasSameType(VarXTy->getElementType(), VarYTy->getElementType());
- }
- return false;
- }
-
- // Namespaces with the same name and inlinedness match.
- if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) {
- const auto *NamespaceY = cast<NamespaceDecl>(Y);
- return NamespaceX->isInline() == NamespaceY->isInline();
- }
-
- // Identical template names and kinds match if their template parameter lists
- // and patterns match.
- if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) {
- const auto *TemplateY = cast<TemplateDecl>(Y);
- return isSameEntity(TemplateX->getTemplatedDecl(),
- TemplateY->getTemplatedDecl()) &&
- isSameTemplateParameterList(TemplateX->getTemplateParameters(),
- TemplateY->getTemplateParameters());
- }
-
- // Fields with the same name and the same type match.
- if (const auto *FDX = dyn_cast<FieldDecl>(X)) {
- const auto *FDY = cast<FieldDecl>(Y);
- // FIXME: Also check the bitwidth is odr-equivalent, if any.
- return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());
- }
-
- // Indirect fields with the same target field match.
- if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) {
- const auto *IFDY = cast<IndirectFieldDecl>(Y);
- return IFDX->getAnonField()->getCanonicalDecl() ==
- IFDY->getAnonField()->getCanonicalDecl();
- }
-
- // Enumerators with the same name match.
- if (isa<EnumConstantDecl>(X))
- // FIXME: Also check the value is odr-equivalent.
- return true;
-
- // Using shadow declarations with the same target match.
- if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) {
- const auto *USY = cast<UsingShadowDecl>(Y);
- return USX->getTargetDecl() == USY->getTargetDecl();
- }
-
- // Using declarations with the same qualifier match. (We already know that
- // the name matches.)
- if (const auto *UX = dyn_cast<UsingDecl>(X)) {
- const auto *UY = cast<UsingDecl>(Y);
- return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
- UX->hasTypename() == UY->hasTypename() &&
- UX->isAccessDeclaration() == UY->isAccessDeclaration();
- }
- if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) {
- const auto *UY = cast<UnresolvedUsingValueDecl>(Y);
- return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
- UX->isAccessDeclaration() == UY->isAccessDeclaration();
- }
- if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X))
- return isSameQualifier(
- UX->getQualifier(),
- cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier());
-
- // Namespace alias definitions with the same target match.
- if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) {
- const auto *NAY = cast<NamespaceAliasDecl>(Y);
- return NAX->getNamespace()->Equals(NAY->getNamespace());
- }
-
- return false;
-}
-
-/// Find the context in which we should search for previous declarations when
-/// looking for declarations to merge.
-DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
- DeclContext *DC) {
- if (auto *ND = dyn_cast<NamespaceDecl>(DC))
- return ND->getOriginalNamespace();
-
- if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
- // Try to dig out the definition.
- auto *DD = RD->DefinitionData;
- if (!DD)
- DD = RD->getCanonicalDecl()->DefinitionData;
-
- // If there's no definition yet, then DC's definition is added by an update
- // record, but we've not yet loaded that update record. In this case, we
- // commit to DC being the canonical definition now, and will fix this when
- // we load the update record.
- if (!DD) {
- DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
- RD->setCompleteDefinition(true);
- RD->DefinitionData = DD;
- RD->getCanonicalDecl()->DefinitionData = DD;
-
- // Track that we did this horrible thing so that we can fix it later.
- Reader.PendingFakeDefinitionData.insert(
- std::make_pair(DD, ASTReader::PendingFakeDefinitionKind::Fake));
- }
-
- return DD->Definition;
- }
-
- if (auto *ED = dyn_cast<EnumDecl>(DC))
- return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
- : nullptr;
-
- // We can see the TU here only if we have no Sema object. In that case,
- // there's no TU scope to look in, so using the DC alone is sufficient.
- if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
- return TU;
-
- return nullptr;
-}
-
-ASTDeclReader::FindExistingResult::~FindExistingResult() {
- // Record that we had a typedef name for linkage whether or not we merge
- // with that declaration.
- if (TypedefNameForLinkage) {
- DeclContext *DC = New->getDeclContext()->getRedeclContext();
- Reader.ImportedTypedefNamesForLinkage.insert(
- std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New));
- return;
- }
-
- if (!AddResult || Existing)
- return;
-
- DeclarationName Name = New->getDeclName();
- DeclContext *DC = New->getDeclContext()->getRedeclContext();
- if (needsAnonymousDeclarationNumber(New)) {
- setAnonymousDeclForMerging(Reader, New->getLexicalDeclContext(),
- AnonymousDeclNumber, New);
- } else if (DC->isTranslationUnit() &&
- !Reader.getContext().getLangOpts().CPlusPlus) {
- if (Reader.getIdResolver().tryAddTopLevelDecl(New, Name))
- Reader.PendingFakeLookupResults[Name.getAsIdentifierInfo()]
- .push_back(New);
- } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) {
- // Add the declaration to its redeclaration context so later merging
- // lookups will find it.
- MergeDC->makeDeclVisibleInContextImpl(New, /*Internal*/true);
- }
-}
-
-/// Find the declaration that should be merged into, given the declaration found
-/// by name lookup. If we're merging an anonymous declaration within a typedef,
-/// we need a matching typedef, and we merge with the type inside it.
-static NamedDecl *getDeclForMerging(NamedDecl *Found,
- bool IsTypedefNameForLinkage) {
- if (!IsTypedefNameForLinkage)
- return Found;
-
- // If we found a typedef declaration that gives a name to some other
- // declaration, then we want that inner declaration. Declarations from
- // AST files are handled via ImportedTypedefNamesForLinkage.
- if (Found->isFromASTFile())
- return nullptr;
-
- if (auto *TND = dyn_cast<TypedefNameDecl>(Found))
- return TND->getAnonDeclWithTypedefName(/*AnyRedecl*/true);
-
- return nullptr;
-}
-
-/// Find the declaration to use to populate the anonymous declaration table
-/// for the given lexical DeclContext. We only care about finding local
-/// definitions of the context; we'll merge imported ones as we go.
-DeclContext *
-ASTDeclReader::getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC) {
- // For classes, we track the definition as we merge.
- if (auto *RD = dyn_cast<CXXRecordDecl>(LexicalDC)) {
- auto *DD = RD->getCanonicalDecl()->DefinitionData;
- return DD ? DD->Definition : nullptr;
- }
-
- // For anything else, walk its merged redeclarations looking for a definition.
- // Note that we can't just call getDefinition here because the redeclaration
- // chain isn't wired up.
- for (auto *D : merged_redecls(cast<Decl>(LexicalDC))) {
- if (auto *FD = dyn_cast<FunctionDecl>(D))
- if (FD->isThisDeclarationADefinition())
- return FD;
- if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
- if (MD->isThisDeclarationADefinition())
- return MD;
- }
-
- // No merged definition yet.
- return nullptr;
-}
-
-NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,
- DeclContext *DC,
- unsigned Index) {
- // If the lexical context has been merged, look into the now-canonical
- // definition.
- auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl();
-
- // If we've seen this before, return the canonical declaration.
- auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC];
- if (Index < Previous.size() && Previous[Index])
- return Previous[Index];
-
- // If this is the first time, but we have parsed a declaration of the context,
- // build the anonymous declaration list from the parsed declaration.
- auto *PrimaryDC = getPrimaryDCForAnonymousDecl(DC);
- if (PrimaryDC && !cast<Decl>(PrimaryDC)->isFromASTFile()) {
- numberAnonymousDeclsWithin(PrimaryDC, [&](NamedDecl *ND, unsigned Number) {
- if (Previous.size() == Number)
- Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl()));
- else
- Previous[Number] = cast<NamedDecl>(ND->getCanonicalDecl());
- });
- }
-
- return Index < Previous.size() ? Previous[Index] : nullptr;
-}
-
-void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader,
- DeclContext *DC, unsigned Index,
- NamedDecl *D) {
- auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl();
-
- auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC];
- if (Index >= Previous.size())
- Previous.resize(Index + 1);
- if (!Previous[Index])
- Previous[Index] = D;
-}
-
-ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
- DeclarationName Name = TypedefNameForLinkage ? TypedefNameForLinkage
- : D->getDeclName();
-
- if (!Name && !needsAnonymousDeclarationNumber(D)) {
- // Don't bother trying to find unnamed declarations that are in
- // unmergeable contexts.
- FindExistingResult Result(Reader, D, /*Existing=*/nullptr,
- AnonymousDeclNumber, TypedefNameForLinkage);
- Result.suppress();
- return Result;
- }
-
- DeclContext *DC = D->getDeclContext()->getRedeclContext();
- if (TypedefNameForLinkage) {
- auto It = Reader.ImportedTypedefNamesForLinkage.find(
- std::make_pair(DC, TypedefNameForLinkage));
- if (It != Reader.ImportedTypedefNamesForLinkage.end())
- if (isSameEntity(It->second, D))
- return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber,
- TypedefNameForLinkage);
- // Go on to check in other places in case an existing typedef name
- // was not imported.
- }
-
- if (needsAnonymousDeclarationNumber(D)) {
- // This is an anonymous declaration that we may need to merge. Look it up
- // in its context by number.
- if (auto *Existing = getAnonymousDeclForMerging(
- Reader, D->getLexicalDeclContext(), AnonymousDeclNumber))
- if (isSameEntity(Existing, D))
- return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
- TypedefNameForLinkage);
- } else if (DC->isTranslationUnit() &&
- !Reader.getContext().getLangOpts().CPlusPlus) {
- IdentifierResolver &IdResolver = Reader.getIdResolver();
-
- // Temporarily consider the identifier to be up-to-date. We don't want to
- // cause additional lookups here.
- class UpToDateIdentifierRAII {
- IdentifierInfo *II;
- bool WasOutToDate = false;
-
- public:
- explicit UpToDateIdentifierRAII(IdentifierInfo *II) : II(II) {
- if (II) {
- WasOutToDate = II->isOutOfDate();
- if (WasOutToDate)
- II->setOutOfDate(false);
- }
- }
-
- ~UpToDateIdentifierRAII() {
- if (WasOutToDate)
- II->setOutOfDate(true);
- }
- } UpToDate(Name.getAsIdentifierInfo());
-
- for (IdentifierResolver::iterator I = IdResolver.begin(Name),
- IEnd = IdResolver.end();
- I != IEnd; ++I) {
- if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
- if (isSameEntity(Existing, D))
- return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
- TypedefNameForLinkage);
- }
- } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) {
- DeclContext::lookup_result R = MergeDC->noload_lookup(Name);
- for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) {
- if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
- if (isSameEntity(Existing, D))
- return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
- TypedefNameForLinkage);
- }
- } else {
- // Not in a mergeable context.
- return FindExistingResult(Reader);
- }
-
- // If this declaration is from a merged context, make a note that we need to
- // check that the canonical definition of that context contains the decl.
- //
- // FIXME: We should do something similar if we merge two definitions of the
- // same template specialization into the same CXXRecordDecl.
- auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext());
- if (MergedDCIt != Reader.MergedDeclContexts.end() &&
- MergedDCIt->second == D->getDeclContext())
- Reader.PendingOdrMergeChecks.push_back(D);
-
- return FindExistingResult(Reader, D, /*Existing=*/nullptr,
- AnonymousDeclNumber, TypedefNameForLinkage);
-}
-
-template<typename DeclT>
-Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) {
- return D->RedeclLink.getLatestNotUpdated();
-}
-
-Decl *ASTDeclReader::getMostRecentDeclImpl(...) {
- llvm_unreachable("getMostRecentDecl on non-redeclarable declaration");
-}
-
-Decl *ASTDeclReader::getMostRecentDecl(Decl *D) {
- assert(D);
-
- switch (D->getKind()) {
-#define ABSTRACT_DECL(TYPE)
-#define DECL(TYPE, BASE) \
- case Decl::TYPE: \
- return getMostRecentDeclImpl(cast<TYPE##Decl>(D));
-#include "clang/AST/DeclNodes.inc"
- }
- llvm_unreachable("unknown decl kind");
-}
-
-Decl *ASTReader::getMostRecentExistingDecl(Decl *D) {
- return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl());
-}
-
-template<typename DeclT>
-void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
- Redeclarable<DeclT> *D,
- Decl *Previous, Decl *Canon) {
- D->RedeclLink.setPrevious(cast<DeclT>(Previous));
- D->First = cast<DeclT>(Previous)->First;
-}
-
-namespace clang {
-
-template<>
-void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
- Redeclarable<VarDecl> *D,
- Decl *Previous, Decl *Canon) {
- auto *VD = static_cast<VarDecl *>(D);
- auto *PrevVD = cast<VarDecl>(Previous);
- D->RedeclLink.setPrevious(PrevVD);
- D->First = PrevVD->First;
-
- // We should keep at most one definition on the chain.
- // FIXME: Cache the definition once we've found it. Building a chain with
- // N definitions currently takes O(N^2) time here.
- if (VD->isThisDeclarationADefinition() == VarDecl::Definition) {
- for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) {
- if (CurD->isThisDeclarationADefinition() == VarDecl::Definition) {
- Reader.mergeDefinitionVisibility(CurD, VD);
- VD->demoteThisDefinitionToDeclaration();
- break;
- }
- }
- }
-}
-
-static bool isUndeducedReturnType(QualType T) {
- auto *DT = T->getContainedDeducedType();
- return DT && !DT->isDeduced();
-}
-
-template<>
-void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
- Redeclarable<FunctionDecl> *D,
- Decl *Previous, Decl *Canon) {
- auto *FD = static_cast<FunctionDecl *>(D);
- auto *PrevFD = cast<FunctionDecl>(Previous);
-
- FD->RedeclLink.setPrevious(PrevFD);
- FD->First = PrevFD->First;
-
- // If the previous declaration is an inline function declaration, then this
- // declaration is too.
- if (PrevFD->isInlined() != FD->isInlined()) {
- // FIXME: [dcl.fct.spec]p4:
- // If a function with external linkage is declared inline in one
- // translation unit, it shall be declared inline in all translation
- // units in which it appears.
- //
- // Be careful of this case:
- //
- // module A:
- // template<typename T> struct X { void f(); };
- // template<typename T> inline void X<T>::f() {}
- //
- // module B instantiates the declaration of X<int>::f
- // module C instantiates the definition of X<int>::f
- //
- // If module B and C are merged, we do not have a violation of this rule.
- FD->setImplicitlyInline(true);
- }
-
- auto *FPT = FD->getType()->getAs<FunctionProtoType>();
- auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>();
- if (FPT && PrevFPT) {
- // If we need to propagate an exception specification along the redecl
- // chain, make a note of that so that we can do so later.
- bool IsUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType());
- bool WasUnresolved =
- isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType());
- if (IsUnresolved != WasUnresolved)
- Reader.PendingExceptionSpecUpdates.insert(
- {Canon, IsUnresolved ? PrevFD : FD});
-
- // If we need to propagate a deduced return type along the redecl chain,
- // make a note of that so that we can do it later.
- bool IsUndeduced = isUndeducedReturnType(FPT->getReturnType());
- bool WasUndeduced = isUndeducedReturnType(PrevFPT->getReturnType());
- if (IsUndeduced != WasUndeduced)
- Reader.PendingDeducedTypeUpdates.insert(
- {cast<FunctionDecl>(Canon),
- (IsUndeduced ? PrevFPT : FPT)->getReturnType()});
- }
-}
-
-} // namespace clang
-
-void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {
- llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
-}
-
-/// Inherit the default template argument from \p From to \p To. Returns
-/// \c false if there is no default template for \p From.
-template <typename ParmDecl>
-static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
- Decl *ToD) {
- auto *To = cast<ParmDecl>(ToD);
- if (!From->hasDefaultArgument())
- return false;
- To->setInheritedDefaultArgument(Context, From);
- return true;
-}
-
-static void inheritDefaultTemplateArguments(ASTContext &Context,
- TemplateDecl *From,
- TemplateDecl *To) {
- auto *FromTP = From->getTemplateParameters();
- auto *ToTP = To->getTemplateParameters();
- assert(FromTP->size() == ToTP->size() && "merged mismatched templates?");
-
- for (unsigned I = 0, N = FromTP->size(); I != N; ++I) {
- NamedDecl *FromParam = FromTP->getParam(I);
- NamedDecl *ToParam = ToTP->getParam(I);
-
- if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam))
- inheritDefaultTemplateArgument(Context, FTTP, ToParam);
- else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam))
- inheritDefaultTemplateArgument(Context, FNTTP, ToParam);
- else
- inheritDefaultTemplateArgument(
- Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam);
- }
-}
-
-void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
- Decl *Previous, Decl *Canon) {
- assert(D && Previous);
-
- switch (D->getKind()) {
-#define ABSTRACT_DECL(TYPE)
-#define DECL(TYPE, BASE) \
- case Decl::TYPE: \
- attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous, Canon); \
- break;
-#include "clang/AST/DeclNodes.inc"
- }
-
- // If the declaration was visible in one module, a redeclaration of it in
- // another module remains visible even if it wouldn't be visible by itself.
- //
- // FIXME: In this case, the declaration should only be visible if a module
- // that makes it visible has been imported.
- D->IdentifierNamespace |=
- Previous->IdentifierNamespace &
- (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
-
- // If the declaration declares a template, it may inherit default arguments
- // from the previous declaration.
- if (auto *TD = dyn_cast<TemplateDecl>(D))
- inheritDefaultTemplateArguments(Reader.getContext(),
- cast<TemplateDecl>(Previous), TD);
-}
-
-template<typename DeclT>
-void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) {
- D->RedeclLink.setLatest(cast<DeclT>(Latest));
-}
-
-void ASTDeclReader::attachLatestDeclImpl(...) {
- llvm_unreachable("attachLatestDecl on non-redeclarable declaration");
-}
-
-void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
- assert(D && Latest);
-
- switch (D->getKind()) {
-#define ABSTRACT_DECL(TYPE)
-#define DECL(TYPE, BASE) \
- case Decl::TYPE: \
- attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \
- break;
-#include "clang/AST/DeclNodes.inc"
- }
-}
-
-template<typename DeclT>
-void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) {
- D->RedeclLink.markIncomplete();
-}
-
-void ASTDeclReader::markIncompleteDeclChainImpl(...) {
- llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration");
-}
-
-void ASTReader::markIncompleteDeclChain(Decl *D) {
- switch (D->getKind()) {
-#define ABSTRACT_DECL(TYPE)
-#define DECL(TYPE, BASE) \
- case Decl::TYPE: \
- ASTDeclReader::markIncompleteDeclChainImpl(cast<TYPE##Decl>(D)); \
- break;
-#include "clang/AST/DeclNodes.inc"
- }
-}
-
-/// Read the declaration at the given offset from the AST file.
-Decl *ASTReader::ReadDeclRecord(DeclID ID) {
- unsigned Index = ID - NUM_PREDEF_DECL_IDS;
- SourceLocation DeclLoc;
- RecordLocation Loc = DeclCursorForID(ID, DeclLoc);
- llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
- // Keep track of where we are in the stream, then jump back there
- // after reading this declaration.
- SavedStreamPosition SavedPosition(DeclsCursor);
-
- ReadingKindTracker ReadingKind(Read_Decl, *this);
-
- // Note that we are loading a declaration record.
- Deserializing ADecl(this);
-
- DeclsCursor.JumpToBit(Loc.Offset);
- ASTRecordReader Record(*this, *Loc.F);
- ASTDeclReader Reader(*this, Record, Loc, ID, DeclLoc);
- unsigned Code = DeclsCursor.ReadCode();
-
- ASTContext &Context = getContext();
- Decl *D = nullptr;
- switch ((DeclCode)Record.readRecord(DeclsCursor, Code)) {
- case DECL_CONTEXT_LEXICAL:
- case DECL_CONTEXT_VISIBLE:
- llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
- case DECL_TYPEDEF:
- D = TypedefDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_TYPEALIAS:
- D = TypeAliasDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_ENUM:
- D = EnumDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_RECORD:
- D = RecordDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_ENUM_CONSTANT:
- D = EnumConstantDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_FUNCTION:
- D = FunctionDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_LINKAGE_SPEC:
- D = LinkageSpecDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_EXPORT:
- D = ExportDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_LABEL:
- D = LabelDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_NAMESPACE:
- D = NamespaceDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_NAMESPACE_ALIAS:
- D = NamespaceAliasDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_USING:
- D = UsingDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_USING_PACK:
- D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_USING_SHADOW:
- D = UsingShadowDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CONSTRUCTOR_USING_SHADOW:
- D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_USING_DIRECTIVE:
- D = UsingDirectiveDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_UNRESOLVED_USING_VALUE:
- D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_UNRESOLVED_USING_TYPENAME:
- D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CXX_RECORD:
- D = CXXRecordDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CXX_DEDUCTION_GUIDE:
- D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CXX_METHOD:
- D = CXXMethodDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CXX_CONSTRUCTOR:
- D = CXXConstructorDecl::CreateDeserialized(Context, ID, false);
- break;
- case DECL_CXX_INHERITED_CONSTRUCTOR:
- D = CXXConstructorDecl::CreateDeserialized(Context, ID, true);
- break;
- case DECL_CXX_DESTRUCTOR:
- D = CXXDestructorDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CXX_CONVERSION:
- D = CXXConversionDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_ACCESS_SPEC:
- D = AccessSpecDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_FRIEND:
- D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_FRIEND_TEMPLATE:
- D = FriendTemplateDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CLASS_TEMPLATE:
- D = ClassTemplateDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CLASS_TEMPLATE_SPECIALIZATION:
- D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
- D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_VAR_TEMPLATE:
- D = VarTemplateDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_VAR_TEMPLATE_SPECIALIZATION:
- D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION:
- D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
- D = ClassScopeFunctionSpecializationDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_FUNCTION_TEMPLATE:
- D = FunctionTemplateDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_TEMPLATE_TYPE_PARM:
- D = TemplateTypeParmDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_NON_TYPE_TEMPLATE_PARM:
- D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
- D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID,
- Record.readInt());
- break;
- case DECL_TEMPLATE_TEMPLATE_PARM:
- D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK:
- D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID,
- Record.readInt());
- break;
- case DECL_TYPE_ALIAS_TEMPLATE:
- D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_STATIC_ASSERT:
- D = StaticAssertDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_METHOD:
- D = ObjCMethodDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_INTERFACE:
- D = ObjCInterfaceDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_IVAR:
- D = ObjCIvarDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_PROTOCOL:
- D = ObjCProtocolDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_AT_DEFS_FIELD:
- D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_CATEGORY:
- D = ObjCCategoryDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_CATEGORY_IMPL:
- D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_IMPLEMENTATION:
- D = ObjCImplementationDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_COMPATIBLE_ALIAS:
- D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_PROPERTY:
- D = ObjCPropertyDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_PROPERTY_IMPL:
- D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_FIELD:
- D = FieldDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_INDIRECTFIELD:
- D = IndirectFieldDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_VAR:
- D = VarDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_IMPLICIT_PARAM:
- D = ImplicitParamDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_PARM_VAR:
- D = ParmVarDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_DECOMPOSITION:
- D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_BINDING:
- D = BindingDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_FILE_SCOPE_ASM:
- D = FileScopeAsmDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_BLOCK:
- D = BlockDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_MS_PROPERTY:
- D = MSPropertyDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_CAPTURED:
- D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_CXX_BASE_SPECIFIERS:
- Error("attempt to read a C++ base-specifier record as a declaration");
- return nullptr;
- case DECL_CXX_CTOR_INITIALIZERS:
- Error("attempt to read a C++ ctor initializer record as a declaration");
- return nullptr;
- case DECL_IMPORT:
- // Note: last entry of the ImportDecl record is the number of stored source
- // locations.
- D = ImportDecl::CreateDeserialized(Context, ID, Record.back());
- break;
- case DECL_OMP_THREADPRIVATE:
- D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_OMP_REQUIRES:
- D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_OMP_DECLARE_REDUCTION:
- D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OMP_CAPTUREDEXPR:
- D = OMPCapturedExprDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_PRAGMA_COMMENT:
- D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt());
- break;
- case DECL_PRAGMA_DETECT_MISMATCH:
- D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID,
- Record.readInt());
- break;
- case DECL_EMPTY:
- D = EmptyDecl::CreateDeserialized(Context, ID);
- break;
- case DECL_OBJC_TYPE_PARAM:
- D = ObjCTypeParamDecl::CreateDeserialized(Context, ID);
- break;
- }
-
- assert(D && "Unknown declaration reading AST file");
- LoadedDecl(Index, D);
- // Set the DeclContext before doing any deserialization, to make sure internal
- // calls to Decl::getASTContext() by Decl's methods will find the
- // TranslationUnitDecl without crashing.
- D->setDeclContext(Context.getTranslationUnitDecl());
- Reader.Visit(D);
-
- // If this declaration is also a declaration context, get the
- // offsets for its tables of lexical and visible declarations.
- if (auto *DC = dyn_cast<DeclContext>(D)) {
- std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
- if (Offsets.first &&
- ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC))
- return nullptr;
- if (Offsets.second &&
- ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID))
- return nullptr;
- }
- assert(Record.getIdx() == Record.size());
-
- // Load any relevant update records.
- PendingUpdateRecords.push_back(
- PendingUpdateRecord(ID, D, /*JustLoaded=*/true));
-
- // Load the categories after recursive loading is finished.
- if (auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
- // If we already have a definition when deserializing the ObjCInterfaceDecl,
- // we put the Decl in PendingDefinitions so we can pull the categories here.
- if (Class->isThisDeclarationADefinition() ||
- PendingDefinitions.count(Class))
- loadObjCCategories(ID, Class);
-
- // If we have deserialized a declaration that has a definition the
- // AST consumer might need to know about, queue it.
- // We don't pass it to the consumer immediately because we may be in recursive
- // loading, and some declarations may still be initializing.
- PotentiallyInterestingDecls.push_back(
- InterestingDecl(D, Reader.hasPendingBody()));
-
- return D;
-}
-
-void ASTReader::PassInterestingDeclsToConsumer() {
- assert(Consumer);
-
- if (PassingDeclsToConsumer)
- return;
-
- // Guard variable to avoid recursively redoing the process of passing
- // decls to consumer.
- SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
- true);
-
- // Ensure that we've loaded all potentially-interesting declarations
- // that need to be eagerly loaded.
- for (auto ID : EagerlyDeserializedDecls)
- GetDecl(ID);
- EagerlyDeserializedDecls.clear();
-
- while (!PotentiallyInterestingDecls.empty()) {
- InterestingDecl D = PotentiallyInterestingDecls.front();
- PotentiallyInterestingDecls.pop_front();
- if (isConsumerInterestedIn(getContext(), D.getDecl(), D.hasPendingBody()))
- PassInterestingDeclToConsumer(D.getDecl());
- }
-}
-
-void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
- // The declaration may have been modified by files later in the chain.
- // If this is the case, read the record containing the updates from each file
- // and pass it to ASTDeclReader to make the modifications.
- serialization::GlobalDeclID ID = Record.ID;
- Decl *D = Record.D;
- ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
- DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
-
- SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
-
- if (UpdI != DeclUpdateOffsets.end()) {
- auto UpdateOffsets = std::move(UpdI->second);
- DeclUpdateOffsets.erase(UpdI);
-
- // Check if this decl was interesting to the consumer. If we just loaded
- // the declaration, then we know it was interesting and we skip the call
- // to isConsumerInterestedIn because it is unsafe to call in the
- // current ASTReader state.
- bool WasInteresting =
- Record.JustLoaded || isConsumerInterestedIn(getContext(), D, false);
- for (auto &FileAndOffset : UpdateOffsets) {
- ModuleFile *F = FileAndOffset.first;
- uint64_t Offset = FileAndOffset.second;
- llvm::BitstreamCursor &Cursor = F->DeclsCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Offset);
- unsigned Code = Cursor.ReadCode();
- ASTRecordReader Record(*this, *F);
- unsigned RecCode = Record.readRecord(Cursor, Code);
- (void)RecCode;
- assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
-
- ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
- SourceLocation());
- Reader.UpdateDecl(D, PendingLazySpecializationIDs);
-
- // We might have made this declaration interesting. If so, remember that
- // we need to hand it off to the consumer.
- if (!WasInteresting &&
- isConsumerInterestedIn(getContext(), D, Reader.hasPendingBody())) {
- PotentiallyInterestingDecls.push_back(
- InterestingDecl(D, Reader.hasPendingBody()));
- WasInteresting = true;
- }
- }
- }
- // Add the lazy specializations to the template.
- assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) ||
- isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) &&
- "Must not have pending specializations");
- if (auto *CTD = dyn_cast<ClassTemplateDecl>(D))
- ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs);
- else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
- ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs);
- else if (auto *VTD = dyn_cast<VarTemplateDecl>(D))
- ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs);
- PendingLazySpecializationIDs.clear();
-
- // Load the pending visible updates for this decl context, if it has any.
- auto I = PendingVisibleUpdates.find(ID);
- if (I != PendingVisibleUpdates.end()) {
- auto VisibleUpdates = std::move(I->second);
- PendingVisibleUpdates.erase(I);
-
- auto *DC = cast<DeclContext>(D)->getPrimaryContext();
- for (const auto &Update : VisibleUpdates)
- Lookups[DC].Table.add(
- Update.Mod, Update.Data,
- reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod));
- DC->setHasExternalVisibleStorage(true);
- }
-}
-
-void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
- // Attach FirstLocal to the end of the decl chain.
- Decl *CanonDecl = FirstLocal->getCanonicalDecl();
- if (FirstLocal != CanonDecl) {
- Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl);
- ASTDeclReader::attachPreviousDecl(
- *this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl,
- CanonDecl);
- }
-
- if (!LocalOffset) {
- ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal);
- return;
- }
-
- // Load the list of other redeclarations from this module file.
- ModuleFile *M = getOwningModuleFile(FirstLocal);
- assert(M && "imported decl from no module file");
-
- llvm::BitstreamCursor &Cursor = M->DeclsCursor;
- SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(LocalOffset);
-
- RecordData Record;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record);
- (void)RecCode;
- assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!");
-
- // FIXME: We have several different dispatches on decl kind here; maybe
- // we should instead generate one loop per kind and dispatch up-front?
- Decl *MostRecent = FirstLocal;
- for (unsigned I = 0, N = Record.size(); I != N; ++I) {
- auto *D = GetLocalDecl(*M, Record[N - I - 1]);
- ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
- MostRecent = D;
- }
- ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);
-}
-
-namespace {
-
- /// Given an ObjC interface, goes through the modules and links to the
- /// interface all the categories for it.
- class ObjCCategoriesVisitor {
- ASTReader &Reader;
- ObjCInterfaceDecl *Interface;
- llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized;
- ObjCCategoryDecl *Tail = nullptr;
- llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap;
- serialization::GlobalDeclID InterfaceID;
- unsigned PreviousGeneration;
-
- void add(ObjCCategoryDecl *Cat) {
- // Only process each category once.
- if (!Deserialized.erase(Cat))
- return;
-
- // Check for duplicate categories.
- if (Cat->getDeclName()) {
- ObjCCategoryDecl *&Existing = NameCategoryMap[Cat->getDeclName()];
- if (Existing &&
- Reader.getOwningModuleFile(Existing)
- != Reader.getOwningModuleFile(Cat)) {
- // FIXME: We should not warn for duplicates in diamond:
- //
- // MT //
- // / \ //
- // ML MR //
- // \ / //
- // MB //
- //
- // If there are duplicates in ML/MR, there will be warning when
- // creating MB *and* when importing MB. We should not warn when
- // importing.
- Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
- << Interface->getDeclName() << Cat->getDeclName();
- Reader.Diag(Existing->getLocation(), diag::note_previous_definition);
- } else if (!Existing) {
- // Record this category.
- Existing = Cat;
- }
- }
-
- // Add this category to the end of the chain.
- if (Tail)
- ASTDeclReader::setNextObjCCategory(Tail, Cat);
- else
- Interface->setCategoryListRaw(Cat);
- Tail = Cat;
- }
-
- public:
- ObjCCategoriesVisitor(ASTReader &Reader,
- ObjCInterfaceDecl *Interface,
- llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized,
- serialization::GlobalDeclID InterfaceID,
- unsigned PreviousGeneration)
- : Reader(Reader), Interface(Interface), Deserialized(Deserialized),
- InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) {
- // Populate the name -> category map with the set of known categories.
- for (auto *Cat : Interface->known_categories()) {
- if (Cat->getDeclName())
- NameCategoryMap[Cat->getDeclName()] = Cat;
-
- // Keep track of the tail of the category list.
- Tail = Cat;
- }
- }
-
- bool operator()(ModuleFile &M) {
- // If we've loaded all of the category information we care about from
- // this module file, we're done.
- if (M.Generation <= PreviousGeneration)
- return true;
-
- // Map global ID of the definition down to the local ID used in this
- // module file. If there is no such mapping, we'll find nothing here
- // (or in any module it imports).
- DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID);
- if (!LocalID)
- return true;
-
- // Perform a binary search to find the local redeclarations for this
- // declaration (if any).
- const ObjCCategoriesInfo Compare = { LocalID, 0 };
- const ObjCCategoriesInfo *Result
- = std::lower_bound(M.ObjCCategoriesMap,
- M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap,
- Compare);
- if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap ||
- Result->DefinitionID != LocalID) {
- // We didn't find anything. If the class definition is in this module
- // file, then the module files it depends on cannot have any categories,
- // so suppress further lookup.
- return Reader.isDeclIDFromModule(InterfaceID, M);
- }
-
- // We found something. Dig out all of the categories.
- unsigned Offset = Result->Offset;
- unsigned N = M.ObjCCategories[Offset];
- M.ObjCCategories[Offset++] = 0; // Don't try to deserialize again
- for (unsigned I = 0; I != N; ++I)
- add(cast_or_null<ObjCCategoryDecl>(
- Reader.GetLocalDecl(M, M.ObjCCategories[Offset++])));
- return true;
- }
- };
-
-} // namespace
-
-void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,
- ObjCInterfaceDecl *D,
- unsigned PreviousGeneration) {
- ObjCCategoriesVisitor Visitor(*this, D, CategoriesDeserialized, ID,
- PreviousGeneration);
- ModuleMgr.visit(Visitor);
-}
-
-template<typename DeclT, typename Fn>
-static void forAllLaterRedecls(DeclT *D, Fn F) {
- F(D);
-
- // Check whether we've already merged D into its redeclaration chain.
- // MostRecent may or may not be nullptr if D has not been merged. If
- // not, walk the merged redecl chain and see if it's there.
- auto *MostRecent = D->getMostRecentDecl();
- bool Found = false;
- for (auto *Redecl = MostRecent; Redecl && !Found;
- Redecl = Redecl->getPreviousDecl())
- Found = (Redecl == D);
-
- // If this declaration is merged, apply the functor to all later decls.
- if (Found) {
- for (auto *Redecl = MostRecent; Redecl != D;
- Redecl = Redecl->getPreviousDecl())
- F(Redecl);
- }
-}
-
-void ASTDeclReader::UpdateDecl(Decl *D,
- llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) {
- while (Record.getIdx() < Record.size()) {
- switch ((DeclUpdateKind)Record.readInt()) {
- case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
- auto *RD = cast<CXXRecordDecl>(D);
- // FIXME: If we also have an update record for instantiating the
- // definition of D, we need that to happen before we get here.
- Decl *MD = Record.readDecl();
- assert(MD && "couldn't read decl from update record");
- // FIXME: We should call addHiddenDecl instead, to add the member
- // to its DeclContext.
- RD->addedMember(MD);
- break;
- }
-
- case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
- // It will be added to the template's lazy specialization set.
- PendingLazySpecializationIDs.push_back(ReadDeclID());
- break;
-
- case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
- auto *Anon = ReadDeclAs<NamespaceDecl>();
-
- // Each module has its own anonymous namespace, which is disjoint from
- // any other module's anonymous namespaces, so don't attach the anonymous
- // namespace at all.
- if (!Record.isModule()) {
- if (auto *TU = dyn_cast<TranslationUnitDecl>(D))
- TU->setAnonymousNamespace(Anon);
- else
- cast<NamespaceDecl>(D)->setAnonymousNamespace(Anon);
- }
- break;
- }
-
- case UPD_CXX_ADDED_VAR_DEFINITION: {
- auto *VD = cast<VarDecl>(D);
- VD->NonParmVarDeclBits.IsInline = Record.readInt();
- VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt();
- uint64_t Val = Record.readInt();
- if (Val && !VD->getInit()) {
- VD->setInit(Record.readExpr());
- if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3
- EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
- Eval->CheckedICE = true;
- Eval->IsICE = Val == 3;
- }
- }
- break;
- }
-
- case UPD_CXX_POINT_OF_INSTANTIATION: {
- SourceLocation POI = Record.readSourceLocation();
- if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) {
- VTSD->setPointOfInstantiation(POI);
- } else if (auto *VD = dyn_cast<VarDecl>(D)) {
- VD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
- } else {
- auto *FD = cast<FunctionDecl>(D);
- if (auto *FTSInfo = FD->TemplateOrSpecialization
- .dyn_cast<FunctionTemplateSpecializationInfo *>())
- FTSInfo->setPointOfInstantiation(POI);
- else
- FD->TemplateOrSpecialization.get<MemberSpecializationInfo *>()
- ->setPointOfInstantiation(POI);
- }
- break;
- }
-
- case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: {
- auto *Param = cast<ParmVarDecl>(D);
-
- // We have to read the default argument regardless of whether we use it
- // so that hypothetical further update records aren't messed up.
- // TODO: Add a function to skip over the next expr record.
- auto *DefaultArg = Record.readExpr();
-
- // Only apply the update if the parameter still has an uninstantiated
- // default argument.
- if (Param->hasUninstantiatedDefaultArg())
- Param->setDefaultArg(DefaultArg);
- break;
- }
-
- case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER: {
- auto *FD = cast<FieldDecl>(D);
- auto *DefaultInit = Record.readExpr();
-
- // Only apply the update if the field still has an uninstantiated
- // default member initializer.
- if (FD->hasInClassInitializer() && !FD->getInClassInitializer()) {
- if (DefaultInit)
- FD->setInClassInitializer(DefaultInit);
- else
- // Instantiation failed. We can get here if we serialized an AST for
- // an invalid program.
- FD->removeInClassInitializer();
- }
- break;
- }
-
- case UPD_CXX_ADDED_FUNCTION_DEFINITION: {
- auto *FD = cast<FunctionDecl>(D);
- if (Reader.PendingBodies[FD]) {
- // FIXME: Maybe check for ODR violations.
- // It's safe to stop now because this update record is always last.
- return;
- }
-
- if (Record.readInt()) {
- // Maintain AST consistency: any later redeclarations of this function
- // are inline if this one is. (We might have merged another declaration
- // into this one.)
- forAllLaterRedecls(FD, [](FunctionDecl *FD) {
- FD->setImplicitlyInline();
- });
- }
- FD->setInnerLocStart(ReadSourceLocation());
- ReadFunctionDefinition(FD);
- assert(Record.getIdx() == Record.size() && "lazy body must be last");
- break;
- }
-
- case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
- auto *RD = cast<CXXRecordDecl>(D);
- auto *OldDD = RD->getCanonicalDecl()->DefinitionData;
- bool HadRealDefinition =
- OldDD && (OldDD->Definition != RD ||
- !Reader.PendingFakeDefinitionData.count(OldDD));
- RD->setParamDestroyedInCallee(Record.readInt());
- RD->setArgPassingRestrictions(
- (RecordDecl::ArgPassingKind)Record.readInt());
- ReadCXXRecordDefinition(RD, /*Update*/true);
-
- // Visible update is handled separately.
- uint64_t LexicalOffset = ReadLocalOffset();
- if (!HadRealDefinition && LexicalOffset) {
- Record.readLexicalDeclContextStorage(LexicalOffset, RD);
- Reader.PendingFakeDefinitionData.erase(OldDD);
- }
-
- auto TSK = (TemplateSpecializationKind)Record.readInt();
- SourceLocation POI = ReadSourceLocation();
- if (MemberSpecializationInfo *MSInfo =
- RD->getMemberSpecializationInfo()) {
- MSInfo->setTemplateSpecializationKind(TSK);
- MSInfo->setPointOfInstantiation(POI);
- } else {
- auto *Spec = cast<ClassTemplateSpecializationDecl>(RD);
- Spec->setTemplateSpecializationKind(TSK);
- Spec->setPointOfInstantiation(POI);
-
- if (Record.readInt()) {
- auto *PartialSpec =
- ReadDeclAs<ClassTemplatePartialSpecializationDecl>();
- SmallVector<TemplateArgument, 8> TemplArgs;
- Record.readTemplateArgumentList(TemplArgs);
- auto *TemplArgList = TemplateArgumentList::CreateCopy(
- Reader.getContext(), TemplArgs);
-
- // FIXME: If we already have a partial specialization set,
- // check that it matches.
- if (!Spec->getSpecializedTemplateOrPartial()
- .is<ClassTemplatePartialSpecializationDecl *>())
- Spec->setInstantiationOf(PartialSpec, TemplArgList);
- }
- }
-
- RD->setTagKind((TagTypeKind)Record.readInt());
- RD->setLocation(ReadSourceLocation());
- RD->setLocStart(ReadSourceLocation());
- RD->setBraceRange(ReadSourceRange());
-
- if (Record.readInt()) {
- AttrVec Attrs;
- Record.readAttributes(Attrs);
- // If the declaration already has attributes, we assume that some other
- // AST file already loaded them.
- if (!D->hasAttrs())
- D->setAttrsImpl(Attrs, Reader.getContext());
- }
- break;
- }
-
- case UPD_CXX_RESOLVED_DTOR_DELETE: {
- // Set the 'operator delete' directly to avoid emitting another update
- // record.
- auto *Del = ReadDeclAs<FunctionDecl>();
- auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl());
- auto *ThisArg = Record.readExpr();
- // FIXME: Check consistency if we have an old and new operator delete.
- if (!First->OperatorDelete) {
- First->OperatorDelete = Del;
- First->OperatorDeleteThisArg = ThisArg;
- }
- break;
- }
-
- case UPD_CXX_RESOLVED_EXCEPTION_SPEC: {
- FunctionProtoType::ExceptionSpecInfo ESI;
- SmallVector<QualType, 8> ExceptionStorage;
- Record.readExceptionSpec(ExceptionStorage, ESI);
-
- // Update this declaration's exception specification, if needed.
- auto *FD = cast<FunctionDecl>(D);
- auto *FPT = FD->getType()->castAs<FunctionProtoType>();
- // FIXME: If the exception specification is already present, check that it
- // matches.
- if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
- FD->setType(Reader.getContext().getFunctionType(
- FPT->getReturnType(), FPT->getParamTypes(),
- FPT->getExtProtoInfo().withExceptionSpec(ESI)));
-
- // When we get to the end of deserializing, see if there are other decls
- // that we need to propagate this exception specification onto.
- Reader.PendingExceptionSpecUpdates.insert(
- std::make_pair(FD->getCanonicalDecl(), FD));
- }
- break;
- }
-
- case UPD_CXX_DEDUCED_RETURN_TYPE: {
- auto *FD = cast<FunctionDecl>(D);
- QualType DeducedResultType = Record.readType();
- Reader.PendingDeducedTypeUpdates.insert(
- {FD->getCanonicalDecl(), DeducedResultType});
- break;
- }
-
- case UPD_DECL_MARKED_USED:
- // Maintain AST consistency: any later redeclarations are used too.
- D->markUsed(Reader.getContext());
- break;
-
- case UPD_MANGLING_NUMBER:
- Reader.getContext().setManglingNumber(cast<NamedDecl>(D),
- Record.readInt());
- break;
-
- case UPD_STATIC_LOCAL_NUMBER:
- Reader.getContext().setStaticLocalNumber(cast<VarDecl>(D),
- Record.readInt());
- break;
-
- case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
- D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(Reader.getContext(),
- ReadSourceRange()));
- break;
-
- case UPD_DECL_EXPORTED: {
- unsigned SubmoduleID = readSubmoduleID();
- auto *Exported = cast<NamedDecl>(D);
- Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr;
- Reader.getContext().mergeDefinitionIntoModule(Exported, Owner);
- Reader.PendingMergedDefinitionsToDeduplicate.insert(Exported);
- break;
- }
-
- case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
- D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(
- Reader.getContext(),
- static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt()),
- ReadSourceRange()));
- break;
-
- case UPD_ADDED_ATTR_TO_RECORD:
- AttrVec Attrs;
- Record.readAttributes(Attrs);
- assert(Attrs.size() == 1);
- D->addAttr(Attrs[0]);
- break;
- }
- }
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h
deleted file mode 100644
index 37a929907dc..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderInternals.h
+++ /dev/null
@@ -1,293 +0,0 @@
-//===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides internal definitions used in the AST reader.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
-#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
-
-#include "MultiOnDiskHashTable.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/OnDiskHashTable.h"
-#include <ctime>
-#include <utility>
-
-namespace clang {
-
-class ASTReader;
-class FileEntry;
-struct HeaderFileInfo;
-class HeaderSearch;
-class IdentifierTable;
-class ObjCMethodDecl;
-
-namespace serialization {
-
-class ModuleFile;
-
-namespace reader {
-
-/// Class that performs name lookup into a DeclContext stored
-/// in an AST file.
-class ASTDeclContextNameLookupTrait {
- ASTReader &Reader;
- ModuleFile &F;
-
-public:
- // Maximum number of lookup tables we allow before condensing the tables.
- static const int MaxTables = 4;
-
- /// The lookup result is a list of global declaration IDs.
- using data_type = SmallVector<DeclID, 4>;
-
- struct data_type_builder {
- data_type &Data;
- llvm::DenseSet<DeclID> Found;
-
- data_type_builder(data_type &D) : Data(D) {}
-
- void insert(DeclID ID) {
- // Just use a linear scan unless we have more than a few IDs.
- if (Found.empty() && !Data.empty()) {
- if (Data.size() <= 4) {
- for (auto I : Found)
- if (I == ID)
- return;
- Data.push_back(ID);
- return;
- }
-
- // Switch to tracking found IDs in the set.
- Found.insert(Data.begin(), Data.end());
- }
-
- if (Found.insert(ID).second)
- Data.push_back(ID);
- }
- };
- using hash_value_type = unsigned;
- using offset_type = unsigned;
- using file_type = ModuleFile *;
-
- using external_key_type = DeclarationName;
- using internal_key_type = DeclarationNameKey;
-
- explicit ASTDeclContextNameLookupTrait(ASTReader &Reader, ModuleFile &F)
- : Reader(Reader), F(F) {}
-
- static bool EqualKey(const internal_key_type &a, const internal_key_type &b) {
- return a == b;
- }
-
- static hash_value_type ComputeHash(const internal_key_type &Key) {
- return Key.getHash();
- }
-
- static internal_key_type GetInternalKey(const external_key_type &Name) {
- return Name;
- }
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char *&d);
-
- internal_key_type ReadKey(const unsigned char *d, unsigned);
-
- void ReadDataInto(internal_key_type, const unsigned char *d,
- unsigned DataLen, data_type_builder &Val);
-
- static void MergeDataInto(const data_type &From, data_type_builder &To) {
- To.Data.reserve(To.Data.size() + From.size());
- for (DeclID ID : From)
- To.insert(ID);
- }
-
- file_type ReadFileRef(const unsigned char *&d);
-};
-
-struct DeclContextLookupTable {
- MultiOnDiskHashTable<ASTDeclContextNameLookupTrait> Table;
-};
-
-/// Base class for the trait describing the on-disk hash table for the
-/// identifiers in an AST file.
-///
-/// This class is not useful by itself; rather, it provides common
-/// functionality for accessing the on-disk hash table of identifiers
-/// in an AST file. Different subclasses customize that functionality
-/// based on what information they are interested in. Those subclasses
-/// must provide the \c data_type type and the ReadData operation, only.
-class ASTIdentifierLookupTraitBase {
-public:
- using external_key_type = StringRef;
- using internal_key_type = StringRef;
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
- return a == b;
- }
-
- static hash_value_type ComputeHash(const internal_key_type& a);
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d);
-
- // This hopefully will just get inlined and removed by the optimizer.
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
-
- // This hopefully will just get inlined and removed by the optimizer.
- static const external_key_type&
- GetExternalKey(const internal_key_type& x) { return x; }
-
- static internal_key_type ReadKey(const unsigned char* d, unsigned n);
-};
-
-/// Class that performs lookup for an identifier stored in an AST file.
-class ASTIdentifierLookupTrait : public ASTIdentifierLookupTraitBase {
- ASTReader &Reader;
- ModuleFile &F;
-
- // If we know the IdentifierInfo in advance, it is here and we will
- // not build a new one. Used when deserializing information about an
- // identifier that was constructed before the AST file was read.
- IdentifierInfo *KnownII;
-
-public:
- using data_type = IdentifierInfo *;
-
- ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
- IdentifierInfo *II = nullptr)
- : Reader(Reader), F(F), KnownII(II) {}
-
- data_type ReadData(const internal_key_type& k,
- const unsigned char* d,
- unsigned DataLen);
-
- IdentID ReadIdentifierID(const unsigned char *d);
-
- ASTReader &getReader() const { return Reader; }
-};
-
-/// The on-disk hash table used to contain information about
-/// all of the identifiers in the program.
-using ASTIdentifierLookupTable =
- llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>;
-
-/// Class that performs lookup for a selector's entries in the global
-/// method pool stored in an AST file.
-class ASTSelectorLookupTrait {
- ASTReader &Reader;
- ModuleFile &F;
-
-public:
- struct data_type {
- SelectorID ID;
- unsigned InstanceBits;
- unsigned FactoryBits;
- bool InstanceHasMoreThanOneDecl;
- bool FactoryHasMoreThanOneDecl;
- SmallVector<ObjCMethodDecl *, 2> Instance;
- SmallVector<ObjCMethodDecl *, 2> Factory;
- };
-
- using external_key_type = Selector;
- using internal_key_type = external_key_type;
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F)
- : Reader(Reader), F(F) {}
-
- static bool EqualKey(const internal_key_type& a,
- const internal_key_type& b) {
- return a == b;
- }
-
- static hash_value_type ComputeHash(Selector Sel);
-
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d);
-
- internal_key_type ReadKey(const unsigned char* d, unsigned);
- data_type ReadData(Selector, const unsigned char* d, unsigned DataLen);
-};
-
-/// The on-disk hash table used for the global method pool.
-using ASTSelectorLookupTable =
- llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>;
-
-/// Trait class used to search the on-disk hash table containing all of
-/// the header search information.
-///
-/// The on-disk hash table contains a mapping from each header path to
-/// information about that header (how many times it has been included, its
-/// controlling macro, etc.). Note that we actually hash based on the size
-/// and mtime, and support "deep" comparisons of file names based on current
-/// inode numbers, so that the search can cope with non-normalized path names
-/// and symlinks.
-class HeaderFileInfoTrait {
- ASTReader &Reader;
- ModuleFile &M;
- HeaderSearch *HS;
- const char *FrameworkStrings;
-
-public:
- using external_key_type = const FileEntry *;
-
- struct internal_key_type {
- off_t Size;
- time_t ModTime;
- StringRef Filename;
- bool Imported;
- };
-
- using internal_key_ref = const internal_key_type &;
-
- using data_type = HeaderFileInfo;
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
- const char *FrameworkStrings)
- : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) {}
-
- static hash_value_type ComputeHash(internal_key_ref ikey);
- internal_key_type GetInternalKey(const FileEntry *FE);
- bool EqualKey(internal_key_ref a, internal_key_ref b);
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d);
-
- static internal_key_type ReadKey(const unsigned char *d, unsigned);
-
- data_type ReadData(internal_key_ref,const unsigned char *d, unsigned DataLen);
-};
-
-/// The on-disk hash table used for known header files.
-using HeaderFileInfoLookupTable =
- llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>;
-
-} // namespace reader
-
-} // namespace serialization
-
-} // namespace clang
-
-#endif // LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp
deleted file mode 100644
index 60abea95bfa..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp
+++ /dev/null
@@ -1,3418 +0,0 @@
-//===- ASTReaderStmt.cpp - Stmt/Expr Deserialization ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Statement/expression deserialization. This implements the
-// ASTReader::ReadStmt method.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/ASTReader.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/AttrIterator.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclAccessPair.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprOpenMP.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/OpenMPClause.h"
-#include "clang/AST/OperationKinds.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/CapturedStmt.h"
-#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Lambda.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TypeTraits.h"
-#include "clang/Lex/Token.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <string>
-
-using namespace clang;
-using namespace serialization;
-
-namespace clang {
-
- class ASTStmtReader : public StmtVisitor<ASTStmtReader> {
- friend class OMPClauseReader;
-
- ASTRecordReader &Record;
- llvm::BitstreamCursor &DeclsCursor;
-
- SourceLocation ReadSourceLocation() {
- return Record.readSourceLocation();
- }
-
- SourceRange ReadSourceRange() {
- return Record.readSourceRange();
- }
-
- std::string ReadString() {
- return Record.readString();
- }
-
- TypeSourceInfo *GetTypeSourceInfo() {
- return Record.getTypeSourceInfo();
- }
-
- Decl *ReadDecl() {
- return Record.readDecl();
- }
-
- template<typename T>
- T *ReadDeclAs() {
- return Record.readDeclAs<T>();
- }
-
- void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc,
- DeclarationName Name) {
- Record.readDeclarationNameLoc(DNLoc, Name);
- }
-
- void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo) {
- Record.readDeclarationNameInfo(NameInfo);
- }
-
- public:
- ASTStmtReader(ASTRecordReader &Record, llvm::BitstreamCursor &Cursor)
- : Record(Record), DeclsCursor(Cursor) {}
-
- /// The number of record fields required for the Stmt class
- /// itself.
- static const unsigned NumStmtFields = 0;
-
- /// The number of record fields required for the Expr class
- /// itself.
- static const unsigned NumExprFields = NumStmtFields + 7;
-
- /// Read and initialize a ExplicitTemplateArgumentList structure.
- void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
- TemplateArgumentLoc *ArgsLocArray,
- unsigned NumTemplateArgs);
-
- /// Read and initialize a ExplicitTemplateArgumentList structure.
- void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList,
- unsigned NumTemplateArgs);
-
- void VisitStmt(Stmt *S);
-#define STMT(Type, Base) \
- void Visit##Type(Type *);
-#include "clang/AST/StmtNodes.inc"
- };
-
-} // namespace clang
-
-void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
- TemplateArgumentLoc *ArgsLocArray,
- unsigned NumTemplateArgs) {
- SourceLocation TemplateKWLoc = ReadSourceLocation();
- TemplateArgumentListInfo ArgInfo;
- ArgInfo.setLAngleLoc(ReadSourceLocation());
- ArgInfo.setRAngleLoc(ReadSourceLocation());
- for (unsigned i = 0; i != NumTemplateArgs; ++i)
- ArgInfo.addArgument(Record.readTemplateArgumentLoc());
- Args.initializeFrom(TemplateKWLoc, ArgInfo, ArgsLocArray);
-}
-
-void ASTStmtReader::VisitStmt(Stmt *S) {
- assert(Record.getIdx() == NumStmtFields && "Incorrect statement field count");
-}
-
-void ASTStmtReader::VisitNullStmt(NullStmt *S) {
- VisitStmt(S);
- S->setSemiLoc(ReadSourceLocation());
- S->NullStmtBits.HasLeadingEmptyMacro = Record.readInt();
-}
-
-void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
- VisitStmt(S);
- SmallVector<Stmt *, 16> Stmts;
- unsigned NumStmts = Record.readInt();
- while (NumStmts--)
- Stmts.push_back(Record.readSubStmt());
- S->setStmts(Stmts);
- S->CompoundStmtBits.LBraceLoc = ReadSourceLocation();
- S->RBraceLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitSwitchCase(SwitchCase *S) {
- VisitStmt(S);
- Record.recordSwitchCaseID(S, Record.readInt());
- S->setKeywordLoc(ReadSourceLocation());
- S->setColonLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
- VisitSwitchCase(S);
- bool CaseStmtIsGNURange = Record.readInt();
- S->setLHS(Record.readSubExpr());
- S->setSubStmt(Record.readSubStmt());
- if (CaseStmtIsGNURange) {
- S->setRHS(Record.readSubExpr());
- S->setEllipsisLoc(ReadSourceLocation());
- }
-}
-
-void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
- VisitSwitchCase(S);
- S->setSubStmt(Record.readSubStmt());
-}
-
-void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
- VisitStmt(S);
- auto *LD = ReadDeclAs<LabelDecl>();
- LD->setStmt(S);
- S->setDecl(LD);
- S->setSubStmt(Record.readSubStmt());
- S->setIdentLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
- VisitStmt(S);
- // NumAttrs in AttributedStmt is set when creating an empty
- // AttributedStmt in AttributedStmt::CreateEmpty, since it is needed
- // to allocate the right amount of space for the trailing Attr *.
- uint64_t NumAttrs = Record.readInt();
- AttrVec Attrs;
- Record.readAttributes(Attrs);
- (void)NumAttrs;
- assert(NumAttrs == S->AttributedStmtBits.NumAttrs);
- assert(NumAttrs == Attrs.size());
- std::copy(Attrs.begin(), Attrs.end(), S->getAttrArrayPtr());
- S->SubStmt = Record.readSubStmt();
- S->AttributedStmtBits.AttrLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitIfStmt(IfStmt *S) {
- VisitStmt(S);
-
- S->setConstexpr(Record.readInt());
- bool HasElse = Record.readInt();
- bool HasVar = Record.readInt();
- bool HasInit = Record.readInt();
-
- S->setCond(Record.readSubExpr());
- S->setThen(Record.readSubStmt());
- if (HasElse)
- S->setElse(Record.readSubStmt());
- if (HasVar)
- S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
- if (HasInit)
- S->setInit(Record.readSubStmt());
-
- S->setIfLoc(ReadSourceLocation());
- if (HasElse)
- S->setElseLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
- VisitStmt(S);
-
- bool HasInit = Record.readInt();
- bool HasVar = Record.readInt();
- bool AllEnumCasesCovered = Record.readInt();
- if (AllEnumCasesCovered)
- S->setAllEnumCasesCovered();
-
- S->setCond(Record.readSubExpr());
- S->setBody(Record.readSubStmt());
- if (HasInit)
- S->setInit(Record.readSubStmt());
- if (HasVar)
- S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
-
- S->setSwitchLoc(ReadSourceLocation());
-
- SwitchCase *PrevSC = nullptr;
- for (auto E = Record.size(); Record.getIdx() != E; ) {
- SwitchCase *SC = Record.getSwitchCaseWithID(Record.readInt());
- if (PrevSC)
- PrevSC->setNextSwitchCase(SC);
- else
- S->setSwitchCaseList(SC);
-
- PrevSC = SC;
- }
-}
-
-void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
- VisitStmt(S);
-
- bool HasVar = Record.readInt();
-
- S->setCond(Record.readSubExpr());
- S->setBody(Record.readSubStmt());
- if (HasVar)
- S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
-
- S->setWhileLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitDoStmt(DoStmt *S) {
- VisitStmt(S);
- S->setCond(Record.readSubExpr());
- S->setBody(Record.readSubStmt());
- S->setDoLoc(ReadSourceLocation());
- S->setWhileLoc(ReadSourceLocation());
- S->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitForStmt(ForStmt *S) {
- VisitStmt(S);
- S->setInit(Record.readSubStmt());
- S->setCond(Record.readSubExpr());
- S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>());
- S->setInc(Record.readSubExpr());
- S->setBody(Record.readSubStmt());
- S->setForLoc(ReadSourceLocation());
- S->setLParenLoc(ReadSourceLocation());
- S->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
- VisitStmt(S);
- S->setLabel(ReadDeclAs<LabelDecl>());
- S->setGotoLoc(ReadSourceLocation());
- S->setLabelLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
- VisitStmt(S);
- S->setGotoLoc(ReadSourceLocation());
- S->setStarLoc(ReadSourceLocation());
- S->setTarget(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitContinueStmt(ContinueStmt *S) {
- VisitStmt(S);
- S->setContinueLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitBreakStmt(BreakStmt *S) {
- VisitStmt(S);
- S->setBreakLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) {
- VisitStmt(S);
-
- bool HasNRVOCandidate = Record.readInt();
-
- S->setRetValue(Record.readSubExpr());
- if (HasNRVOCandidate)
- S->setNRVOCandidate(ReadDeclAs<VarDecl>());
-
- S->setReturnLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
- VisitStmt(S);
- S->setStartLoc(ReadSourceLocation());
- S->setEndLoc(ReadSourceLocation());
-
- if (Record.size() - Record.getIdx() == 1) {
- // Single declaration
- S->setDeclGroup(DeclGroupRef(ReadDecl()));
- } else {
- SmallVector<Decl *, 16> Decls;
- int N = Record.size() - Record.getIdx();
- Decls.reserve(N);
- for (int I = 0; I < N; ++I)
- Decls.push_back(ReadDecl());
- S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Record.getContext(),
- Decls.data(),
- Decls.size())));
- }
-}
-
-void ASTStmtReader::VisitAsmStmt(AsmStmt *S) {
- VisitStmt(S);
- S->NumOutputs = Record.readInt();
- S->NumInputs = Record.readInt();
- S->NumClobbers = Record.readInt();
- S->setAsmLoc(ReadSourceLocation());
- S->setVolatile(Record.readInt());
- S->setSimple(Record.readInt());
-}
-
-void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) {
- VisitAsmStmt(S);
- S->setRParenLoc(ReadSourceLocation());
- S->setAsmString(cast_or_null<StringLiteral>(Record.readSubStmt()));
-
- unsigned NumOutputs = S->getNumOutputs();
- unsigned NumInputs = S->getNumInputs();
- unsigned NumClobbers = S->getNumClobbers();
-
- // Outputs and inputs
- SmallVector<IdentifierInfo *, 16> Names;
- SmallVector<StringLiteral*, 16> Constraints;
- SmallVector<Stmt*, 16> Exprs;
- for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
- Names.push_back(Record.getIdentifierInfo());
- Constraints.push_back(cast_or_null<StringLiteral>(Record.readSubStmt()));
- Exprs.push_back(Record.readSubStmt());
- }
-
- // Constraints
- SmallVector<StringLiteral*, 16> Clobbers;
- for (unsigned I = 0; I != NumClobbers; ++I)
- Clobbers.push_back(cast_or_null<StringLiteral>(Record.readSubStmt()));
-
- S->setOutputsAndInputsAndClobbers(Record.getContext(),
- Names.data(), Constraints.data(),
- Exprs.data(), NumOutputs, NumInputs,
- Clobbers.data(), NumClobbers);
-}
-
-void ASTStmtReader::VisitMSAsmStmt(MSAsmStmt *S) {
- VisitAsmStmt(S);
- S->LBraceLoc = ReadSourceLocation();
- S->EndLoc = ReadSourceLocation();
- S->NumAsmToks = Record.readInt();
- std::string AsmStr = ReadString();
-
- // Read the tokens.
- SmallVector<Token, 16> AsmToks;
- AsmToks.reserve(S->NumAsmToks);
- for (unsigned i = 0, e = S->NumAsmToks; i != e; ++i) {
- AsmToks.push_back(Record.readToken());
- }
-
- // The calls to reserve() for the FooData vectors are mandatory to
- // prevent dead StringRefs in the Foo vectors.
-
- // Read the clobbers.
- SmallVector<std::string, 16> ClobbersData;
- SmallVector<StringRef, 16> Clobbers;
- ClobbersData.reserve(S->NumClobbers);
- Clobbers.reserve(S->NumClobbers);
- for (unsigned i = 0, e = S->NumClobbers; i != e; ++i) {
- ClobbersData.push_back(ReadString());
- Clobbers.push_back(ClobbersData.back());
- }
-
- // Read the operands.
- unsigned NumOperands = S->NumOutputs + S->NumInputs;
- SmallVector<Expr*, 16> Exprs;
- SmallVector<std::string, 16> ConstraintsData;
- SmallVector<StringRef, 16> Constraints;
- Exprs.reserve(NumOperands);
- ConstraintsData.reserve(NumOperands);
- Constraints.reserve(NumOperands);
- for (unsigned i = 0; i != NumOperands; ++i) {
- Exprs.push_back(cast<Expr>(Record.readSubStmt()));
- ConstraintsData.push_back(ReadString());
- Constraints.push_back(ConstraintsData.back());
- }
-
- S->initialize(Record.getContext(), AsmStr, AsmToks,
- Constraints, Exprs, Clobbers);
-}
-
-void ASTStmtReader::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
- VisitStmt(S);
- assert(Record.peekInt() == S->NumParams);
- Record.skipInts(1);
- auto *StoredStmts = S->getStoredStmts();
- for (unsigned i = 0;
- i < CoroutineBodyStmt::SubStmt::FirstParamMove + S->NumParams; ++i)
- StoredStmts[i] = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitCoreturnStmt(CoreturnStmt *S) {
- VisitStmt(S);
- S->CoreturnLoc = Record.readSourceLocation();
- for (auto &SubStmt: S->SubStmts)
- SubStmt = Record.readSubStmt();
- S->IsImplicit = Record.readInt() != 0;
-}
-
-void ASTStmtReader::VisitCoawaitExpr(CoawaitExpr *E) {
- VisitExpr(E);
- E->KeywordLoc = ReadSourceLocation();
- for (auto &SubExpr: E->SubExprs)
- SubExpr = Record.readSubStmt();
- E->OpaqueValue = cast_or_null<OpaqueValueExpr>(Record.readSubStmt());
- E->setIsImplicit(Record.readInt() != 0);
-}
-
-void ASTStmtReader::VisitCoyieldExpr(CoyieldExpr *E) {
- VisitExpr(E);
- E->KeywordLoc = ReadSourceLocation();
- for (auto &SubExpr: E->SubExprs)
- SubExpr = Record.readSubStmt();
- E->OpaqueValue = cast_or_null<OpaqueValueExpr>(Record.readSubStmt());
-}
-
-void ASTStmtReader::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
- VisitExpr(E);
- E->KeywordLoc = ReadSourceLocation();
- for (auto &SubExpr: E->SubExprs)
- SubExpr = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) {
- VisitStmt(S);
- Record.skipInts(1);
- S->setCapturedDecl(ReadDeclAs<CapturedDecl>());
- S->setCapturedRegionKind(static_cast<CapturedRegionKind>(Record.readInt()));
- S->setCapturedRecordDecl(ReadDeclAs<RecordDecl>());
-
- // Capture inits
- for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(),
- E = S->capture_init_end();
- I != E; ++I)
- *I = Record.readSubExpr();
-
- // Body
- S->setCapturedStmt(Record.readSubStmt());
- S->getCapturedDecl()->setBody(S->getCapturedStmt());
-
- // Captures
- for (auto &I : S->captures()) {
- I.VarAndKind.setPointer(ReadDeclAs<VarDecl>());
- I.VarAndKind.setInt(
- static_cast<CapturedStmt::VariableCaptureKind>(Record.readInt()));
- I.Loc = ReadSourceLocation();
- }
-}
-
-void ASTStmtReader::VisitExpr(Expr *E) {
- VisitStmt(E);
- E->setType(Record.readType());
- E->setTypeDependent(Record.readInt());
- E->setValueDependent(Record.readInt());
- E->setInstantiationDependent(Record.readInt());
- E->ExprBits.ContainsUnexpandedParameterPack = Record.readInt();
- E->setValueKind(static_cast<ExprValueKind>(Record.readInt()));
- E->setObjectKind(static_cast<ExprObjectKind>(Record.readInt()));
- assert(Record.getIdx() == NumExprFields &&
- "Incorrect expression field count");
-}
-
-void ASTStmtReader::VisitConstantExpr(ConstantExpr *E) {
- VisitExpr(E);
- E->setSubExpr(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
- VisitExpr(E);
- bool HasFunctionName = Record.readInt();
- E->PredefinedExprBits.HasFunctionName = HasFunctionName;
- E->PredefinedExprBits.Kind = Record.readInt();
- E->setLocation(ReadSourceLocation());
- if (HasFunctionName)
- E->setFunctionName(cast<StringLiteral>(Record.readSubExpr()));
-}
-
-void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
- VisitExpr(E);
-
- E->DeclRefExprBits.HasQualifier = Record.readInt();
- E->DeclRefExprBits.HasFoundDecl = Record.readInt();
- E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record.readInt();
- E->DeclRefExprBits.HadMultipleCandidates = Record.readInt();
- E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt();
- unsigned NumTemplateArgs = 0;
- if (E->hasTemplateKWAndArgsInfo())
- NumTemplateArgs = Record.readInt();
-
- if (E->hasQualifier())
- new (E->getTrailingObjects<NestedNameSpecifierLoc>())
- NestedNameSpecifierLoc(Record.readNestedNameSpecifierLoc());
-
- if (E->hasFoundDecl())
- *E->getTrailingObjects<NamedDecl *>() = ReadDeclAs<NamedDecl>();
-
- if (E->hasTemplateKWAndArgsInfo())
- ReadTemplateKWAndArgsInfo(
- *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
- E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
-
- E->setDecl(ReadDeclAs<ValueDecl>());
- E->setLocation(ReadSourceLocation());
- ReadDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
-}
-
-void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
- VisitExpr(E);
- E->setLocation(ReadSourceLocation());
- E->setValue(Record.getContext(), Record.readAPInt());
-}
-
-void ASTStmtReader::VisitFixedPointLiteral(FixedPointLiteral *E) {
- VisitExpr(E);
- E->setLocation(ReadSourceLocation());
- E->setValue(Record.getContext(), Record.readAPInt());
-}
-
-void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
- VisitExpr(E);
- E->setRawSemantics(static_cast<Stmt::APFloatSemantics>(Record.readInt()));
- E->setExact(Record.readInt());
- E->setValue(Record.getContext(), Record.readAPFloat(E->getSemantics()));
- E->setLocation(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) {
- VisitExpr(E);
- E->setSubExpr(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitStringLiteral(StringLiteral *E) {
- VisitExpr(E);
-
- // NumConcatenated, Length and CharByteWidth are set by the empty
- // ctor since they are needed to allocate storage for the trailing objects.
- unsigned NumConcatenated = Record.readInt();
- unsigned Length = Record.readInt();
- unsigned CharByteWidth = Record.readInt();
- assert((NumConcatenated == E->getNumConcatenated()) &&
- "Wrong number of concatenated tokens!");
- assert((Length == E->getLength()) && "Wrong Length!");
- assert((CharByteWidth == E->getCharByteWidth()) && "Wrong character width!");
- E->StringLiteralBits.Kind = Record.readInt();
- E->StringLiteralBits.IsPascal = Record.readInt();
-
- // The character width is originally computed via mapCharByteWidth.
- // Check that the deserialized character width is consistant with the result
- // of calling mapCharByteWidth.
- assert((CharByteWidth ==
- StringLiteral::mapCharByteWidth(Record.getContext().getTargetInfo(),
- E->getKind())) &&
- "Wrong character width!");
-
- // Deserialize the trailing array of SourceLocation.
- for (unsigned I = 0; I < NumConcatenated; ++I)
- E->setStrTokenLoc(I, ReadSourceLocation());
-
- // Deserialize the trailing array of char holding the string data.
- char *StrData = E->getStrDataAsChar();
- for (unsigned I = 0; I < Length * CharByteWidth; ++I)
- StrData[I] = Record.readInt();
-}
-
-void ASTStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
- VisitExpr(E);
- E->setValue(Record.readInt());
- E->setLocation(ReadSourceLocation());
- E->setKind(static_cast<CharacterLiteral::CharacterKind>(Record.readInt()));
-}
-
-void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
- VisitExpr(E);
- E->setLParen(ReadSourceLocation());
- E->setRParen(ReadSourceLocation());
- E->setSubExpr(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
- VisitExpr(E);
- unsigned NumExprs = Record.readInt();
- assert((NumExprs == E->getNumExprs()) && "Wrong NumExprs!");
- for (unsigned I = 0; I != NumExprs; ++I)
- E->getTrailingObjects<Stmt *>()[I] = Record.readSubStmt();
- E->LParenLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
- VisitExpr(E);
- E->setSubExpr(Record.readSubExpr());
- E->setOpcode((UnaryOperator::Opcode)Record.readInt());
- E->setOperatorLoc(ReadSourceLocation());
- E->setCanOverflow(Record.readInt());
-}
-
-void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
- VisitExpr(E);
- assert(E->getNumComponents() == Record.peekInt());
- Record.skipInts(1);
- assert(E->getNumExpressions() == Record.peekInt());
- Record.skipInts(1);
- E->setOperatorLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
- E->setTypeSourceInfo(GetTypeSourceInfo());
- for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
- auto Kind = static_cast<OffsetOfNode::Kind>(Record.readInt());
- SourceLocation Start = ReadSourceLocation();
- SourceLocation End = ReadSourceLocation();
- switch (Kind) {
- case OffsetOfNode::Array:
- E->setComponent(I, OffsetOfNode(Start, Record.readInt(), End));
- break;
-
- case OffsetOfNode::Field:
- E->setComponent(
- I, OffsetOfNode(Start, ReadDeclAs<FieldDecl>(), End));
- break;
-
- case OffsetOfNode::Identifier:
- E->setComponent(
- I,
- OffsetOfNode(Start, Record.getIdentifierInfo(), End));
- break;
-
- case OffsetOfNode::Base: {
- auto *Base = new (Record.getContext()) CXXBaseSpecifier();
- *Base = Record.readCXXBaseSpecifier();
- E->setComponent(I, OffsetOfNode(Base));
- break;
- }
- }
- }
-
- for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
- E->setIndexExpr(I, Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
- VisitExpr(E);
- E->setKind(static_cast<UnaryExprOrTypeTrait>(Record.readInt()));
- if (Record.peekInt() == 0) {
- E->setArgument(Record.readSubExpr());
- Record.skipInts(1);
- } else {
- E->setArgument(GetTypeSourceInfo());
- }
- E->setOperatorLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- VisitExpr(E);
- E->setLHS(Record.readSubExpr());
- E->setRHS(Record.readSubExpr());
- E->setRBracketLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
- VisitExpr(E);
- E->setBase(Record.readSubExpr());
- E->setLowerBound(Record.readSubExpr());
- E->setLength(Record.readSubExpr());
- E->setColonLoc(ReadSourceLocation());
- E->setRBracketLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitCallExpr(CallExpr *E) {
- VisitExpr(E);
- unsigned NumArgs = Record.readInt();
- assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
- E->setRParenLoc(ReadSourceLocation());
- E->setCallee(Record.readSubExpr());
- for (unsigned I = 0; I != NumArgs; ++I)
- E->setArg(I, Record.readSubExpr());
- E->setADLCallKind(static_cast<CallExpr::ADLCallKind>(Record.readInt()));
-}
-
-void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
- VisitCallExpr(E);
-}
-
-void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
- // Don't call VisitExpr, this is fully initialized at creation.
- assert(E->getStmtClass() == Stmt::MemberExprClass &&
- "It's a subclass, we must advance Idx!");
-}
-
-void ASTStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
- VisitExpr(E);
- E->setBase(Record.readSubExpr());
- E->setIsaMemberLoc(ReadSourceLocation());
- E->setOpLoc(ReadSourceLocation());
- E->setArrow(Record.readInt());
-}
-
-void ASTStmtReader::
-VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
- VisitExpr(E);
- E->Operand = Record.readSubExpr();
- E->setShouldCopy(Record.readInt());
-}
-
-void ASTStmtReader::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
- VisitExplicitCastExpr(E);
- E->LParenLoc = ReadSourceLocation();
- E->BridgeKeywordLoc = ReadSourceLocation();
- E->Kind = Record.readInt();
-}
-
-void ASTStmtReader::VisitCastExpr(CastExpr *E) {
- VisitExpr(E);
- unsigned NumBaseSpecs = Record.readInt();
- assert(NumBaseSpecs == E->path_size());
- E->setSubExpr(Record.readSubExpr());
- E->setCastKind((CastKind)Record.readInt());
- CastExpr::path_iterator BaseI = E->path_begin();
- while (NumBaseSpecs--) {
- auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier;
- *BaseSpec = Record.readCXXBaseSpecifier();
- *BaseI++ = BaseSpec;
- }
-}
-
-void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
- VisitExpr(E);
- E->setLHS(Record.readSubExpr());
- E->setRHS(Record.readSubExpr());
- E->setOpcode((BinaryOperator::Opcode)Record.readInt());
- E->setOperatorLoc(ReadSourceLocation());
- E->setFPFeatures(FPOptions(Record.readInt()));
-}
-
-void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- VisitBinaryOperator(E);
- E->setComputationLHSType(Record.readType());
- E->setComputationResultType(Record.readType());
-}
-
-void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
- VisitExpr(E);
- E->SubExprs[ConditionalOperator::COND] = Record.readSubExpr();
- E->SubExprs[ConditionalOperator::LHS] = Record.readSubExpr();
- E->SubExprs[ConditionalOperator::RHS] = Record.readSubExpr();
- E->QuestionLoc = ReadSourceLocation();
- E->ColonLoc = ReadSourceLocation();
-}
-
-void
-ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
- VisitExpr(E);
- E->OpaqueValue = cast<OpaqueValueExpr>(Record.readSubExpr());
- E->SubExprs[BinaryConditionalOperator::COMMON] = Record.readSubExpr();
- E->SubExprs[BinaryConditionalOperator::COND] = Record.readSubExpr();
- E->SubExprs[BinaryConditionalOperator::LHS] = Record.readSubExpr();
- E->SubExprs[BinaryConditionalOperator::RHS] = Record.readSubExpr();
- E->QuestionLoc = ReadSourceLocation();
- E->ColonLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
- VisitCastExpr(E);
- E->setIsPartOfExplicitCast(Record.readInt());
-}
-
-void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
- VisitCastExpr(E);
- E->setTypeInfoAsWritten(GetTypeSourceInfo());
-}
-
-void ASTStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) {
- VisitExplicitCastExpr(E);
- E->setLParenLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- VisitExpr(E);
- E->setLParenLoc(ReadSourceLocation());
- E->setTypeSourceInfo(GetTypeSourceInfo());
- E->setInitializer(Record.readSubExpr());
- E->setFileScope(Record.readInt());
-}
-
-void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
- VisitExpr(E);
- E->setBase(Record.readSubExpr());
- E->setAccessor(Record.getIdentifierInfo());
- E->setAccessorLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
- VisitExpr(E);
- if (auto *SyntForm = cast_or_null<InitListExpr>(Record.readSubStmt()))
- E->setSyntacticForm(SyntForm);
- E->setLBraceLoc(ReadSourceLocation());
- E->setRBraceLoc(ReadSourceLocation());
- bool isArrayFiller = Record.readInt();
- Expr *filler = nullptr;
- if (isArrayFiller) {
- filler = Record.readSubExpr();
- E->ArrayFillerOrUnionFieldInit = filler;
- } else
- E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>();
- E->sawArrayRangeDesignator(Record.readInt());
- unsigned NumInits = Record.readInt();
- E->reserveInits(Record.getContext(), NumInits);
- if (isArrayFiller) {
- for (unsigned I = 0; I != NumInits; ++I) {
- Expr *init = Record.readSubExpr();
- E->updateInit(Record.getContext(), I, init ? init : filler);
- }
- } else {
- for (unsigned I = 0; I != NumInits; ++I)
- E->updateInit(Record.getContext(), I, Record.readSubExpr());
- }
-}
-
-void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
- using Designator = DesignatedInitExpr::Designator;
-
- VisitExpr(E);
- unsigned NumSubExprs = Record.readInt();
- assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
- for (unsigned I = 0; I != NumSubExprs; ++I)
- E->setSubExpr(I, Record.readSubExpr());
- E->setEqualOrColonLoc(ReadSourceLocation());
- E->setGNUSyntax(Record.readInt());
-
- SmallVector<Designator, 4> Designators;
- while (Record.getIdx() < Record.size()) {
- switch ((DesignatorTypes)Record.readInt()) {
- case DESIG_FIELD_DECL: {
- auto *Field = ReadDeclAs<FieldDecl>();
- SourceLocation DotLoc = ReadSourceLocation();
- SourceLocation FieldLoc = ReadSourceLocation();
- Designators.push_back(Designator(Field->getIdentifier(), DotLoc,
- FieldLoc));
- Designators.back().setField(Field);
- break;
- }
-
- case DESIG_FIELD_NAME: {
- const IdentifierInfo *Name = Record.getIdentifierInfo();
- SourceLocation DotLoc = ReadSourceLocation();
- SourceLocation FieldLoc = ReadSourceLocation();
- Designators.push_back(Designator(Name, DotLoc, FieldLoc));
- break;
- }
-
- case DESIG_ARRAY: {
- unsigned Index = Record.readInt();
- SourceLocation LBracketLoc = ReadSourceLocation();
- SourceLocation RBracketLoc = ReadSourceLocation();
- Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
- break;
- }
-
- case DESIG_ARRAY_RANGE: {
- unsigned Index = Record.readInt();
- SourceLocation LBracketLoc = ReadSourceLocation();
- SourceLocation EllipsisLoc = ReadSourceLocation();
- SourceLocation RBracketLoc = ReadSourceLocation();
- Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
- RBracketLoc));
- break;
- }
- }
- }
- E->setDesignators(Record.getContext(),
- Designators.data(), Designators.size());
-}
-
-void ASTStmtReader::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
- VisitExpr(E);
- E->setBase(Record.readSubExpr());
- E->setUpdater(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitNoInitExpr(NoInitExpr *E) {
- VisitExpr(E);
-}
-
-void ASTStmtReader::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
- VisitExpr(E);
- E->SubExprs[0] = Record.readSubExpr();
- E->SubExprs[1] = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
- VisitExpr(E);
-}
-
-void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
- VisitExpr(E);
-}
-
-void ASTStmtReader::VisitVAArgExpr(VAArgExpr *E) {
- VisitExpr(E);
- E->setSubExpr(Record.readSubExpr());
- E->setWrittenTypeInfo(GetTypeSourceInfo());
- E->setBuiltinLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
- E->setIsMicrosoftABI(Record.readInt());
-}
-
-void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
- VisitExpr(E);
- E->setAmpAmpLoc(ReadSourceLocation());
- E->setLabelLoc(ReadSourceLocation());
- E->setLabel(ReadDeclAs<LabelDecl>());
-}
-
-void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
- VisitExpr(E);
- E->setLParenLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
- E->setSubStmt(cast_or_null<CompoundStmt>(Record.readSubStmt()));
-}
-
-void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) {
- VisitExpr(E);
- E->setCond(Record.readSubExpr());
- E->setLHS(Record.readSubExpr());
- E->setRHS(Record.readSubExpr());
- E->setBuiltinLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
- E->setIsConditionTrue(Record.readInt());
-}
-
-void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
- VisitExpr(E);
- E->setTokenLocation(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
- VisitExpr(E);
- SmallVector<Expr *, 16> Exprs;
- unsigned NumExprs = Record.readInt();
- while (NumExprs--)
- Exprs.push_back(Record.readSubExpr());
- E->setExprs(Record.getContext(), Exprs);
- E->setBuiltinLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitConvertVectorExpr(ConvertVectorExpr *E) {
- VisitExpr(E);
- E->BuiltinLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
- E->TInfo = GetTypeSourceInfo();
- E->SrcExpr = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitBlockExpr(BlockExpr *E) {
- VisitExpr(E);
- E->setBlockDecl(ReadDeclAs<BlockDecl>());
-}
-
-void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
- VisitExpr(E);
- E->NumAssocs = Record.readInt();
- E->AssocTypes = new (Record.getContext()) TypeSourceInfo*[E->NumAssocs];
- E->SubExprs =
- new(Record.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
-
- E->SubExprs[GenericSelectionExpr::CONTROLLING] = Record.readSubExpr();
- for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
- E->AssocTypes[I] = GetTypeSourceInfo();
- E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Record.readSubExpr();
- }
- E->ResultIndex = Record.readInt();
-
- E->GenericLoc = ReadSourceLocation();
- E->DefaultLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
- VisitExpr(E);
- unsigned numSemanticExprs = Record.readInt();
- assert(numSemanticExprs + 1 == E->PseudoObjectExprBits.NumSubExprs);
- E->PseudoObjectExprBits.ResultIndex = Record.readInt();
-
- // Read the syntactic expression.
- E->getSubExprsBuffer()[0] = Record.readSubExpr();
-
- // Read all the semantic expressions.
- for (unsigned i = 0; i != numSemanticExprs; ++i) {
- Expr *subExpr = Record.readSubExpr();
- E->getSubExprsBuffer()[i+1] = subExpr;
- }
-}
-
-void ASTStmtReader::VisitAtomicExpr(AtomicExpr *E) {
- VisitExpr(E);
- E->Op = AtomicExpr::AtomicOp(Record.readInt());
- E->NumSubExprs = AtomicExpr::getNumSubExprs(E->Op);
- for (unsigned I = 0; I != E->NumSubExprs; ++I)
- E->SubExprs[I] = Record.readSubExpr();
- E->BuiltinLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
-}
-
-//===----------------------------------------------------------------------===//
-// Objective-C Expressions and Statements
-
-void ASTStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) {
- VisitExpr(E);
- E->setString(cast<StringLiteral>(Record.readSubStmt()));
- E->setAtLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
- VisitExpr(E);
- // could be one of several IntegerLiteral, FloatLiteral, etc.
- E->SubExpr = Record.readSubStmt();
- E->BoxingMethod = ReadDeclAs<ObjCMethodDecl>();
- E->Range = ReadSourceRange();
-}
-
-void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
- VisitExpr(E);
- unsigned NumElements = Record.readInt();
- assert(NumElements == E->getNumElements() && "Wrong number of elements");
- Expr **Elements = E->getElements();
- for (unsigned I = 0, N = NumElements; I != N; ++I)
- Elements[I] = Record.readSubExpr();
- E->ArrayWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>();
- E->Range = ReadSourceRange();
-}
-
-void ASTStmtReader::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
- VisitExpr(E);
- unsigned NumElements = Record.readInt();
- assert(NumElements == E->getNumElements() && "Wrong number of elements");
- bool HasPackExpansions = Record.readInt();
- assert(HasPackExpansions == E->HasPackExpansions &&"Pack expansion mismatch");
- auto *KeyValues =
- E->getTrailingObjects<ObjCDictionaryLiteral::KeyValuePair>();
- auto *Expansions =
- E->getTrailingObjects<ObjCDictionaryLiteral::ExpansionData>();
- for (unsigned I = 0; I != NumElements; ++I) {
- KeyValues[I].Key = Record.readSubExpr();
- KeyValues[I].Value = Record.readSubExpr();
- if (HasPackExpansions) {
- Expansions[I].EllipsisLoc = ReadSourceLocation();
- Expansions[I].NumExpansionsPlusOne = Record.readInt();
- }
- }
- E->DictWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>();
- E->Range = ReadSourceRange();
-}
-
-void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
- VisitExpr(E);
- E->setEncodedTypeSourceInfo(GetTypeSourceInfo());
- E->setAtLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
- VisitExpr(E);
- E->setSelector(Record.readSelector());
- E->setAtLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
- VisitExpr(E);
- E->setProtocol(ReadDeclAs<ObjCProtocolDecl>());
- E->setAtLoc(ReadSourceLocation());
- E->ProtoLoc = ReadSourceLocation();
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
- VisitExpr(E);
- E->setDecl(ReadDeclAs<ObjCIvarDecl>());
- E->setLocation(ReadSourceLocation());
- E->setOpLoc(ReadSourceLocation());
- E->setBase(Record.readSubExpr());
- E->setIsArrow(Record.readInt());
- E->setIsFreeIvar(Record.readInt());
-}
-
-void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
- VisitExpr(E);
- unsigned MethodRefFlags = Record.readInt();
- bool Implicit = Record.readInt() != 0;
- if (Implicit) {
- auto *Getter = ReadDeclAs<ObjCMethodDecl>();
- auto *Setter = ReadDeclAs<ObjCMethodDecl>();
- E->setImplicitProperty(Getter, Setter, MethodRefFlags);
- } else {
- E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(), MethodRefFlags);
- }
- E->setLocation(ReadSourceLocation());
- E->setReceiverLocation(ReadSourceLocation());
- switch (Record.readInt()) {
- case 0:
- E->setBase(Record.readSubExpr());
- break;
- case 1:
- E->setSuperReceiver(Record.readType());
- break;
- case 2:
- E->setClassReceiver(ReadDeclAs<ObjCInterfaceDecl>());
- break;
- }
-}
-
-void ASTStmtReader::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
- VisitExpr(E);
- E->setRBracket(ReadSourceLocation());
- E->setBaseExpr(Record.readSubExpr());
- E->setKeyExpr(Record.readSubExpr());
- E->GetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>();
- E->SetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>();
-}
-
-void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
- VisitExpr(E);
- assert(Record.peekInt() == E->getNumArgs());
- Record.skipInts(1);
- unsigned NumStoredSelLocs = Record.readInt();
- E->SelLocsKind = Record.readInt();
- E->setDelegateInitCall(Record.readInt());
- E->IsImplicit = Record.readInt();
- auto Kind = static_cast<ObjCMessageExpr::ReceiverKind>(Record.readInt());
- switch (Kind) {
- case ObjCMessageExpr::Instance:
- E->setInstanceReceiver(Record.readSubExpr());
- break;
-
- case ObjCMessageExpr::Class:
- E->setClassReceiver(GetTypeSourceInfo());
- break;
-
- case ObjCMessageExpr::SuperClass:
- case ObjCMessageExpr::SuperInstance: {
- QualType T = Record.readType();
- SourceLocation SuperLoc = ReadSourceLocation();
- E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
- break;
- }
- }
-
- assert(Kind == E->getReceiverKind());
-
- if (Record.readInt())
- E->setMethodDecl(ReadDeclAs<ObjCMethodDecl>());
- else
- E->setSelector(Record.readSelector());
-
- E->LBracLoc = ReadSourceLocation();
- E->RBracLoc = ReadSourceLocation();
-
- for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
- E->setArg(I, Record.readSubExpr());
-
- SourceLocation *Locs = E->getStoredSelLocs();
- for (unsigned I = 0; I != NumStoredSelLocs; ++I)
- Locs[I] = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
- VisitStmt(S);
- S->setElement(Record.readSubStmt());
- S->setCollection(Record.readSubExpr());
- S->setBody(Record.readSubStmt());
- S->setForLoc(ReadSourceLocation());
- S->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
- VisitStmt(S);
- S->setCatchBody(Record.readSubStmt());
- S->setCatchParamDecl(ReadDeclAs<VarDecl>());
- S->setAtCatchLoc(ReadSourceLocation());
- S->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
- VisitStmt(S);
- S->setFinallyBody(Record.readSubStmt());
- S->setAtFinallyLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
- VisitStmt(S);
- S->setSubStmt(Record.readSubStmt());
- S->setAtLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
- VisitStmt(S);
- assert(Record.peekInt() == S->getNumCatchStmts());
- Record.skipInts(1);
- bool HasFinally = Record.readInt();
- S->setTryBody(Record.readSubStmt());
- for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
- S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(Record.readSubStmt()));
-
- if (HasFinally)
- S->setFinallyStmt(Record.readSubStmt());
- S->setAtTryLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
- VisitStmt(S);
- S->setSynchExpr(Record.readSubStmt());
- S->setSynchBody(Record.readSubStmt());
- S->setAtSynchronizedLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
- VisitStmt(S);
- S->setThrowExpr(Record.readSubStmt());
- S->setThrowLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
- VisitExpr(E);
- E->setValue(Record.readInt());
- E->setLocation(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
- VisitExpr(E);
- SourceRange R = Record.readSourceRange();
- E->AtLoc = R.getBegin();
- E->RParen = R.getEnd();
- E->VersionToCheck = Record.readVersionTuple();
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Expressions and Statements
-//===----------------------------------------------------------------------===//
-
-void ASTStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) {
- VisitStmt(S);
- S->CatchLoc = ReadSourceLocation();
- S->ExceptionDecl = ReadDeclAs<VarDecl>();
- S->HandlerBlock = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitCXXTryStmt(CXXTryStmt *S) {
- VisitStmt(S);
- assert(Record.peekInt() == S->getNumHandlers() && "NumStmtFields is wrong ?");
- Record.skipInts(1);
- S->TryLoc = ReadSourceLocation();
- S->getStmts()[0] = Record.readSubStmt();
- for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
- S->getStmts()[i + 1] = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
- VisitStmt(S);
- S->ForLoc = ReadSourceLocation();
- S->CoawaitLoc = ReadSourceLocation();
- S->ColonLoc = ReadSourceLocation();
- S->RParenLoc = ReadSourceLocation();
- S->setInit(Record.readSubStmt());
- S->setRangeStmt(Record.readSubStmt());
- S->setBeginStmt(Record.readSubStmt());
- S->setEndStmt(Record.readSubStmt());
- S->setCond(Record.readSubExpr());
- S->setInc(Record.readSubExpr());
- S->setLoopVarStmt(Record.readSubStmt());
- S->setBody(Record.readSubStmt());
-}
-
-void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
- VisitStmt(S);
- S->KeywordLoc = ReadSourceLocation();
- S->IsIfExists = Record.readInt();
- S->QualifierLoc = Record.readNestedNameSpecifierLoc();
- ReadDeclarationNameInfo(S->NameInfo);
- S->SubStmt = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
- VisitCallExpr(E);
- E->CXXOperatorCallExprBits.OperatorKind = Record.readInt();
- E->CXXOperatorCallExprBits.FPFeatures = Record.readInt();
- E->Range = Record.readSourceRange();
-}
-
-void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
- VisitExpr(E);
-
- unsigned NumArgs = Record.readInt();
- assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
-
- E->CXXConstructExprBits.Elidable = Record.readInt();
- E->CXXConstructExprBits.HadMultipleCandidates = Record.readInt();
- E->CXXConstructExprBits.ListInitialization = Record.readInt();
- E->CXXConstructExprBits.StdInitListInitialization = Record.readInt();
- E->CXXConstructExprBits.ZeroInitialization = Record.readInt();
- E->CXXConstructExprBits.ConstructionKind = Record.readInt();
- E->CXXConstructExprBits.Loc = ReadSourceLocation();
- E->Constructor = ReadDeclAs<CXXConstructorDecl>();
- E->ParenOrBraceRange = ReadSourceRange();
-
- for (unsigned I = 0; I != NumArgs; ++I)
- E->setArg(I, Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
- VisitExpr(E);
- E->Constructor = ReadDeclAs<CXXConstructorDecl>();
- E->Loc = ReadSourceLocation();
- E->ConstructsVirtualBase = Record.readInt();
- E->InheritedFromVirtualBase = Record.readInt();
-}
-
-void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
- VisitCXXConstructExpr(E);
- E->TSI = GetTypeSourceInfo();
-}
-
-void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
- VisitExpr(E);
- unsigned NumCaptures = Record.readInt();
- assert(NumCaptures == E->NumCaptures);(void)NumCaptures;
- E->IntroducerRange = ReadSourceRange();
- E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record.readInt());
- E->CaptureDefaultLoc = ReadSourceLocation();
- E->ExplicitParams = Record.readInt();
- E->ExplicitResultType = Record.readInt();
- E->ClosingBrace = ReadSourceLocation();
-
- // Read capture initializers.
- for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
- CEnd = E->capture_init_end();
- C != CEnd; ++C)
- *C = Record.readSubExpr();
-}
-
-void
-ASTStmtReader::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
- VisitExpr(E);
- E->SubExpr = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
- VisitExplicitCastExpr(E);
- SourceRange R = ReadSourceRange();
- E->Loc = R.getBegin();
- E->RParenLoc = R.getEnd();
- R = ReadSourceRange();
- E->AngleBrackets = R;
-}
-
-void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
- return VisitCXXNamedCastExpr(E);
-}
-
-void ASTStmtReader::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
- return VisitCXXNamedCastExpr(E);
-}
-
-void ASTStmtReader::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
- return VisitCXXNamedCastExpr(E);
-}
-
-void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
- return VisitCXXNamedCastExpr(E);
-}
-
-void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
- VisitExplicitCastExpr(E);
- E->setLParenLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
- VisitCallExpr(E);
- E->UDSuffixLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
- VisitExpr(E);
- E->setValue(Record.readInt());
- E->setLocation(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
- VisitExpr(E);
- E->setLocation(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
- VisitExpr(E);
- E->setSourceRange(ReadSourceRange());
- if (E->isTypeOperand()) { // typeid(int)
- E->setTypeOperandSourceInfo(
- GetTypeSourceInfo());
- return;
- }
-
- // typeid(42+2)
- E->setExprOperand(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
- VisitExpr(E);
- E->setLocation(ReadSourceLocation());
- E->setImplicit(Record.readInt());
-}
-
-void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
- VisitExpr(E);
- E->CXXThrowExprBits.ThrowLoc = ReadSourceLocation();
- E->Operand = Record.readSubExpr();
- E->CXXThrowExprBits.IsThrownVariableInScope = Record.readInt();
-}
-
-void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
- VisitExpr(E);
- E->Param = ReadDeclAs<ParmVarDecl>();
- E->CXXDefaultArgExprBits.Loc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
- VisitExpr(E);
- E->Field = ReadDeclAs<FieldDecl>();
- E->CXXDefaultInitExprBits.Loc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- VisitExpr(E);
- E->setTemporary(Record.readCXXTemporary());
- E->setSubExpr(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
- VisitExpr(E);
- E->TypeInfo = GetTypeSourceInfo();
- E->CXXScalarValueInitExprBits.RParenLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
- VisitExpr(E);
-
- bool IsArray = Record.readInt();
- bool HasInit = Record.readInt();
- unsigned NumPlacementArgs = Record.readInt();
- bool IsParenTypeId = Record.readInt();
-
- E->CXXNewExprBits.IsGlobalNew = Record.readInt();
- E->CXXNewExprBits.ShouldPassAlignment = Record.readInt();
- E->CXXNewExprBits.UsualArrayDeleteWantsSize = Record.readInt();
- E->CXXNewExprBits.StoredInitializationStyle = Record.readInt();
-
- assert((IsArray == E->isArray()) && "Wrong IsArray!");
- assert((HasInit == E->hasInitializer()) && "Wrong HasInit!");
- assert((NumPlacementArgs == E->getNumPlacementArgs()) &&
- "Wrong NumPlacementArgs!");
- assert((IsParenTypeId == E->isParenTypeId()) && "Wrong IsParenTypeId!");
- (void)IsArray;
- (void)HasInit;
- (void)NumPlacementArgs;
-
- E->setOperatorNew(ReadDeclAs<FunctionDecl>());
- E->setOperatorDelete(ReadDeclAs<FunctionDecl>());
- E->AllocatedTypeInfo = GetTypeSourceInfo();
- if (IsParenTypeId)
- E->getTrailingObjects<SourceRange>()[0] = ReadSourceRange();
- E->Range = ReadSourceRange();
- E->DirectInitRange = ReadSourceRange();
-
- // Install all the subexpressions.
- for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),
- N = E->raw_arg_end();
- I != N; ++I)
- *I = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
- VisitExpr(E);
- E->CXXDeleteExprBits.GlobalDelete = Record.readInt();
- E->CXXDeleteExprBits.ArrayForm = Record.readInt();
- E->CXXDeleteExprBits.ArrayFormAsWritten = Record.readInt();
- E->CXXDeleteExprBits.UsualArrayDeleteWantsSize = Record.readInt();
- E->OperatorDelete = ReadDeclAs<FunctionDecl>();
- E->Argument = Record.readSubExpr();
- E->CXXDeleteExprBits.Loc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
- VisitExpr(E);
-
- E->Base = Record.readSubExpr();
- E->IsArrow = Record.readInt();
- E->OperatorLoc = ReadSourceLocation();
- E->QualifierLoc = Record.readNestedNameSpecifierLoc();
- E->ScopeType = GetTypeSourceInfo();
- E->ColonColonLoc = ReadSourceLocation();
- E->TildeLoc = ReadSourceLocation();
-
- IdentifierInfo *II = Record.getIdentifierInfo();
- if (II)
- E->setDestroyedType(II, ReadSourceLocation());
- else
- E->setDestroyedType(GetTypeSourceInfo());
-}
-
-void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
- VisitExpr(E);
-
- unsigned NumObjects = Record.readInt();
- assert(NumObjects == E->getNumObjects());
- for (unsigned i = 0; i != NumObjects; ++i)
- E->getTrailingObjects<BlockDecl *>()[i] =
- ReadDeclAs<BlockDecl>();
-
- E->ExprWithCleanupsBits.CleanupsHaveSideEffects = Record.readInt();
- E->SubExpr = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
- CXXDependentScopeMemberExpr *E) {
- VisitExpr(E);
-
- bool HasTemplateKWAndArgsInfo = Record.readInt();
- unsigned NumTemplateArgs = Record.readInt();
- bool HasFirstQualifierFoundInScope = Record.readInt();
-
- assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) &&
- "Wrong HasTemplateKWAndArgsInfo!");
- assert(
- (HasFirstQualifierFoundInScope == E->hasFirstQualifierFoundInScope()) &&
- "Wrong HasFirstQualifierFoundInScope!");
-
- if (HasTemplateKWAndArgsInfo)
- ReadTemplateKWAndArgsInfo(
- *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
- E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs);
-
- assert((NumTemplateArgs == E->getNumTemplateArgs()) &&
- "Wrong NumTemplateArgs!");
-
- E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt();
- E->CXXDependentScopeMemberExprBits.OperatorLoc = ReadSourceLocation();
- E->BaseType = Record.readType();
- E->QualifierLoc = Record.readNestedNameSpecifierLoc();
- E->Base = Record.readSubExpr();
-
- if (HasFirstQualifierFoundInScope)
- *E->getTrailingObjects<NamedDecl *>() = ReadDeclAs<NamedDecl>();
-
- ReadDeclarationNameInfo(E->MemberNameInfo);
-}
-
-void
-ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
- VisitExpr(E);
-
- if (Record.readInt()) // HasTemplateKWAndArgsInfo
- ReadTemplateKWAndArgsInfo(
- *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
- E->getTrailingObjects<TemplateArgumentLoc>(),
- /*NumTemplateArgs=*/Record.readInt());
-
- E->QualifierLoc = Record.readNestedNameSpecifierLoc();
- ReadDeclarationNameInfo(E->NameInfo);
-}
-
-void
-ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
- VisitExpr(E);
- assert(Record.peekInt() == E->arg_size() &&
- "Read wrong record during creation ?");
- Record.skipInts(1);
- for (unsigned I = 0, N = E->arg_size(); I != N; ++I)
- E->setArg(I, Record.readSubExpr());
- E->TSI = GetTypeSourceInfo();
- E->setLParenLoc(ReadSourceLocation());
- E->setRParenLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
- VisitExpr(E);
-
- unsigned NumResults = Record.readInt();
- bool HasTemplateKWAndArgsInfo = Record.readInt();
- assert((E->getNumDecls() == NumResults) && "Wrong NumResults!");
- assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) &&
- "Wrong HasTemplateKWAndArgsInfo!");
-
- if (HasTemplateKWAndArgsInfo) {
- unsigned NumTemplateArgs = Record.readInt();
- ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
- E->getTrailingTemplateArgumentLoc(),
- NumTemplateArgs);
- assert((E->getNumTemplateArgs() == NumTemplateArgs) &&
- "Wrong NumTemplateArgs!");
- }
-
- UnresolvedSet<8> Decls;
- for (unsigned I = 0; I != NumResults; ++I) {
- auto *D = ReadDeclAs<NamedDecl>();
- auto AS = (AccessSpecifier)Record.readInt();
- Decls.addDecl(D, AS);
- }
-
- DeclAccessPair *Results = E->getTrailingResults();
- UnresolvedSetIterator Iter = Decls.begin();
- for (unsigned I = 0; I != NumResults; ++I) {
- Results[I] = (Iter + I).getPair();
- }
-
- ReadDeclarationNameInfo(E->NameInfo);
- E->QualifierLoc = Record.readNestedNameSpecifierLoc();
-}
-
-void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
- VisitOverloadExpr(E);
- E->UnresolvedMemberExprBits.IsArrow = Record.readInt();
- E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt();
- E->Base = Record.readSubExpr();
- E->BaseType = Record.readType();
- E->OperatorLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
- VisitOverloadExpr(E);
- E->UnresolvedLookupExprBits.RequiresADL = Record.readInt();
- E->UnresolvedLookupExprBits.Overloaded = Record.readInt();
- E->NamingClass = ReadDeclAs<CXXRecordDecl>();
-}
-
-void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
- VisitExpr(E);
- E->TypeTraitExprBits.NumArgs = Record.readInt();
- E->TypeTraitExprBits.Kind = Record.readInt();
- E->TypeTraitExprBits.Value = Record.readInt();
- SourceRange Range = ReadSourceRange();
- E->Loc = Range.getBegin();
- E->RParenLoc = Range.getEnd();
-
- auto **Args = E->getTrailingObjects<TypeSourceInfo *>();
- for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
- Args[I] = GetTypeSourceInfo();
-}
-
-void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
- VisitExpr(E);
- E->ATT = (ArrayTypeTrait)Record.readInt();
- E->Value = (unsigned int)Record.readInt();
- SourceRange Range = ReadSourceRange();
- E->Loc = Range.getBegin();
- E->RParen = Range.getEnd();
- E->QueriedType = GetTypeSourceInfo();
- E->Dimension = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
- VisitExpr(E);
- E->ET = (ExpressionTrait)Record.readInt();
- E->Value = (bool)Record.readInt();
- SourceRange Range = ReadSourceRange();
- E->QueriedExpression = Record.readSubExpr();
- E->Loc = Range.getBegin();
- E->RParen = Range.getEnd();
-}
-
-void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
- VisitExpr(E);
- E->CXXNoexceptExprBits.Value = Record.readInt();
- E->Range = ReadSourceRange();
- E->Operand = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitPackExpansionExpr(PackExpansionExpr *E) {
- VisitExpr(E);
- E->EllipsisLoc = ReadSourceLocation();
- E->NumExpansions = Record.readInt();
- E->Pattern = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
- VisitExpr(E);
- unsigned NumPartialArgs = Record.readInt();
- E->OperatorLoc = ReadSourceLocation();
- E->PackLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
- E->Pack = Record.readDeclAs<NamedDecl>();
- if (E->isPartiallySubstituted()) {
- assert(E->Length == NumPartialArgs);
- for (auto *I = E->getTrailingObjects<TemplateArgument>(),
- *E = I + NumPartialArgs;
- I != E; ++I)
- new (I) TemplateArgument(Record.readTemplateArgument());
- } else if (!E->isValueDependent()) {
- E->Length = Record.readInt();
- }
-}
-
-void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
- SubstNonTypeTemplateParmExpr *E) {
- VisitExpr(E);
- E->Param = ReadDeclAs<NonTypeTemplateParmDecl>();
- E->SubstNonTypeTemplateParmExprBits.NameLoc = ReadSourceLocation();
- E->Replacement = Record.readSubExpr();
-}
-
-void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
- SubstNonTypeTemplateParmPackExpr *E) {
- VisitExpr(E);
- E->Param = ReadDeclAs<NonTypeTemplateParmDecl>();
- TemplateArgument ArgPack = Record.readTemplateArgument();
- if (ArgPack.getKind() != TemplateArgument::Pack)
- return;
-
- E->Arguments = ArgPack.pack_begin();
- E->NumArguments = ArgPack.pack_size();
- E->NameLoc = ReadSourceLocation();
-}
-
-void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
- VisitExpr(E);
- E->NumParameters = Record.readInt();
- E->ParamPack = ReadDeclAs<ParmVarDecl>();
- E->NameLoc = ReadSourceLocation();
- auto **Parms = E->getTrailingObjects<ParmVarDecl *>();
- for (unsigned i = 0, n = E->NumParameters; i != n; ++i)
- Parms[i] = ReadDeclAs<ParmVarDecl>();
-}
-
-void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
- VisitExpr(E);
- E->State = Record.readSubExpr();
- auto *VD = ReadDeclAs<ValueDecl>();
- unsigned ManglingNumber = Record.readInt();
- E->setExtendingDecl(VD, ManglingNumber);
-}
-
-void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
- VisitExpr(E);
- E->LParenLoc = ReadSourceLocation();
- E->EllipsisLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
- E->SubExprs[0] = Record.readSubExpr();
- E->SubExprs[1] = Record.readSubExpr();
- E->Opcode = (BinaryOperatorKind)Record.readInt();
-}
-
-void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
- VisitExpr(E);
- E->SourceExpr = Record.readSubExpr();
- E->OpaqueValueExprBits.Loc = ReadSourceLocation();
- E->setIsUnique(Record.readInt());
-}
-
-void ASTStmtReader::VisitTypoExpr(TypoExpr *E) {
- llvm_unreachable("Cannot read TypoExpr nodes");
-}
-
-//===----------------------------------------------------------------------===//
-// Microsoft Expressions and Statements
-//===----------------------------------------------------------------------===//
-void ASTStmtReader::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
- VisitExpr(E);
- E->IsArrow = (Record.readInt() != 0);
- E->BaseExpr = Record.readSubExpr();
- E->QualifierLoc = Record.readNestedNameSpecifierLoc();
- E->MemberLoc = ReadSourceLocation();
- E->TheDecl = ReadDeclAs<MSPropertyDecl>();
-}
-
-void ASTStmtReader::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
- VisitExpr(E);
- E->setBase(Record.readSubExpr());
- E->setIdx(Record.readSubExpr());
- E->setRBracketLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
- VisitExpr(E);
- E->setSourceRange(ReadSourceRange());
- std::string UuidStr = ReadString();
- E->setUuidStr(StringRef(UuidStr).copy(Record.getContext()));
- if (E->isTypeOperand()) { // __uuidof(ComType)
- E->setTypeOperandSourceInfo(
- GetTypeSourceInfo());
- return;
- }
-
- // __uuidof(expr)
- E->setExprOperand(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
- VisitStmt(S);
- S->setLeaveLoc(ReadSourceLocation());
-}
-
-void ASTStmtReader::VisitSEHExceptStmt(SEHExceptStmt *S) {
- VisitStmt(S);
- S->Loc = ReadSourceLocation();
- S->Children[SEHExceptStmt::FILTER_EXPR] = Record.readSubStmt();
- S->Children[SEHExceptStmt::BLOCK] = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
- VisitStmt(S);
- S->Loc = ReadSourceLocation();
- S->Block = Record.readSubStmt();
-}
-
-void ASTStmtReader::VisitSEHTryStmt(SEHTryStmt *S) {
- VisitStmt(S);
- S->IsCXXTry = Record.readInt();
- S->TryLoc = ReadSourceLocation();
- S->Children[SEHTryStmt::TRY] = Record.readSubStmt();
- S->Children[SEHTryStmt::HANDLER] = Record.readSubStmt();
-}
-
-//===----------------------------------------------------------------------===//
-// CUDA Expressions and Statements
-//===----------------------------------------------------------------------===//
-
-void ASTStmtReader::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
- VisitCallExpr(E);
- E->setConfig(cast<CallExpr>(Record.readSubExpr()));
-}
-
-//===----------------------------------------------------------------------===//
-// OpenCL Expressions and Statements.
-//===----------------------------------------------------------------------===//
-void ASTStmtReader::VisitAsTypeExpr(AsTypeExpr *E) {
- VisitExpr(E);
- E->BuiltinLoc = ReadSourceLocation();
- E->RParenLoc = ReadSourceLocation();
- E->SrcExpr = Record.readSubExpr();
-}
-
-//===----------------------------------------------------------------------===//
-// OpenMP Directives.
-//===----------------------------------------------------------------------===//
-
-void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
- E->setLocStart(ReadSourceLocation());
- E->setLocEnd(ReadSourceLocation());
- OMPClauseReader ClauseReader(Record);
- SmallVector<OMPClause *, 5> Clauses;
- for (unsigned i = 0; i < E->getNumClauses(); ++i)
- Clauses.push_back(ClauseReader.readClause());
- E->setClauses(Clauses);
- if (E->hasAssociatedStmt())
- E->setAssociatedStmt(Record.readSubStmt());
-}
-
-void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) {
- VisitStmt(D);
- // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
- Record.skipInts(2);
- VisitOMPExecutableDirective(D);
- D->setIterationVariable(Record.readSubExpr());
- D->setLastIteration(Record.readSubExpr());
- D->setCalcLastIteration(Record.readSubExpr());
- D->setPreCond(Record.readSubExpr());
- D->setCond(Record.readSubExpr());
- D->setInit(Record.readSubExpr());
- D->setInc(Record.readSubExpr());
- D->setPreInits(Record.readSubStmt());
- if (isOpenMPWorksharingDirective(D->getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(D->getDirectiveKind()) ||
- isOpenMPDistributeDirective(D->getDirectiveKind())) {
- D->setIsLastIterVariable(Record.readSubExpr());
- D->setLowerBoundVariable(Record.readSubExpr());
- D->setUpperBoundVariable(Record.readSubExpr());
- D->setStrideVariable(Record.readSubExpr());
- D->setEnsureUpperBound(Record.readSubExpr());
- D->setNextLowerBound(Record.readSubExpr());
- D->setNextUpperBound(Record.readSubExpr());
- D->setNumIterations(Record.readSubExpr());
- }
- if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) {
- D->setPrevLowerBoundVariable(Record.readSubExpr());
- D->setPrevUpperBoundVariable(Record.readSubExpr());
- D->setDistInc(Record.readSubExpr());
- D->setPrevEnsureUpperBound(Record.readSubExpr());
- D->setCombinedLowerBoundVariable(Record.readSubExpr());
- D->setCombinedUpperBoundVariable(Record.readSubExpr());
- D->setCombinedEnsureUpperBound(Record.readSubExpr());
- D->setCombinedInit(Record.readSubExpr());
- D->setCombinedCond(Record.readSubExpr());
- D->setCombinedNextLowerBound(Record.readSubExpr());
- D->setCombinedNextUpperBound(Record.readSubExpr());
- D->setCombinedDistCond(Record.readSubExpr());
- D->setCombinedParForInDistCond(Record.readSubExpr());
- }
- SmallVector<Expr *, 4> Sub;
- unsigned CollapsedNum = D->getCollapsedNumber();
- Sub.reserve(CollapsedNum);
- for (unsigned i = 0; i < CollapsedNum; ++i)
- Sub.push_back(Record.readSubExpr());
- D->setCounters(Sub);
- Sub.clear();
- for (unsigned i = 0; i < CollapsedNum; ++i)
- Sub.push_back(Record.readSubExpr());
- D->setPrivateCounters(Sub);
- Sub.clear();
- for (unsigned i = 0; i < CollapsedNum; ++i)
- Sub.push_back(Record.readSubExpr());
- D->setInits(Sub);
- Sub.clear();
- for (unsigned i = 0; i < CollapsedNum; ++i)
- Sub.push_back(Record.readSubExpr());
- D->setUpdates(Sub);
- Sub.clear();
- for (unsigned i = 0; i < CollapsedNum; ++i)
- Sub.push_back(Record.readSubExpr());
- D->setFinals(Sub);
-}
-
-void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
- VisitOMPLoopDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPMasterDirective(OMPMasterDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- ReadDeclarationNameInfo(D->DirName);
-}
-
-void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPParallelForSimdDirective(
- OMPParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPParallelSectionsDirective(
- OMPParallelSectionsDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setReductionRef(Record.readSubExpr());
-}
-
-void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setX(Record.readSubExpr());
- D->setV(Record.readSubExpr());
- D->setExpr(Record.readSubExpr());
- D->setUpdateExpr(Record.readSubExpr());
- D->IsXLHSInRHSPart = Record.readInt() != 0;
- D->IsPostfixUpdate = Record.readInt() != 0;
-}
-
-void ASTStmtReader::VisitOMPTargetDirective(OMPTargetDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
- VisitStmt(D);
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetEnterDataDirective(
- OMPTargetEnterDataDirective *D) {
- VisitStmt(D);
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetExitDataDirective(
- OMPTargetExitDataDirective *D) {
- VisitStmt(D);
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetParallelDirective(
- OMPTargetParallelDirective *D) {
- VisitStmt(D);
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetParallelForDirective(
- OMPTargetParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPCancellationPointDirective(
- OMPCancellationPointDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record.readInt()));
-}
-
-void ASTStmtReader::VisitOMPCancelDirective(OMPCancelDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
- D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record.readInt()));
-}
-
-void ASTStmtReader::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
- VisitStmt(D);
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPDistributeParallelForDirective(
- OMPDistributeParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPDistributeParallelForSimdDirective(
- OMPDistributeParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPDistributeSimdDirective(
- OMPDistributeSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetParallelForSimdDirective(
- OMPTargetParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTeamsDistributeDirective(
- OMPTeamsDistributeDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTeamsDistributeSimdDirective(
- OMPTeamsDistributeSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTeamsDistributeParallelForSimdDirective(
- OMPTeamsDistributeParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTeamsDistributeParallelForDirective(
- OMPTeamsDistributeParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
- VisitStmt(D);
- // The NumClauses field was read in ReadStmtFromStream.
- Record.skipInts(1);
- VisitOMPExecutableDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetTeamsDistributeDirective(
- OMPTargetTeamsDistributeDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForDirective(
- OMPTargetTeamsDistributeParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- D->setHasCancel(Record.readInt());
-}
-
-void ASTStmtReader::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
- OMPTargetTeamsDistributeParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-void ASTStmtReader::VisitOMPTargetTeamsDistributeSimdDirective(
- OMPTargetTeamsDistributeSimdDirective *D) {
- VisitOMPLoopDirective(D);
-}
-
-//===----------------------------------------------------------------------===//
-// ASTReader Implementation
-//===----------------------------------------------------------------------===//
-
-Stmt *ASTReader::ReadStmt(ModuleFile &F) {
- switch (ReadingKind) {
- case Read_None:
- llvm_unreachable("should not call this when not reading anything");
- case Read_Decl:
- case Read_Type:
- return ReadStmtFromStream(F);
- case Read_Stmt:
- return ReadSubStmt();
- }
-
- llvm_unreachable("ReadingKind not set ?");
-}
-
-Expr *ASTReader::ReadExpr(ModuleFile &F) {
- return cast_or_null<Expr>(ReadStmt(F));
-}
-
-Expr *ASTReader::ReadSubExpr() {
- return cast_or_null<Expr>(ReadSubStmt());
-}
-
-// Within the bitstream, expressions are stored in Reverse Polish
-// Notation, with each of the subexpressions preceding the
-// expression they are stored in. Subexpressions are stored from last to first.
-// To evaluate expressions, we continue reading expressions and placing them on
-// the stack, with expressions having operands removing those operands from the
-// stack. Evaluation terminates when we see a STMT_STOP record, and
-// the single remaining expression on the stack is our result.
-Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
- ReadingKindTracker ReadingKind(Read_Stmt, *this);
- llvm::BitstreamCursor &Cursor = F.DeclsCursor;
-
- // Map of offset to previously deserialized stmt. The offset points
- // just after the stmt record.
- llvm::DenseMap<uint64_t, Stmt *> StmtEntries;
-
-#ifndef NDEBUG
- unsigned PrevNumStmts = StmtStack.size();
-#endif
-
- ASTRecordReader Record(*this, F);
- ASTStmtReader Reader(Record, Cursor);
- Stmt::EmptyShell Empty;
-
- while (true) {
- llvm::BitstreamEntry Entry = Cursor.advanceSkippingSubblocks();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock: // Handled for us already.
- case llvm::BitstreamEntry::Error:
- Error("malformed block record in AST file");
- return nullptr;
- case llvm::BitstreamEntry::EndBlock:
- goto Done;
- case llvm::BitstreamEntry::Record:
- // The interesting case.
- break;
- }
-
- ASTContext &Context = getContext();
- Stmt *S = nullptr;
- bool Finished = false;
- bool IsStmtReference = false;
- switch ((StmtCode)Record.readRecord(Cursor, Entry.ID)) {
- case STMT_STOP:
- Finished = true;
- break;
-
- case STMT_REF_PTR:
- IsStmtReference = true;
- assert(StmtEntries.find(Record[0]) != StmtEntries.end() &&
- "No stmt was recorded for this offset reference!");
- S = StmtEntries[Record.readInt()];
- break;
-
- case STMT_NULL_PTR:
- S = nullptr;
- break;
-
- case STMT_NULL:
- S = new (Context) NullStmt(Empty);
- break;
-
- case STMT_COMPOUND:
- S = CompoundStmt::CreateEmpty(
- Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields]);
- break;
-
- case STMT_CASE:
- S = CaseStmt::CreateEmpty(
- Context,
- /*CaseStmtIsGNURange*/ Record[ASTStmtReader::NumStmtFields + 3]);
- break;
-
- case STMT_DEFAULT:
- S = new (Context) DefaultStmt(Empty);
- break;
-
- case STMT_LABEL:
- S = new (Context) LabelStmt(Empty);
- break;
-
- case STMT_ATTRIBUTED:
- S = AttributedStmt::CreateEmpty(
- Context,
- /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]);
- break;
-
- case STMT_IF:
- S = IfStmt::CreateEmpty(
- Context,
- /* HasElse=*/Record[ASTStmtReader::NumStmtFields + 1],
- /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 2],
- /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 3]);
- break;
-
- case STMT_SWITCH:
- S = SwitchStmt::CreateEmpty(
- Context,
- /* HasInit=*/Record[ASTStmtReader::NumStmtFields],
- /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1]);
- break;
-
- case STMT_WHILE:
- S = WhileStmt::CreateEmpty(
- Context,
- /* HasVar=*/Record[ASTStmtReader::NumStmtFields]);
- break;
-
- case STMT_DO:
- S = new (Context) DoStmt(Empty);
- break;
-
- case STMT_FOR:
- S = new (Context) ForStmt(Empty);
- break;
-
- case STMT_GOTO:
- S = new (Context) GotoStmt(Empty);
- break;
-
- case STMT_INDIRECT_GOTO:
- S = new (Context) IndirectGotoStmt(Empty);
- break;
-
- case STMT_CONTINUE:
- S = new (Context) ContinueStmt(Empty);
- break;
-
- case STMT_BREAK:
- S = new (Context) BreakStmt(Empty);
- break;
-
- case STMT_RETURN:
- S = ReturnStmt::CreateEmpty(
- Context, /* HasNRVOCandidate=*/Record[ASTStmtReader::NumStmtFields]);
- break;
-
- case STMT_DECL:
- S = new (Context) DeclStmt(Empty);
- break;
-
- case STMT_GCCASM:
- S = new (Context) GCCAsmStmt(Empty);
- break;
-
- case STMT_MSASM:
- S = new (Context) MSAsmStmt(Empty);
- break;
-
- case STMT_CAPTURED:
- S = CapturedStmt::CreateDeserialized(
- Context, Record[ASTStmtReader::NumStmtFields]);
- break;
-
- case EXPR_CONSTANT:
- S = new (Context) ConstantExpr(Empty);
- break;
-
- case EXPR_PREDEFINED:
- S = PredefinedExpr::CreateEmpty(
- Context,
- /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_DECL_REF:
- S = DeclRefExpr::CreateEmpty(
- Context,
- /*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
- /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1],
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ?
- Record[ASTStmtReader::NumExprFields + 5] : 0);
- break;
-
- case EXPR_INTEGER_LITERAL:
- S = IntegerLiteral::Create(Context, Empty);
- break;
-
- case EXPR_FLOATING_LITERAL:
- S = FloatingLiteral::Create(Context, Empty);
- break;
-
- case EXPR_IMAGINARY_LITERAL:
- S = new (Context) ImaginaryLiteral(Empty);
- break;
-
- case EXPR_STRING_LITERAL:
- S = StringLiteral::CreateEmpty(
- Context,
- /* NumConcatenated=*/Record[ASTStmtReader::NumExprFields],
- /* Length=*/Record[ASTStmtReader::NumExprFields + 1],
- /* CharByteWidth=*/Record[ASTStmtReader::NumExprFields + 2]);
- break;
-
- case EXPR_CHARACTER_LITERAL:
- S = new (Context) CharacterLiteral(Empty);
- break;
-
- case EXPR_PAREN:
- S = new (Context) ParenExpr(Empty);
- break;
-
- case EXPR_PAREN_LIST:
- S = ParenListExpr::CreateEmpty(
- Context,
- /* NumExprs=*/Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_UNARY_OPERATOR:
- S = new (Context) UnaryOperator(Empty);
- break;
-
- case EXPR_OFFSETOF:
- S = OffsetOfExpr::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields],
- Record[ASTStmtReader::NumExprFields + 1]);
- break;
-
- case EXPR_SIZEOF_ALIGN_OF:
- S = new (Context) UnaryExprOrTypeTraitExpr(Empty);
- break;
-
- case EXPR_ARRAY_SUBSCRIPT:
- S = new (Context) ArraySubscriptExpr(Empty);
- break;
-
- case EXPR_OMP_ARRAY_SECTION:
- S = new (Context) OMPArraySectionExpr(Empty);
- break;
-
- case EXPR_CALL:
- S = CallExpr::CreateEmpty(
- Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
- break;
-
- case EXPR_MEMBER: {
- // We load everything here and fully initialize it at creation.
- // That way we can use MemberExpr::Create and don't have to duplicate its
- // logic with a MemberExpr::CreateEmpty.
-
- assert(Record.getIdx() == 0);
- NestedNameSpecifierLoc QualifierLoc;
- if (Record.readInt()) { // HasQualifier.
- QualifierLoc = Record.readNestedNameSpecifierLoc();
- }
-
- SourceLocation TemplateKWLoc;
- TemplateArgumentListInfo ArgInfo;
- bool HasTemplateKWAndArgsInfo = Record.readInt();
- if (HasTemplateKWAndArgsInfo) {
- TemplateKWLoc = Record.readSourceLocation();
- unsigned NumTemplateArgs = Record.readInt();
- ArgInfo.setLAngleLoc(Record.readSourceLocation());
- ArgInfo.setRAngleLoc(Record.readSourceLocation());
- for (unsigned i = 0; i != NumTemplateArgs; ++i)
- ArgInfo.addArgument(Record.readTemplateArgumentLoc());
- }
-
- bool HadMultipleCandidates = Record.readInt();
-
- auto *FoundD = Record.readDeclAs<NamedDecl>();
- auto AS = (AccessSpecifier)Record.readInt();
- DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
-
- QualType T = Record.readType();
- auto VK = static_cast<ExprValueKind>(Record.readInt());
- auto OK = static_cast<ExprObjectKind>(Record.readInt());
- Expr *Base = ReadSubExpr();
- auto *MemberD = Record.readDeclAs<ValueDecl>();
- SourceLocation MemberLoc = Record.readSourceLocation();
- DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc);
- bool IsArrow = Record.readInt();
- SourceLocation OperatorLoc = Record.readSourceLocation();
-
- S = MemberExpr::Create(Context, Base, IsArrow, OperatorLoc, QualifierLoc,
- TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo,
- HasTemplateKWAndArgsInfo ? &ArgInfo : nullptr, T,
- VK, OK);
- Record.readDeclarationNameLoc(cast<MemberExpr>(S)->MemberDNLoc,
- MemberD->getDeclName());
- if (HadMultipleCandidates)
- cast<MemberExpr>(S)->setHadMultipleCandidates(true);
- break;
- }
-
- case EXPR_BINARY_OPERATOR:
- S = new (Context) BinaryOperator(Empty);
- break;
-
- case EXPR_COMPOUND_ASSIGN_OPERATOR:
- S = new (Context) CompoundAssignOperator(Empty);
- break;
-
- case EXPR_CONDITIONAL_OPERATOR:
- S = new (Context) ConditionalOperator(Empty);
- break;
-
- case EXPR_BINARY_CONDITIONAL_OPERATOR:
- S = new (Context) BinaryConditionalOperator(Empty);
- break;
-
- case EXPR_IMPLICIT_CAST:
- S = ImplicitCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CSTYLE_CAST:
- S = CStyleCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_COMPOUND_LITERAL:
- S = new (Context) CompoundLiteralExpr(Empty);
- break;
-
- case EXPR_EXT_VECTOR_ELEMENT:
- S = new (Context) ExtVectorElementExpr(Empty);
- break;
-
- case EXPR_INIT_LIST:
- S = new (Context) InitListExpr(Empty);
- break;
-
- case EXPR_DESIGNATED_INIT:
- S = DesignatedInitExpr::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields] - 1);
-
- break;
-
- case EXPR_DESIGNATED_INIT_UPDATE:
- S = new (Context) DesignatedInitUpdateExpr(Empty);
- break;
-
- case EXPR_IMPLICIT_VALUE_INIT:
- S = new (Context) ImplicitValueInitExpr(Empty);
- break;
-
- case EXPR_NO_INIT:
- S = new (Context) NoInitExpr(Empty);
- break;
-
- case EXPR_ARRAY_INIT_LOOP:
- S = new (Context) ArrayInitLoopExpr(Empty);
- break;
-
- case EXPR_ARRAY_INIT_INDEX:
- S = new (Context) ArrayInitIndexExpr(Empty);
- break;
-
- case EXPR_VA_ARG:
- S = new (Context) VAArgExpr(Empty);
- break;
-
- case EXPR_ADDR_LABEL:
- S = new (Context) AddrLabelExpr(Empty);
- break;
-
- case EXPR_STMT:
- S = new (Context) StmtExpr(Empty);
- break;
-
- case EXPR_CHOOSE:
- S = new (Context) ChooseExpr(Empty);
- break;
-
- case EXPR_GNU_NULL:
- S = new (Context) GNUNullExpr(Empty);
- break;
-
- case EXPR_SHUFFLE_VECTOR:
- S = new (Context) ShuffleVectorExpr(Empty);
- break;
-
- case EXPR_CONVERT_VECTOR:
- S = new (Context) ConvertVectorExpr(Empty);
- break;
-
- case EXPR_BLOCK:
- S = new (Context) BlockExpr(Empty);
- break;
-
- case EXPR_GENERIC_SELECTION:
- S = new (Context) GenericSelectionExpr(Empty);
- break;
-
- case EXPR_OBJC_STRING_LITERAL:
- S = new (Context) ObjCStringLiteral(Empty);
- break;
-
- case EXPR_OBJC_BOXED_EXPRESSION:
- S = new (Context) ObjCBoxedExpr(Empty);
- break;
-
- case EXPR_OBJC_ARRAY_LITERAL:
- S = ObjCArrayLiteral::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_OBJC_DICTIONARY_LITERAL:
- S = ObjCDictionaryLiteral::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields],
- Record[ASTStmtReader::NumExprFields + 1]);
- break;
-
- case EXPR_OBJC_ENCODE:
- S = new (Context) ObjCEncodeExpr(Empty);
- break;
-
- case EXPR_OBJC_SELECTOR_EXPR:
- S = new (Context) ObjCSelectorExpr(Empty);
- break;
-
- case EXPR_OBJC_PROTOCOL_EXPR:
- S = new (Context) ObjCProtocolExpr(Empty);
- break;
-
- case EXPR_OBJC_IVAR_REF_EXPR:
- S = new (Context) ObjCIvarRefExpr(Empty);
- break;
-
- case EXPR_OBJC_PROPERTY_REF_EXPR:
- S = new (Context) ObjCPropertyRefExpr(Empty);
- break;
-
- case EXPR_OBJC_SUBSCRIPT_REF_EXPR:
- S = new (Context) ObjCSubscriptRefExpr(Empty);
- break;
-
- case EXPR_OBJC_KVC_REF_EXPR:
- llvm_unreachable("mismatching AST file");
-
- case EXPR_OBJC_MESSAGE_EXPR:
- S = ObjCMessageExpr::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields],
- Record[ASTStmtReader::NumExprFields + 1]);
- break;
-
- case EXPR_OBJC_ISA:
- S = new (Context) ObjCIsaExpr(Empty);
- break;
-
- case EXPR_OBJC_INDIRECT_COPY_RESTORE:
- S = new (Context) ObjCIndirectCopyRestoreExpr(Empty);
- break;
-
- case EXPR_OBJC_BRIDGED_CAST:
- S = new (Context) ObjCBridgedCastExpr(Empty);
- break;
-
- case STMT_OBJC_FOR_COLLECTION:
- S = new (Context) ObjCForCollectionStmt(Empty);
- break;
-
- case STMT_OBJC_CATCH:
- S = new (Context) ObjCAtCatchStmt(Empty);
- break;
-
- case STMT_OBJC_FINALLY:
- S = new (Context) ObjCAtFinallyStmt(Empty);
- break;
-
- case STMT_OBJC_AT_TRY:
- S = ObjCAtTryStmt::CreateEmpty(Context,
- Record[ASTStmtReader::NumStmtFields],
- Record[ASTStmtReader::NumStmtFields + 1]);
- break;
-
- case STMT_OBJC_AT_SYNCHRONIZED:
- S = new (Context) ObjCAtSynchronizedStmt(Empty);
- break;
-
- case STMT_OBJC_AT_THROW:
- S = new (Context) ObjCAtThrowStmt(Empty);
- break;
-
- case STMT_OBJC_AUTORELEASE_POOL:
- S = new (Context) ObjCAutoreleasePoolStmt(Empty);
- break;
-
- case EXPR_OBJC_BOOL_LITERAL:
- S = new (Context) ObjCBoolLiteralExpr(Empty);
- break;
-
- case EXPR_OBJC_AVAILABILITY_CHECK:
- S = new (Context) ObjCAvailabilityCheckExpr(Empty);
- break;
-
- case STMT_SEH_LEAVE:
- S = new (Context) SEHLeaveStmt(Empty);
- break;
-
- case STMT_SEH_EXCEPT:
- S = new (Context) SEHExceptStmt(Empty);
- break;
-
- case STMT_SEH_FINALLY:
- S = new (Context) SEHFinallyStmt(Empty);
- break;
-
- case STMT_SEH_TRY:
- S = new (Context) SEHTryStmt(Empty);
- break;
-
- case STMT_CXX_CATCH:
- S = new (Context) CXXCatchStmt(Empty);
- break;
-
- case STMT_CXX_TRY:
- S = CXXTryStmt::Create(Context, Empty,
- /*NumHandlers=*/Record[ASTStmtReader::NumStmtFields]);
- break;
-
- case STMT_CXX_FOR_RANGE:
- S = new (Context) CXXForRangeStmt(Empty);
- break;
-
- case STMT_MS_DEPENDENT_EXISTS:
- S = new (Context) MSDependentExistsStmt(SourceLocation(), true,
- NestedNameSpecifierLoc(),
- DeclarationNameInfo(),
- nullptr);
- break;
-
- case STMT_OMP_PARALLEL_DIRECTIVE:
- S =
- OMPParallelDirective::CreateEmpty(Context,
- Record[ASTStmtReader::NumStmtFields],
- Empty);
- break;
-
- case STMT_OMP_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_FOR_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPForDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
- Empty);
- break;
- }
-
- case STMT_OMP_FOR_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPForSimdDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
- Empty);
- break;
- }
-
- case STMT_OMP_SECTIONS_DIRECTIVE:
- S = OMPSectionsDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_SECTION_DIRECTIVE:
- S = OMPSectionDirective::CreateEmpty(Context, Empty);
- break;
-
- case STMT_OMP_SINGLE_DIRECTIVE:
- S = OMPSingleDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_MASTER_DIRECTIVE:
- S = OMPMasterDirective::CreateEmpty(Context, Empty);
- break;
-
- case STMT_OMP_CRITICAL_DIRECTIVE:
- S = OMPCriticalDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_PARALLEL_FOR_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPParallelForDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPParallelForSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE:
- S = OMPParallelSectionsDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TASK_DIRECTIVE:
- S = OMPTaskDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TASKYIELD_DIRECTIVE:
- S = OMPTaskyieldDirective::CreateEmpty(Context, Empty);
- break;
-
- case STMT_OMP_BARRIER_DIRECTIVE:
- S = OMPBarrierDirective::CreateEmpty(Context, Empty);
- break;
-
- case STMT_OMP_TASKWAIT_DIRECTIVE:
- S = OMPTaskwaitDirective::CreateEmpty(Context, Empty);
- break;
-
- case STMT_OMP_TASKGROUP_DIRECTIVE:
- S = OMPTaskgroupDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_FLUSH_DIRECTIVE:
- S = OMPFlushDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_ORDERED_DIRECTIVE:
- S = OMPOrderedDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_ATOMIC_DIRECTIVE:
- S = OMPAtomicDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_DIRECTIVE:
- S = OMPTargetDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_DATA_DIRECTIVE:
- S = OMPTargetDataDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE:
- S = OMPTargetEnterDataDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE:
- S = OMPTargetExitDataDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_PARALLEL_DIRECTIVE:
- S = OMPTargetParallelDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetParallelForDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_UPDATE_DIRECTIVE:
- S = OMPTargetUpdateDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TEAMS_DIRECTIVE:
- S = OMPTeamsDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_CANCELLATION_POINT_DIRECTIVE:
- S = OMPCancellationPointDirective::CreateEmpty(Context, Empty);
- break;
-
- case STMT_OMP_CANCEL_DIRECTIVE:
- S = OMPCancelDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TASKLOOP_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTaskLoopDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
- Empty);
- break;
- }
-
- case STMT_OMP_TASKLOOP_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTaskLoopSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_DISTRIBUTE_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPDistributeDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
- Empty);
- break;
- }
-
- case STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPDistributeParallelForDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPDistributeParallelForSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum,
- Empty);
- break;
- }
-
- case STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPDistributeSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetParallelForSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_SIMD_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetSimdDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
- Empty);
- break;
- }
-
- case STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTeamsDistributeDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE: {
- unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
- unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTeamsDistributeSimdDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTeamsDistributeParallelForSimdDirective::CreateEmpty(
- Context, NumClauses, CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTeamsDistributeParallelForDirective::CreateEmpty(
- Context, NumClauses, CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_TEAMS_DIRECTIVE:
- S = OMPTargetTeamsDirective::CreateEmpty(
- Context, Record[ASTStmtReader::NumStmtFields], Empty);
- break;
-
- case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetTeamsDistributeDirective::CreateEmpty(Context, NumClauses,
- CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetTeamsDistributeParallelForDirective::CreateEmpty(
- Context, NumClauses, CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetTeamsDistributeParallelForSimdDirective::CreateEmpty(
- Context, NumClauses, CollapsedNum, Empty);
- break;
- }
-
- case STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE: {
- auto NumClauses = Record[ASTStmtReader::NumStmtFields];
- auto CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
- S = OMPTargetTeamsDistributeSimdDirective::CreateEmpty(
- Context, NumClauses, CollapsedNum, Empty);
- break;
- }
-
- case EXPR_CXX_OPERATOR_CALL:
- S = CXXOperatorCallExpr::CreateEmpty(
- Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
- break;
-
- case EXPR_CXX_MEMBER_CALL:
- S = CXXMemberCallExpr::CreateEmpty(
- Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
- break;
-
- case EXPR_CXX_CONSTRUCT:
- S = CXXConstructExpr::CreateEmpty(
- Context,
- /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_INHERITED_CTOR_INIT:
- S = new (Context) CXXInheritedCtorInitExpr(Empty);
- break;
-
- case EXPR_CXX_TEMPORARY_OBJECT:
- S = CXXTemporaryObjectExpr::CreateEmpty(
- Context,
- /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_STATIC_CAST:
- S = CXXStaticCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_DYNAMIC_CAST:
- S = CXXDynamicCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_REINTERPRET_CAST:
- S = CXXReinterpretCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_CONST_CAST:
- S = CXXConstCastExpr::CreateEmpty(Context);
- break;
-
- case EXPR_CXX_FUNCTIONAL_CAST:
- S = CXXFunctionalCastExpr::CreateEmpty(Context,
- /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_USER_DEFINED_LITERAL:
- S = UserDefinedLiteral::CreateEmpty(
- Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
- break;
-
- case EXPR_CXX_STD_INITIALIZER_LIST:
- S = new (Context) CXXStdInitializerListExpr(Empty);
- break;
-
- case EXPR_CXX_BOOL_LITERAL:
- S = new (Context) CXXBoolLiteralExpr(Empty);
- break;
-
- case EXPR_CXX_NULL_PTR_LITERAL:
- S = new (Context) CXXNullPtrLiteralExpr(Empty);
- break;
-
- case EXPR_CXX_TYPEID_EXPR:
- S = new (Context) CXXTypeidExpr(Empty, true);
- break;
-
- case EXPR_CXX_TYPEID_TYPE:
- S = new (Context) CXXTypeidExpr(Empty, false);
- break;
-
- case EXPR_CXX_UUIDOF_EXPR:
- S = new (Context) CXXUuidofExpr(Empty, true);
- break;
-
- case EXPR_CXX_PROPERTY_REF_EXPR:
- S = new (Context) MSPropertyRefExpr(Empty);
- break;
-
- case EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR:
- S = new (Context) MSPropertySubscriptExpr(Empty);
- break;
-
- case EXPR_CXX_UUIDOF_TYPE:
- S = new (Context) CXXUuidofExpr(Empty, false);
- break;
-
- case EXPR_CXX_THIS:
- S = new (Context) CXXThisExpr(Empty);
- break;
-
- case EXPR_CXX_THROW:
- S = new (Context) CXXThrowExpr(Empty);
- break;
-
- case EXPR_CXX_DEFAULT_ARG:
- S = new (Context) CXXDefaultArgExpr(Empty);
- break;
-
- case EXPR_CXX_DEFAULT_INIT:
- S = new (Context) CXXDefaultInitExpr(Empty);
- break;
-
- case EXPR_CXX_BIND_TEMPORARY:
- S = new (Context) CXXBindTemporaryExpr(Empty);
- break;
-
- case EXPR_CXX_SCALAR_VALUE_INIT:
- S = new (Context) CXXScalarValueInitExpr(Empty);
- break;
-
- case EXPR_CXX_NEW:
- S = CXXNewExpr::CreateEmpty(
- Context,
- /*IsArray=*/Record[ASTStmtReader::NumExprFields],
- /*HasInit=*/Record[ASTStmtReader::NumExprFields + 1],
- /*NumPlacementArgs=*/Record[ASTStmtReader::NumExprFields + 2],
- /*IsParenTypeId=*/Record[ASTStmtReader::NumExprFields + 3]);
- break;
-
- case EXPR_CXX_DELETE:
- S = new (Context) CXXDeleteExpr(Empty);
- break;
-
- case EXPR_CXX_PSEUDO_DESTRUCTOR:
- S = new (Context) CXXPseudoDestructorExpr(Empty);
- break;
-
- case EXPR_EXPR_WITH_CLEANUPS:
- S = ExprWithCleanups::Create(Context, Empty,
- Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
- S = CXXDependentScopeMemberExpr::CreateEmpty(
- Context,
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
- /*HasFirstQualifierFoundInScope=*/
- Record[ASTStmtReader::NumExprFields + 2]);
- break;
-
- case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
- S = DependentScopeDeclRefExpr::CreateEmpty(Context,
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
- /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
- ? Record[ASTStmtReader::NumExprFields + 1]
- : 0);
- break;
-
- case EXPR_CXX_UNRESOLVED_CONSTRUCT:
- S = CXXUnresolvedConstructExpr::CreateEmpty(Context,
- /*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_CXX_UNRESOLVED_MEMBER:
- S = UnresolvedMemberExpr::CreateEmpty(
- Context,
- /*NumResults=*/Record[ASTStmtReader::NumExprFields],
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
- /*NumTemplateArgs=*/
- Record[ASTStmtReader::NumExprFields + 1]
- ? Record[ASTStmtReader::NumExprFields + 2]
- : 0);
- break;
-
- case EXPR_CXX_UNRESOLVED_LOOKUP:
- S = UnresolvedLookupExpr::CreateEmpty(
- Context,
- /*NumResults=*/Record[ASTStmtReader::NumExprFields],
- /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 1],
- /*NumTemplateArgs=*/
- Record[ASTStmtReader::NumExprFields + 1]
- ? Record[ASTStmtReader::NumExprFields + 2]
- : 0);
- break;
-
- case EXPR_TYPE_TRAIT:
- S = TypeTraitExpr::CreateDeserialized(Context,
- Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_ARRAY_TYPE_TRAIT:
- S = new (Context) ArrayTypeTraitExpr(Empty);
- break;
-
- case EXPR_CXX_EXPRESSION_TRAIT:
- S = new (Context) ExpressionTraitExpr(Empty);
- break;
-
- case EXPR_CXX_NOEXCEPT:
- S = new (Context) CXXNoexceptExpr(Empty);
- break;
-
- case EXPR_PACK_EXPANSION:
- S = new (Context) PackExpansionExpr(Empty);
- break;
-
- case EXPR_SIZEOF_PACK:
- S = SizeOfPackExpr::CreateDeserialized(
- Context,
- /*NumPartialArgs=*/Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM:
- S = new (Context) SubstNonTypeTemplateParmExpr(Empty);
- break;
-
- case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK:
- S = new (Context) SubstNonTypeTemplateParmPackExpr(Empty);
- break;
-
- case EXPR_FUNCTION_PARM_PACK:
- S = FunctionParmPackExpr::CreateEmpty(Context,
- Record[ASTStmtReader::NumExprFields]);
- break;
-
- case EXPR_MATERIALIZE_TEMPORARY:
- S = new (Context) MaterializeTemporaryExpr(Empty);
- break;
-
- case EXPR_CXX_FOLD:
- S = new (Context) CXXFoldExpr(Empty);
- break;
-
- case EXPR_OPAQUE_VALUE:
- S = new (Context) OpaqueValueExpr(Empty);
- break;
-
- case EXPR_CUDA_KERNEL_CALL:
- S = CUDAKernelCallExpr::CreateEmpty(
- Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
- break;
-
- case EXPR_ASTYPE:
- S = new (Context) AsTypeExpr(Empty);
- break;
-
- case EXPR_PSEUDO_OBJECT: {
- unsigned numSemanticExprs = Record[ASTStmtReader::NumExprFields];
- S = PseudoObjectExpr::Create(Context, Empty, numSemanticExprs);
- break;
- }
-
- case EXPR_ATOMIC:
- S = new (Context) AtomicExpr(Empty);
- break;
-
- case EXPR_LAMBDA: {
- unsigned NumCaptures = Record[ASTStmtReader::NumExprFields];
- S = LambdaExpr::CreateDeserialized(Context, NumCaptures);
- break;
- }
-
- case STMT_COROUTINE_BODY: {
- unsigned NumParams = Record[ASTStmtReader::NumStmtFields];
- S = CoroutineBodyStmt::Create(Context, Empty, NumParams);
- break;
- }
-
- case STMT_CORETURN:
- S = new (Context) CoreturnStmt(Empty);
- break;
-
- case EXPR_COAWAIT:
- S = new (Context) CoawaitExpr(Empty);
- break;
-
- case EXPR_COYIELD:
- S = new (Context) CoyieldExpr(Empty);
- break;
-
- case EXPR_DEPENDENT_COAWAIT:
- S = new (Context) DependentCoawaitExpr(Empty);
- break;
- }
-
- // We hit a STMT_STOP, so we're done with this expression.
- if (Finished)
- break;
-
- ++NumStatementsRead;
-
- if (S && !IsStmtReference) {
- Reader.Visit(S);
- StmtEntries[Cursor.GetCurrentBitNo()] = S;
- }
-
- assert(Record.getIdx() == Record.size() &&
- "Invalid deserialization of statement");
- StmtStack.push_back(S);
- }
-Done:
- assert(StmtStack.size() > PrevNumStmts && "Read too many sub-stmts!");
- assert(StmtStack.size() == PrevNumStmts + 1 && "Extra expressions on stack!");
- return StmtStack.pop_back_val();
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTWriter.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
deleted file mode 100644
index 37adcb70640..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTWriter.cpp
+++ /dev/null
@@ -1,6955 +0,0 @@
-//===- ASTWriter.cpp - AST File Writer ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTWriter class, which writes AST files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/ASTWriter.h"
-#include "ASTCommon.h"
-#include "ASTReaderInternals.h"
-#include "MultiOnDiskHashTable.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTUnresolvedSet.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclContextInternals.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/LambdaCapture.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLocVisitor.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Lambda.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/ObjCRuntime.h"
-#include "clang/Basic/OpenCLOptions.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/SourceManagerInternals.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/TargetOptions.h"
-#include "clang/Basic/Version.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/HeaderSearchOptions.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/ModuleMap.h"
-#include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Lex/Token.h"
-#include "clang/Sema/IdentifierResolver.h"
-#include "clang/Sema/ObjCMethodList.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Sema/Weak.h"
-#include "clang/Serialization/ASTReader.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/ModuleFileExtension.h"
-#include "clang/Serialization/SerializationDiagnostic.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/Hashing.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/ScopeExit.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Bitcode/BitCodes.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compression.h"
-#include "llvm/Support/DJB.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/EndianStream.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/OnDiskHashTable.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/SHA1.h"
-#include "llvm/Support/VersionTuple.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-#include <deque>
-#include <limits>
-#include <memory>
-#include <queue>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-using namespace clang;
-using namespace clang::serialization;
-
-template <typename T, typename Allocator>
-static StringRef bytes(const std::vector<T, Allocator> &v) {
- if (v.empty()) return StringRef();
- return StringRef(reinterpret_cast<const char*>(&v[0]),
- sizeof(T) * v.size());
-}
-
-template <typename T>
-static StringRef bytes(const SmallVectorImpl<T> &v) {
- return StringRef(reinterpret_cast<const char*>(v.data()),
- sizeof(T) * v.size());
-}
-
-//===----------------------------------------------------------------------===//
-// Type serialization
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-
- class ASTTypeWriter {
- ASTWriter &Writer;
- ASTRecordWriter Record;
-
- /// Type code that corresponds to the record generated.
- TypeCode Code = static_cast<TypeCode>(0);
-
- /// Abbreviation to use for the record, if any.
- unsigned AbbrevToUse = 0;
-
- public:
- ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
- : Writer(Writer), Record(Writer, Record) {}
-
- uint64_t Emit() {
- return Record.Emit(Code, AbbrevToUse);
- }
-
- void Visit(QualType T) {
- if (T.hasLocalNonFastQualifiers()) {
- Qualifiers Qs = T.getLocalQualifiers();
- Record.AddTypeRef(T.getLocalUnqualifiedType());
- Record.push_back(Qs.getAsOpaqueValue());
- Code = TYPE_EXT_QUAL;
- AbbrevToUse = Writer.TypeExtQualAbbrev;
- } else {
- switch (T->getTypeClass()) {
- // For all of the concrete, non-dependent types, call the
- // appropriate visitor function.
-#define TYPE(Class, Base) \
- case Type::Class: Visit##Class##Type(cast<Class##Type>(T)); break;
-#define ABSTRACT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- }
- }
- }
-
- void VisitArrayType(const ArrayType *T);
- void VisitFunctionType(const FunctionType *T);
- void VisitTagType(const TagType *T);
-
-#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T);
-#define ABSTRACT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- };
-
-} // namespace clang
-
-void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
- llvm_unreachable("Built-in types are never serialized");
-}
-
-void ASTTypeWriter::VisitComplexType(const ComplexType *T) {
- Record.AddTypeRef(T->getElementType());
- Code = TYPE_COMPLEX;
-}
-
-void ASTTypeWriter::VisitPointerType(const PointerType *T) {
- Record.AddTypeRef(T->getPointeeType());
- Code = TYPE_POINTER;
-}
-
-void ASTTypeWriter::VisitDecayedType(const DecayedType *T) {
- Record.AddTypeRef(T->getOriginalType());
- Code = TYPE_DECAYED;
-}
-
-void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) {
- Record.AddTypeRef(T->getOriginalType());
- Record.AddTypeRef(T->getAdjustedType());
- Code = TYPE_ADJUSTED;
-}
-
-void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
- Record.AddTypeRef(T->getPointeeType());
- Code = TYPE_BLOCK_POINTER;
-}
-
-void ASTTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
- Record.AddTypeRef(T->getPointeeTypeAsWritten());
- Record.push_back(T->isSpelledAsLValue());
- Code = TYPE_LVALUE_REFERENCE;
-}
-
-void ASTTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
- Record.AddTypeRef(T->getPointeeTypeAsWritten());
- Code = TYPE_RVALUE_REFERENCE;
-}
-
-void ASTTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
- Record.AddTypeRef(T->getPointeeType());
- Record.AddTypeRef(QualType(T->getClass(), 0));
- Code = TYPE_MEMBER_POINTER;
-}
-
-void ASTTypeWriter::VisitArrayType(const ArrayType *T) {
- Record.AddTypeRef(T->getElementType());
- Record.push_back(T->getSizeModifier()); // FIXME: stable values
- Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values
-}
-
-void ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
- VisitArrayType(T);
- Record.AddAPInt(T->getSize());
- Code = TYPE_CONSTANT_ARRAY;
-}
-
-void ASTTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
- VisitArrayType(T);
- Code = TYPE_INCOMPLETE_ARRAY;
-}
-
-void ASTTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
- VisitArrayType(T);
- Record.AddSourceLocation(T->getLBracketLoc());
- Record.AddSourceLocation(T->getRBracketLoc());
- Record.AddStmt(T->getSizeExpr());
- Code = TYPE_VARIABLE_ARRAY;
-}
-
-void ASTTypeWriter::VisitVectorType(const VectorType *T) {
- Record.AddTypeRef(T->getElementType());
- Record.push_back(T->getNumElements());
- Record.push_back(T->getVectorKind());
- Code = TYPE_VECTOR;
-}
-
-void ASTTypeWriter::VisitExtVectorType(const ExtVectorType *T) {
- VisitVectorType(T);
- Code = TYPE_EXT_VECTOR;
-}
-
-void ASTTypeWriter::VisitFunctionType(const FunctionType *T) {
- Record.AddTypeRef(T->getReturnType());
- FunctionType::ExtInfo C = T->getExtInfo();
- Record.push_back(C.getNoReturn());
- Record.push_back(C.getHasRegParm());
- Record.push_back(C.getRegParm());
- // FIXME: need to stabilize encoding of calling convention...
- Record.push_back(C.getCC());
- Record.push_back(C.getProducesResult());
- Record.push_back(C.getNoCallerSavedRegs());
- Record.push_back(C.getNoCfCheck());
-
- if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult())
- AbbrevToUse = 0;
-}
-
-void ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
- VisitFunctionType(T);
- Code = TYPE_FUNCTION_NO_PROTO;
-}
-
-static void addExceptionSpec(const FunctionProtoType *T,
- ASTRecordWriter &Record) {
- Record.push_back(T->getExceptionSpecType());
- if (T->getExceptionSpecType() == EST_Dynamic) {
- Record.push_back(T->getNumExceptions());
- for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I)
- Record.AddTypeRef(T->getExceptionType(I));
- } else if (isComputedNoexcept(T->getExceptionSpecType())) {
- Record.AddStmt(T->getNoexceptExpr());
- } else if (T->getExceptionSpecType() == EST_Uninstantiated) {
- Record.AddDeclRef(T->getExceptionSpecDecl());
- Record.AddDeclRef(T->getExceptionSpecTemplate());
- } else if (T->getExceptionSpecType() == EST_Unevaluated) {
- Record.AddDeclRef(T->getExceptionSpecDecl());
- }
-}
-
-void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
- VisitFunctionType(T);
-
- Record.push_back(T->isVariadic());
- Record.push_back(T->hasTrailingReturn());
- Record.push_back(T->getTypeQuals().getAsOpaqueValue());
- Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
- addExceptionSpec(T, Record);
-
- Record.push_back(T->getNumParams());
- for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
- Record.AddTypeRef(T->getParamType(I));
-
- if (T->hasExtParameterInfos()) {
- for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
- Record.push_back(T->getExtParameterInfo(I).getOpaqueValue());
- }
-
- if (T->isVariadic() || T->hasTrailingReturn() || T->getTypeQuals() ||
- T->getRefQualifier() || T->getExceptionSpecType() != EST_None ||
- T->hasExtParameterInfos())
- AbbrevToUse = 0;
-
- Code = TYPE_FUNCTION_PROTO;
-}
-
-void ASTTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
- Record.AddDeclRef(T->getDecl());
- Code = TYPE_UNRESOLVED_USING;
-}
-
-void ASTTypeWriter::VisitTypedefType(const TypedefType *T) {
- Record.AddDeclRef(T->getDecl());
- assert(!T->isCanonicalUnqualified() && "Invalid typedef ?");
- Record.AddTypeRef(T->getCanonicalTypeInternal());
- Code = TYPE_TYPEDEF;
-}
-
-void ASTTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
- Record.AddStmt(T->getUnderlyingExpr());
- Code = TYPE_TYPEOF_EXPR;
-}
-
-void ASTTypeWriter::VisitTypeOfType(const TypeOfType *T) {
- Record.AddTypeRef(T->getUnderlyingType());
- Code = TYPE_TYPEOF;
-}
-
-void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) {
- Record.AddTypeRef(T->getUnderlyingType());
- Record.AddStmt(T->getUnderlyingExpr());
- Code = TYPE_DECLTYPE;
-}
-
-void ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) {
- Record.AddTypeRef(T->getBaseType());
- Record.AddTypeRef(T->getUnderlyingType());
- Record.push_back(T->getUTTKind());
- Code = TYPE_UNARY_TRANSFORM;
-}
-
-void ASTTypeWriter::VisitAutoType(const AutoType *T) {
- Record.AddTypeRef(T->getDeducedType());
- Record.push_back((unsigned)T->getKeyword());
- if (T->getDeducedType().isNull())
- Record.push_back(T->isDependentType());
- Code = TYPE_AUTO;
-}
-
-void ASTTypeWriter::VisitDeducedTemplateSpecializationType(
- const DeducedTemplateSpecializationType *T) {
- Record.AddTemplateName(T->getTemplateName());
- Record.AddTypeRef(T->getDeducedType());
- if (T->getDeducedType().isNull())
- Record.push_back(T->isDependentType());
- Code = TYPE_DEDUCED_TEMPLATE_SPECIALIZATION;
-}
-
-void ASTTypeWriter::VisitTagType(const TagType *T) {
- Record.push_back(T->isDependentType());
- Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
- assert(!T->isBeingDefined() &&
- "Cannot serialize in the middle of a type definition");
-}
-
-void ASTTypeWriter::VisitRecordType(const RecordType *T) {
- VisitTagType(T);
- Code = TYPE_RECORD;
-}
-
-void ASTTypeWriter::VisitEnumType(const EnumType *T) {
- VisitTagType(T);
- Code = TYPE_ENUM;
-}
-
-void ASTTypeWriter::VisitAttributedType(const AttributedType *T) {
- Record.AddTypeRef(T->getModifiedType());
- Record.AddTypeRef(T->getEquivalentType());
- Record.push_back(T->getAttrKind());
- Code = TYPE_ATTRIBUTED;
-}
-
-void
-ASTTypeWriter::VisitSubstTemplateTypeParmType(
- const SubstTemplateTypeParmType *T) {
- Record.AddTypeRef(QualType(T->getReplacedParameter(), 0));
- Record.AddTypeRef(T->getReplacementType());
- Code = TYPE_SUBST_TEMPLATE_TYPE_PARM;
-}
-
-void
-ASTTypeWriter::VisitSubstTemplateTypeParmPackType(
- const SubstTemplateTypeParmPackType *T) {
- Record.AddTypeRef(QualType(T->getReplacedParameter(), 0));
- Record.AddTemplateArgument(T->getArgumentPack());
- Code = TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK;
-}
-
-void
-ASTTypeWriter::VisitTemplateSpecializationType(
- const TemplateSpecializationType *T) {
- Record.push_back(T->isDependentType());
- Record.AddTemplateName(T->getTemplateName());
- Record.push_back(T->getNumArgs());
- for (const auto &ArgI : *T)
- Record.AddTemplateArgument(ArgI);
- Record.AddTypeRef(T->isTypeAlias() ? T->getAliasedType()
- : T->isCanonicalUnqualified()
- ? QualType()
- : T->getCanonicalTypeInternal());
- Code = TYPE_TEMPLATE_SPECIALIZATION;
-}
-
-void
-ASTTypeWriter::VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
- VisitArrayType(T);
- Record.AddStmt(T->getSizeExpr());
- Record.AddSourceRange(T->getBracketsRange());
- Code = TYPE_DEPENDENT_SIZED_ARRAY;
-}
-
-void
-ASTTypeWriter::VisitDependentSizedExtVectorType(
- const DependentSizedExtVectorType *T) {
- Record.AddTypeRef(T->getElementType());
- Record.AddStmt(T->getSizeExpr());
- Record.AddSourceLocation(T->getAttributeLoc());
- Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
-}
-
-void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) {
- Record.AddTypeRef(T->getElementType());
- Record.AddStmt(const_cast<Expr*>(T->getSizeExpr()));
- Record.AddSourceLocation(T->getAttributeLoc());
- Record.push_back(T->getVectorKind());
- Code = TYPE_DEPENDENT_SIZED_VECTOR;
-}
-
-void
-ASTTypeWriter::VisitDependentAddressSpaceType(
- const DependentAddressSpaceType *T) {
- Record.AddTypeRef(T->getPointeeType());
- Record.AddStmt(T->getAddrSpaceExpr());
- Record.AddSourceLocation(T->getAttributeLoc());
- Code = TYPE_DEPENDENT_ADDRESS_SPACE;
-}
-
-void
-ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
- Record.push_back(T->getDepth());
- Record.push_back(T->getIndex());
- Record.push_back(T->isParameterPack());
- Record.AddDeclRef(T->getDecl());
- Code = TYPE_TEMPLATE_TYPE_PARM;
-}
-
-void
-ASTTypeWriter::VisitDependentNameType(const DependentNameType *T) {
- Record.push_back(T->getKeyword());
- Record.AddNestedNameSpecifier(T->getQualifier());
- Record.AddIdentifierRef(T->getIdentifier());
- Record.AddTypeRef(
- T->isCanonicalUnqualified() ? QualType() : T->getCanonicalTypeInternal());
- Code = TYPE_DEPENDENT_NAME;
-}
-
-void
-ASTTypeWriter::VisitDependentTemplateSpecializationType(
- const DependentTemplateSpecializationType *T) {
- Record.push_back(T->getKeyword());
- Record.AddNestedNameSpecifier(T->getQualifier());
- Record.AddIdentifierRef(T->getIdentifier());
- Record.push_back(T->getNumArgs());
- for (const auto &I : *T)
- Record.AddTemplateArgument(I);
- Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION;
-}
-
-void ASTTypeWriter::VisitPackExpansionType(const PackExpansionType *T) {
- Record.AddTypeRef(T->getPattern());
- if (Optional<unsigned> NumExpansions = T->getNumExpansions())
- Record.push_back(*NumExpansions + 1);
- else
- Record.push_back(0);
- Code = TYPE_PACK_EXPANSION;
-}
-
-void ASTTypeWriter::VisitParenType(const ParenType *T) {
- Record.AddTypeRef(T->getInnerType());
- Code = TYPE_PAREN;
-}
-
-void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
- Record.push_back(T->getKeyword());
- Record.AddNestedNameSpecifier(T->getQualifier());
- Record.AddTypeRef(T->getNamedType());
- Record.AddDeclRef(T->getOwnedTagDecl());
- Code = TYPE_ELABORATED;
-}
-
-void ASTTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
- Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
- Record.AddTypeRef(T->getInjectedSpecializationType());
- Code = TYPE_INJECTED_CLASS_NAME;
-}
-
-void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- Record.AddDeclRef(T->getDecl()->getCanonicalDecl());
- Code = TYPE_OBJC_INTERFACE;
-}
-
-void ASTTypeWriter::VisitObjCTypeParamType(const ObjCTypeParamType *T) {
- Record.AddDeclRef(T->getDecl());
- Record.push_back(T->getNumProtocols());
- for (const auto *I : T->quals())
- Record.AddDeclRef(I);
- Code = TYPE_OBJC_TYPE_PARAM;
-}
-
-void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
- Record.AddTypeRef(T->getBaseType());
- Record.push_back(T->getTypeArgsAsWritten().size());
- for (auto TypeArg : T->getTypeArgsAsWritten())
- Record.AddTypeRef(TypeArg);
- Record.push_back(T->getNumProtocols());
- for (const auto *I : T->quals())
- Record.AddDeclRef(I);
- Record.push_back(T->isKindOfTypeAsWritten());
- Code = TYPE_OBJC_OBJECT;
-}
-
-void
-ASTTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
- Record.AddTypeRef(T->getPointeeType());
- Code = TYPE_OBJC_OBJECT_POINTER;
-}
-
-void
-ASTTypeWriter::VisitAtomicType(const AtomicType *T) {
- Record.AddTypeRef(T->getValueType());
- Code = TYPE_ATOMIC;
-}
-
-void
-ASTTypeWriter::VisitPipeType(const PipeType *T) {
- Record.AddTypeRef(T->getElementType());
- Record.push_back(T->isReadOnly());
- Code = TYPE_PIPE;
-}
-
-namespace {
-
-class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
- ASTRecordWriter &Record;
-
-public:
- TypeLocWriter(ASTRecordWriter &Record) : Record(Record) {}
-
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
-#include "clang/AST/TypeLocNodes.def"
-
- void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
- void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
-};
-
-} // namespace
-
-void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
- // nothing to do
-}
-
-void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
- Record.AddSourceLocation(TL.getBuiltinLoc());
- if (TL.needsExtraLocalData()) {
- Record.push_back(TL.getWrittenTypeSpec());
- Record.push_back(TL.getWrittenSignSpec());
- Record.push_back(TL.getWrittenWidthSpec());
- Record.push_back(TL.hasModeAttr());
- }
-}
-
-void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
- Record.AddSourceLocation(TL.getStarLoc());
-}
-
-void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
- // nothing to do
-}
-
-void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
- // nothing to do
-}
-
-void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
- Record.AddSourceLocation(TL.getCaretLoc());
-}
-
-void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
- Record.AddSourceLocation(TL.getAmpLoc());
-}
-
-void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
- Record.AddSourceLocation(TL.getAmpAmpLoc());
-}
-
-void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
- Record.AddSourceLocation(TL.getStarLoc());
- Record.AddTypeSourceInfo(TL.getClassTInfo());
-}
-
-void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
- Record.AddSourceLocation(TL.getLBracketLoc());
- Record.AddSourceLocation(TL.getRBracketLoc());
- Record.push_back(TL.getSizeExpr() ? 1 : 0);
- if (TL.getSizeExpr())
- Record.AddStmt(TL.getSizeExpr());
-}
-
-void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
- DependentSizedArrayTypeLoc TL) {
- VisitArrayTypeLoc(TL);
-}
-
-void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
- DependentAddressSpaceTypeLoc TL) {
- Record.AddSourceLocation(TL.getAttrNameLoc());
- SourceRange range = TL.getAttrOperandParensRange();
- Record.AddSourceLocation(range.getBegin());
- Record.AddSourceLocation(range.getEnd());
- Record.AddStmt(TL.getAttrExprOperand());
-}
-
-void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
- DependentSizedExtVectorTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitDependentVectorTypeLoc(
- DependentVectorTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
- Record.AddSourceLocation(TL.getLocalRangeBegin());
- Record.AddSourceLocation(TL.getLParenLoc());
- Record.AddSourceLocation(TL.getRParenLoc());
- Record.AddSourceRange(TL.getExceptionSpecRange());
- Record.AddSourceLocation(TL.getLocalRangeEnd());
- for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
- Record.AddDeclRef(TL.getParam(i));
-}
-
-void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
- VisitFunctionTypeLoc(TL);
-}
-
-void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
- VisitFunctionTypeLoc(TL);
-}
-
-void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
- if (TL.getNumProtocols()) {
- Record.AddSourceLocation(TL.getProtocolLAngleLoc());
- Record.AddSourceLocation(TL.getProtocolRAngleLoc());
- }
- for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
- Record.AddSourceLocation(TL.getProtocolLoc(i));
-}
-
-void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
- Record.AddSourceLocation(TL.getTypeofLoc());
- Record.AddSourceLocation(TL.getLParenLoc());
- Record.AddSourceLocation(TL.getRParenLoc());
-}
-
-void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
- Record.AddSourceLocation(TL.getTypeofLoc());
- Record.AddSourceLocation(TL.getLParenLoc());
- Record.AddSourceLocation(TL.getRParenLoc());
- Record.AddTypeSourceInfo(TL.getUnderlyingTInfo());
-}
-
-void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
- Record.AddSourceLocation(TL.getKWLoc());
- Record.AddSourceLocation(TL.getLParenLoc());
- Record.AddSourceLocation(TL.getRParenLoc());
- Record.AddTypeSourceInfo(TL.getUnderlyingTInfo());
-}
-
-void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
- DeducedTemplateSpecializationTypeLoc TL) {
- Record.AddSourceLocation(TL.getTemplateNameLoc());
-}
-
-void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
- Record.AddAttr(TL.getAttr());
-}
-
-void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
- SubstTemplateTypeParmTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
- SubstTemplateTypeParmPackTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
- TemplateSpecializationTypeLoc TL) {
- Record.AddSourceLocation(TL.getTemplateKeywordLoc());
- Record.AddSourceLocation(TL.getTemplateNameLoc());
- Record.AddSourceLocation(TL.getLAngleLoc());
- Record.AddSourceLocation(TL.getRAngleLoc());
- for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- Record.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
- TL.getArgLoc(i).getLocInfo());
-}
-
-void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
- Record.AddSourceLocation(TL.getLParenLoc());
- Record.AddSourceLocation(TL.getRParenLoc());
-}
-
-void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
- Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
-}
-
-void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
- Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
- Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc TL) {
- Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
- Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
- Record.AddSourceLocation(TL.getTemplateKeywordLoc());
- Record.AddSourceLocation(TL.getTemplateNameLoc());
- Record.AddSourceLocation(TL.getLAngleLoc());
- Record.AddSourceLocation(TL.getRAngleLoc());
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- Record.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(),
- TL.getArgLoc(I).getLocInfo());
-}
-
-void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
- Record.AddSourceLocation(TL.getEllipsisLoc());
-}
-
-void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
- Record.AddSourceLocation(TL.getNameLoc());
-}
-
-void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
- Record.push_back(TL.hasBaseTypeAsWritten());
- Record.AddSourceLocation(TL.getTypeArgsLAngleLoc());
- Record.AddSourceLocation(TL.getTypeArgsRAngleLoc());
- for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)
- Record.AddTypeSourceInfo(TL.getTypeArgTInfo(i));
- Record.AddSourceLocation(TL.getProtocolLAngleLoc());
- Record.AddSourceLocation(TL.getProtocolRAngleLoc());
- for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
- Record.AddSourceLocation(TL.getProtocolLoc(i));
-}
-
-void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
- Record.AddSourceLocation(TL.getStarLoc());
-}
-
-void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
- Record.AddSourceLocation(TL.getKWLoc());
- Record.AddSourceLocation(TL.getLParenLoc());
- Record.AddSourceLocation(TL.getRParenLoc());
-}
-
-void TypeLocWriter::VisitPipeTypeLoc(PipeTypeLoc TL) {
- Record.AddSourceLocation(TL.getKWLoc());
-}
-
-void ASTWriter::WriteTypeAbbrevs() {
- using namespace llvm;
-
- std::shared_ptr<BitCodeAbbrev> Abv;
-
- // Abbreviation for TYPE_EXT_QUAL
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3)); // Quals
- TypeExtQualAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for TYPE_FUNCTION_PROTO
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::TYPE_FUNCTION_PROTO));
- // FunctionType
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ReturnType
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // NoReturn
- Abv->Add(BitCodeAbbrevOp(0)); // HasRegParm
- Abv->Add(BitCodeAbbrevOp(0)); // RegParm
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC
- Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult
- Abv->Add(BitCodeAbbrevOp(0)); // NoCallerSavedRegs
- Abv->Add(BitCodeAbbrevOp(0)); // NoCfCheck
- // FunctionProtoType
- Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic
- Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn
- Abv->Add(BitCodeAbbrevOp(0)); // TypeQuals
- Abv->Add(BitCodeAbbrevOp(0)); // RefQualifier
- Abv->Add(BitCodeAbbrevOp(EST_None)); // ExceptionSpec
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumParams
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Params
- TypeFunctionProtoAbbrev = Stream.EmitAbbrev(std::move(Abv));
-}
-
-//===----------------------------------------------------------------------===//
-// ASTWriter Implementation
-//===----------------------------------------------------------------------===//
-
-static void EmitBlockID(unsigned ID, const char *Name,
- llvm::BitstreamWriter &Stream,
- ASTWriter::RecordDataImpl &Record) {
- Record.clear();
- Record.push_back(ID);
- Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
-
- // Emit the block name if present.
- if (!Name || Name[0] == 0)
- return;
- Record.clear();
- while (*Name)
- Record.push_back(*Name++);
- Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
-}
-
-static void EmitRecordID(unsigned ID, const char *Name,
- llvm::BitstreamWriter &Stream,
- ASTWriter::RecordDataImpl &Record) {
- Record.clear();
- Record.push_back(ID);
- while (*Name)
- Record.push_back(*Name++);
- Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
-}
-
-static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
- ASTWriter::RecordDataImpl &Record) {
-#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
- RECORD(STMT_STOP);
- RECORD(STMT_NULL_PTR);
- RECORD(STMT_REF_PTR);
- RECORD(STMT_NULL);
- RECORD(STMT_COMPOUND);
- RECORD(STMT_CASE);
- RECORD(STMT_DEFAULT);
- RECORD(STMT_LABEL);
- RECORD(STMT_ATTRIBUTED);
- RECORD(STMT_IF);
- RECORD(STMT_SWITCH);
- RECORD(STMT_WHILE);
- RECORD(STMT_DO);
- RECORD(STMT_FOR);
- RECORD(STMT_GOTO);
- RECORD(STMT_INDIRECT_GOTO);
- RECORD(STMT_CONTINUE);
- RECORD(STMT_BREAK);
- RECORD(STMT_RETURN);
- RECORD(STMT_DECL);
- RECORD(STMT_GCCASM);
- RECORD(STMT_MSASM);
- RECORD(EXPR_PREDEFINED);
- RECORD(EXPR_DECL_REF);
- RECORD(EXPR_INTEGER_LITERAL);
- RECORD(EXPR_FLOATING_LITERAL);
- RECORD(EXPR_IMAGINARY_LITERAL);
- RECORD(EXPR_STRING_LITERAL);
- RECORD(EXPR_CHARACTER_LITERAL);
- RECORD(EXPR_PAREN);
- RECORD(EXPR_PAREN_LIST);
- RECORD(EXPR_UNARY_OPERATOR);
- RECORD(EXPR_SIZEOF_ALIGN_OF);
- RECORD(EXPR_ARRAY_SUBSCRIPT);
- RECORD(EXPR_CALL);
- RECORD(EXPR_MEMBER);
- RECORD(EXPR_BINARY_OPERATOR);
- RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR);
- RECORD(EXPR_CONDITIONAL_OPERATOR);
- RECORD(EXPR_IMPLICIT_CAST);
- RECORD(EXPR_CSTYLE_CAST);
- RECORD(EXPR_COMPOUND_LITERAL);
- RECORD(EXPR_EXT_VECTOR_ELEMENT);
- RECORD(EXPR_INIT_LIST);
- RECORD(EXPR_DESIGNATED_INIT);
- RECORD(EXPR_DESIGNATED_INIT_UPDATE);
- RECORD(EXPR_IMPLICIT_VALUE_INIT);
- RECORD(EXPR_NO_INIT);
- RECORD(EXPR_VA_ARG);
- RECORD(EXPR_ADDR_LABEL);
- RECORD(EXPR_STMT);
- RECORD(EXPR_CHOOSE);
- RECORD(EXPR_GNU_NULL);
- RECORD(EXPR_SHUFFLE_VECTOR);
- RECORD(EXPR_BLOCK);
- RECORD(EXPR_GENERIC_SELECTION);
- RECORD(EXPR_OBJC_STRING_LITERAL);
- RECORD(EXPR_OBJC_BOXED_EXPRESSION);
- RECORD(EXPR_OBJC_ARRAY_LITERAL);
- RECORD(EXPR_OBJC_DICTIONARY_LITERAL);
- RECORD(EXPR_OBJC_ENCODE);
- RECORD(EXPR_OBJC_SELECTOR_EXPR);
- RECORD(EXPR_OBJC_PROTOCOL_EXPR);
- RECORD(EXPR_OBJC_IVAR_REF_EXPR);
- RECORD(EXPR_OBJC_PROPERTY_REF_EXPR);
- RECORD(EXPR_OBJC_KVC_REF_EXPR);
- RECORD(EXPR_OBJC_MESSAGE_EXPR);
- RECORD(STMT_OBJC_FOR_COLLECTION);
- RECORD(STMT_OBJC_CATCH);
- RECORD(STMT_OBJC_FINALLY);
- RECORD(STMT_OBJC_AT_TRY);
- RECORD(STMT_OBJC_AT_SYNCHRONIZED);
- RECORD(STMT_OBJC_AT_THROW);
- RECORD(EXPR_OBJC_BOOL_LITERAL);
- RECORD(STMT_CXX_CATCH);
- RECORD(STMT_CXX_TRY);
- RECORD(STMT_CXX_FOR_RANGE);
- RECORD(EXPR_CXX_OPERATOR_CALL);
- RECORD(EXPR_CXX_MEMBER_CALL);
- RECORD(EXPR_CXX_CONSTRUCT);
- RECORD(EXPR_CXX_TEMPORARY_OBJECT);
- RECORD(EXPR_CXX_STATIC_CAST);
- RECORD(EXPR_CXX_DYNAMIC_CAST);
- RECORD(EXPR_CXX_REINTERPRET_CAST);
- RECORD(EXPR_CXX_CONST_CAST);
- RECORD(EXPR_CXX_FUNCTIONAL_CAST);
- RECORD(EXPR_USER_DEFINED_LITERAL);
- RECORD(EXPR_CXX_STD_INITIALIZER_LIST);
- RECORD(EXPR_CXX_BOOL_LITERAL);
- RECORD(EXPR_CXX_NULL_PTR_LITERAL);
- RECORD(EXPR_CXX_TYPEID_EXPR);
- RECORD(EXPR_CXX_TYPEID_TYPE);
- RECORD(EXPR_CXX_THIS);
- RECORD(EXPR_CXX_THROW);
- RECORD(EXPR_CXX_DEFAULT_ARG);
- RECORD(EXPR_CXX_DEFAULT_INIT);
- RECORD(EXPR_CXX_BIND_TEMPORARY);
- RECORD(EXPR_CXX_SCALAR_VALUE_INIT);
- RECORD(EXPR_CXX_NEW);
- RECORD(EXPR_CXX_DELETE);
- RECORD(EXPR_CXX_PSEUDO_DESTRUCTOR);
- RECORD(EXPR_EXPR_WITH_CLEANUPS);
- RECORD(EXPR_CXX_DEPENDENT_SCOPE_MEMBER);
- RECORD(EXPR_CXX_DEPENDENT_SCOPE_DECL_REF);
- RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);
- RECORD(EXPR_CXX_UNRESOLVED_MEMBER);
- RECORD(EXPR_CXX_UNRESOLVED_LOOKUP);
- RECORD(EXPR_CXX_EXPRESSION_TRAIT);
- RECORD(EXPR_CXX_NOEXCEPT);
- RECORD(EXPR_OPAQUE_VALUE);
- RECORD(EXPR_BINARY_CONDITIONAL_OPERATOR);
- RECORD(EXPR_TYPE_TRAIT);
- RECORD(EXPR_ARRAY_TYPE_TRAIT);
- RECORD(EXPR_PACK_EXPANSION);
- RECORD(EXPR_SIZEOF_PACK);
- RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);
- RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
- RECORD(EXPR_FUNCTION_PARM_PACK);
- RECORD(EXPR_MATERIALIZE_TEMPORARY);
- RECORD(EXPR_CUDA_KERNEL_CALL);
- RECORD(EXPR_CXX_UUIDOF_EXPR);
- RECORD(EXPR_CXX_UUIDOF_TYPE);
- RECORD(EXPR_LAMBDA);
-#undef RECORD
-}
-
-void ASTWriter::WriteBlockInfoBlock() {
- RecordData Record;
- Stream.EnterBlockInfoBlock();
-
-#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record)
-#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
-
- // Control Block.
- BLOCK(CONTROL_BLOCK);
- RECORD(METADATA);
- RECORD(MODULE_NAME);
- RECORD(MODULE_DIRECTORY);
- RECORD(MODULE_MAP_FILE);
- RECORD(IMPORTS);
- RECORD(ORIGINAL_FILE);
- RECORD(ORIGINAL_PCH_DIR);
- RECORD(ORIGINAL_FILE_ID);
- RECORD(INPUT_FILE_OFFSETS);
-
- BLOCK(OPTIONS_BLOCK);
- RECORD(LANGUAGE_OPTIONS);
- RECORD(TARGET_OPTIONS);
- RECORD(FILE_SYSTEM_OPTIONS);
- RECORD(HEADER_SEARCH_OPTIONS);
- RECORD(PREPROCESSOR_OPTIONS);
-
- BLOCK(INPUT_FILES_BLOCK);
- RECORD(INPUT_FILE);
-
- // AST Top-Level Block.
- BLOCK(AST_BLOCK);
- RECORD(TYPE_OFFSET);
- RECORD(DECL_OFFSET);
- RECORD(IDENTIFIER_OFFSET);
- RECORD(IDENTIFIER_TABLE);
- RECORD(EAGERLY_DESERIALIZED_DECLS);
- RECORD(MODULAR_CODEGEN_DECLS);
- RECORD(SPECIAL_TYPES);
- RECORD(STATISTICS);
- RECORD(TENTATIVE_DEFINITIONS);
- RECORD(SELECTOR_OFFSETS);
- RECORD(METHOD_POOL);
- RECORD(PP_COUNTER_VALUE);
- RECORD(SOURCE_LOCATION_OFFSETS);
- RECORD(SOURCE_LOCATION_PRELOADS);
- RECORD(EXT_VECTOR_DECLS);
- RECORD(UNUSED_FILESCOPED_DECLS);
- RECORD(PPD_ENTITIES_OFFSETS);
- RECORD(VTABLE_USES);
- RECORD(PPD_SKIPPED_RANGES);
- RECORD(REFERENCED_SELECTOR_POOL);
- RECORD(TU_UPDATE_LEXICAL);
- RECORD(SEMA_DECL_REFS);
- RECORD(WEAK_UNDECLARED_IDENTIFIERS);
- RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
- RECORD(UPDATE_VISIBLE);
- RECORD(DECL_UPDATE_OFFSETS);
- RECORD(DECL_UPDATES);
- RECORD(CUDA_SPECIAL_DECL_REFS);
- RECORD(HEADER_SEARCH_TABLE);
- RECORD(FP_PRAGMA_OPTIONS);
- RECORD(OPENCL_EXTENSIONS);
- RECORD(OPENCL_EXTENSION_TYPES);
- RECORD(OPENCL_EXTENSION_DECLS);
- RECORD(DELEGATING_CTORS);
- RECORD(KNOWN_NAMESPACES);
- RECORD(MODULE_OFFSET_MAP);
- RECORD(SOURCE_MANAGER_LINE_TABLE);
- RECORD(OBJC_CATEGORIES_MAP);
- RECORD(FILE_SORTED_DECLS);
- RECORD(IMPORTED_MODULES);
- RECORD(OBJC_CATEGORIES);
- RECORD(MACRO_OFFSET);
- RECORD(INTERESTING_IDENTIFIERS);
- RECORD(UNDEFINED_BUT_USED);
- RECORD(LATE_PARSED_TEMPLATE);
- RECORD(OPTIMIZE_PRAGMA_OPTIONS);
- RECORD(MSSTRUCT_PRAGMA_OPTIONS);
- RECORD(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS);
- RECORD(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES);
- RECORD(DELETE_EXPRS_TO_ANALYZE);
- RECORD(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH);
- RECORD(PP_CONDITIONAL_STACK);
-
- // SourceManager Block.
- BLOCK(SOURCE_MANAGER_BLOCK);
- RECORD(SM_SLOC_FILE_ENTRY);
- RECORD(SM_SLOC_BUFFER_ENTRY);
- RECORD(SM_SLOC_BUFFER_BLOB);
- RECORD(SM_SLOC_BUFFER_BLOB_COMPRESSED);
- RECORD(SM_SLOC_EXPANSION_ENTRY);
-
- // Preprocessor Block.
- BLOCK(PREPROCESSOR_BLOCK);
- RECORD(PP_MACRO_DIRECTIVE_HISTORY);
- RECORD(PP_MACRO_FUNCTION_LIKE);
- RECORD(PP_MACRO_OBJECT_LIKE);
- RECORD(PP_MODULE_MACRO);
- RECORD(PP_TOKEN);
-
- // Submodule Block.
- BLOCK(SUBMODULE_BLOCK);
- RECORD(SUBMODULE_METADATA);
- RECORD(SUBMODULE_DEFINITION);
- RECORD(SUBMODULE_UMBRELLA_HEADER);
- RECORD(SUBMODULE_HEADER);
- RECORD(SUBMODULE_TOPHEADER);
- RECORD(SUBMODULE_UMBRELLA_DIR);
- RECORD(SUBMODULE_IMPORTS);
- RECORD(SUBMODULE_EXPORTS);
- RECORD(SUBMODULE_REQUIRES);
- RECORD(SUBMODULE_EXCLUDED_HEADER);
- RECORD(SUBMODULE_LINK_LIBRARY);
- RECORD(SUBMODULE_CONFIG_MACRO);
- RECORD(SUBMODULE_CONFLICT);
- RECORD(SUBMODULE_PRIVATE_HEADER);
- RECORD(SUBMODULE_TEXTUAL_HEADER);
- RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
- RECORD(SUBMODULE_INITIALIZERS);
- RECORD(SUBMODULE_EXPORT_AS);
-
- // Comments Block.
- BLOCK(COMMENTS_BLOCK);
- RECORD(COMMENTS_RAW_COMMENT);
-
- // Decls and Types block.
- BLOCK(DECLTYPES_BLOCK);
- RECORD(TYPE_EXT_QUAL);
- RECORD(TYPE_COMPLEX);
- RECORD(TYPE_POINTER);
- RECORD(TYPE_BLOCK_POINTER);
- RECORD(TYPE_LVALUE_REFERENCE);
- RECORD(TYPE_RVALUE_REFERENCE);
- RECORD(TYPE_MEMBER_POINTER);
- RECORD(TYPE_CONSTANT_ARRAY);
- RECORD(TYPE_INCOMPLETE_ARRAY);
- RECORD(TYPE_VARIABLE_ARRAY);
- RECORD(TYPE_VECTOR);
- RECORD(TYPE_EXT_VECTOR);
- RECORD(TYPE_FUNCTION_NO_PROTO);
- RECORD(TYPE_FUNCTION_PROTO);
- RECORD(TYPE_TYPEDEF);
- RECORD(TYPE_TYPEOF_EXPR);
- RECORD(TYPE_TYPEOF);
- RECORD(TYPE_RECORD);
- RECORD(TYPE_ENUM);
- RECORD(TYPE_OBJC_INTERFACE);
- RECORD(TYPE_OBJC_OBJECT_POINTER);
- RECORD(TYPE_DECLTYPE);
- RECORD(TYPE_ELABORATED);
- RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM);
- RECORD(TYPE_UNRESOLVED_USING);
- RECORD(TYPE_INJECTED_CLASS_NAME);
- RECORD(TYPE_OBJC_OBJECT);
- RECORD(TYPE_TEMPLATE_TYPE_PARM);
- RECORD(TYPE_TEMPLATE_SPECIALIZATION);
- RECORD(TYPE_DEPENDENT_NAME);
- RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION);
- RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
- RECORD(TYPE_PAREN);
- RECORD(TYPE_PACK_EXPANSION);
- RECORD(TYPE_ATTRIBUTED);
- RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
- RECORD(TYPE_AUTO);
- RECORD(TYPE_UNARY_TRANSFORM);
- RECORD(TYPE_ATOMIC);
- RECORD(TYPE_DECAYED);
- RECORD(TYPE_ADJUSTED);
- RECORD(TYPE_OBJC_TYPE_PARAM);
- RECORD(LOCAL_REDECLARATIONS);
- RECORD(DECL_TYPEDEF);
- RECORD(DECL_TYPEALIAS);
- RECORD(DECL_ENUM);
- RECORD(DECL_RECORD);
- RECORD(DECL_ENUM_CONSTANT);
- RECORD(DECL_FUNCTION);
- RECORD(DECL_OBJC_METHOD);
- RECORD(DECL_OBJC_INTERFACE);
- RECORD(DECL_OBJC_PROTOCOL);
- RECORD(DECL_OBJC_IVAR);
- RECORD(DECL_OBJC_AT_DEFS_FIELD);
- RECORD(DECL_OBJC_CATEGORY);
- RECORD(DECL_OBJC_CATEGORY_IMPL);
- RECORD(DECL_OBJC_IMPLEMENTATION);
- RECORD(DECL_OBJC_COMPATIBLE_ALIAS);
- RECORD(DECL_OBJC_PROPERTY);
- RECORD(DECL_OBJC_PROPERTY_IMPL);
- RECORD(DECL_FIELD);
- RECORD(DECL_MS_PROPERTY);
- RECORD(DECL_VAR);
- RECORD(DECL_IMPLICIT_PARAM);
- RECORD(DECL_PARM_VAR);
- RECORD(DECL_FILE_SCOPE_ASM);
- RECORD(DECL_BLOCK);
- RECORD(DECL_CONTEXT_LEXICAL);
- RECORD(DECL_CONTEXT_VISIBLE);
- RECORD(DECL_NAMESPACE);
- RECORD(DECL_NAMESPACE_ALIAS);
- RECORD(DECL_USING);
- RECORD(DECL_USING_SHADOW);
- RECORD(DECL_USING_DIRECTIVE);
- RECORD(DECL_UNRESOLVED_USING_VALUE);
- RECORD(DECL_UNRESOLVED_USING_TYPENAME);
- RECORD(DECL_LINKAGE_SPEC);
- RECORD(DECL_CXX_RECORD);
- RECORD(DECL_CXX_METHOD);
- RECORD(DECL_CXX_CONSTRUCTOR);
- RECORD(DECL_CXX_INHERITED_CONSTRUCTOR);
- RECORD(DECL_CXX_DESTRUCTOR);
- RECORD(DECL_CXX_CONVERSION);
- RECORD(DECL_ACCESS_SPEC);
- RECORD(DECL_FRIEND);
- RECORD(DECL_FRIEND_TEMPLATE);
- RECORD(DECL_CLASS_TEMPLATE);
- RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION);
- RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION);
- RECORD(DECL_VAR_TEMPLATE);
- RECORD(DECL_VAR_TEMPLATE_SPECIALIZATION);
- RECORD(DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION);
- RECORD(DECL_FUNCTION_TEMPLATE);
- RECORD(DECL_TEMPLATE_TYPE_PARM);
- RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
- RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
- RECORD(DECL_TYPE_ALIAS_TEMPLATE);
- RECORD(DECL_STATIC_ASSERT);
- RECORD(DECL_CXX_BASE_SPECIFIERS);
- RECORD(DECL_CXX_CTOR_INITIALIZERS);
- RECORD(DECL_INDIRECTFIELD);
- RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK);
- RECORD(DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK);
- RECORD(DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION);
- RECORD(DECL_IMPORT);
- RECORD(DECL_OMP_THREADPRIVATE);
- RECORD(DECL_EMPTY);
- RECORD(DECL_OBJC_TYPE_PARAM);
- RECORD(DECL_OMP_CAPTUREDEXPR);
- RECORD(DECL_PRAGMA_COMMENT);
- RECORD(DECL_PRAGMA_DETECT_MISMATCH);
- RECORD(DECL_OMP_DECLARE_REDUCTION);
-
- // Statements and Exprs can occur in the Decls and Types block.
- AddStmtsExprs(Stream, Record);
-
- BLOCK(PREPROCESSOR_DETAIL_BLOCK);
- RECORD(PPD_MACRO_EXPANSION);
- RECORD(PPD_MACRO_DEFINITION);
- RECORD(PPD_INCLUSION_DIRECTIVE);
-
- // Decls and Types block.
- BLOCK(EXTENSION_BLOCK);
- RECORD(EXTENSION_METADATA);
-
- BLOCK(UNHASHED_CONTROL_BLOCK);
- RECORD(SIGNATURE);
- RECORD(DIAGNOSTIC_OPTIONS);
- RECORD(DIAG_PRAGMA_MAPPINGS);
-
-#undef RECORD
-#undef BLOCK
- Stream.ExitBlock();
-}
-
-/// Prepares a path for being written to an AST file by converting it
-/// to an absolute path and removing nested './'s.
-///
-/// \return \c true if the path was changed.
-static bool cleanPathForOutput(FileManager &FileMgr,
- SmallVectorImpl<char> &Path) {
- bool Changed = FileMgr.makeAbsolutePath(Path);
- return Changed | llvm::sys::path::remove_dots(Path);
-}
-
-/// Adjusts the given filename to only write out the portion of the
-/// filename that is not part of the system root directory.
-///
-/// \param Filename the file name to adjust.
-///
-/// \param BaseDir When non-NULL, the PCH file is a relocatable AST file and
-/// the returned filename will be adjusted by this root directory.
-///
-/// \returns either the original filename (if it needs no adjustment) or the
-/// adjusted filename (which points into the @p Filename parameter).
-static const char *
-adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) {
- assert(Filename && "No file name to adjust?");
-
- if (BaseDir.empty())
- return Filename;
-
- // Verify that the filename and the system root have the same prefix.
- unsigned Pos = 0;
- for (; Filename[Pos] && Pos < BaseDir.size(); ++Pos)
- if (Filename[Pos] != BaseDir[Pos])
- return Filename; // Prefixes don't match.
-
- // We hit the end of the filename before we hit the end of the system root.
- if (!Filename[Pos])
- return Filename;
-
- // If there's not a path separator at the end of the base directory nor
- // immediately after it, then this isn't within the base directory.
- if (!llvm::sys::path::is_separator(Filename[Pos])) {
- if (!llvm::sys::path::is_separator(BaseDir.back()))
- return Filename;
- } else {
- // If the file name has a '/' at the current position, skip over the '/'.
- // We distinguish relative paths from absolute paths by the
- // absence of '/' at the beginning of relative paths.
- //
- // FIXME: This is wrong. We distinguish them by asking if the path is
- // absolute, which isn't the same thing. And there might be multiple '/'s
- // in a row. Use a better mechanism to indicate whether we have emitted an
- // absolute or relative path.
- ++Pos;
- }
-
- return Filename + Pos;
-}
-
-ASTFileSignature ASTWriter::createSignature(StringRef Bytes) {
- // Calculate the hash till start of UNHASHED_CONTROL_BLOCK.
- llvm::SHA1 Hasher;
- Hasher.update(ArrayRef<uint8_t>(Bytes.bytes_begin(), Bytes.size()));
- auto Hash = Hasher.result();
-
- // Convert to an array [5*i32].
- ASTFileSignature Signature;
- auto LShift = [&](unsigned char Val, unsigned Shift) {
- return (uint32_t)Val << Shift;
- };
- for (int I = 0; I != 5; ++I)
- Signature[I] = LShift(Hash[I * 4 + 0], 24) | LShift(Hash[I * 4 + 1], 16) |
- LShift(Hash[I * 4 + 2], 8) | LShift(Hash[I * 4 + 3], 0);
-
- return Signature;
-}
-
-ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
- ASTContext &Context) {
- // Flush first to prepare the PCM hash (signature).
- Stream.FlushToWord();
- auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3;
-
- // Enter the block and prepare to write records.
- RecordData Record;
- Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5);
-
- // For implicit modules, write the hash of the PCM as its signature.
- ASTFileSignature Signature;
- if (WritingModule &&
- PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) {
- Signature = createSignature(StringRef(Buffer.begin(), StartOfUnhashedControl));
- Record.append(Signature.begin(), Signature.end());
- Stream.EmitRecord(SIGNATURE, Record);
- Record.clear();
- }
-
- // Diagnostic options.
- const auto &Diags = Context.getDiagnostics();
- const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
-#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
- Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
-#include "clang/Basic/DiagnosticOptions.def"
- Record.push_back(DiagOpts.Warnings.size());
- for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
- AddString(DiagOpts.Warnings[I], Record);
- Record.push_back(DiagOpts.Remarks.size());
- for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
- AddString(DiagOpts.Remarks[I], Record);
- // Note: we don't serialize the log or serialization file names, because they
- // are generally transient files and will almost always be overridden.
- Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
-
- // Write out the diagnostic/pragma mappings.
- WritePragmaDiagnosticMappings(Diags, /* IsModule = */ WritingModule);
-
- // Leave the options block.
- Stream.ExitBlock();
- return Signature;
-}
-
-/// Write the control block.
-void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
- StringRef isysroot,
- const std::string &OutputFile) {
- using namespace llvm;
-
- Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
- RecordData Record;
-
- // Metadata
- auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>();
- MetadataAbbrev->Add(BitCodeAbbrevOp(METADATA));
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Major
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Minor
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang maj.
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang min.
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Timestamps
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PCHHasObjectFile
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Errors
- MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
- unsigned MetadataAbbrevCode = Stream.EmitAbbrev(std::move(MetadataAbbrev));
- assert((!WritingModule || isysroot.empty()) &&
- "writing module as a relocatable PCH?");
- {
- RecordData::value_type Record[] = {
- METADATA,
- VERSION_MAJOR,
- VERSION_MINOR,
- CLANG_VERSION_MAJOR,
- CLANG_VERSION_MINOR,
- !isysroot.empty(),
- IncludeTimestamps,
- Context.getLangOpts().BuildingPCHWithObjectFile,
- ASTHasCompilerErrors};
- Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
- getClangFullRepositoryVersion());
- }
-
- if (WritingModule) {
- // Module name
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
- RecordData::value_type Record[] = {MODULE_NAME};
- Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
- }
-
- if (WritingModule && WritingModule->Directory) {
- SmallString<128> BaseDir(WritingModule->Directory->getName());
- cleanPathForOutput(Context.getSourceManager().getFileManager(), BaseDir);
-
- // If the home of the module is the current working directory, then we
- // want to pick up the cwd of the build process loading the module, not
- // our cwd, when we load this module.
- if (!PP.getHeaderSearchInfo()
- .getHeaderSearchOpts()
- .ModuleMapFileHomeIsCwd ||
- WritingModule->Directory->getName() != StringRef(".")) {
- // Module directory.
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory
- unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
-
- RecordData::value_type Record[] = {MODULE_DIRECTORY};
- Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir);
- }
-
- // Write out all other paths relative to the base directory if possible.
- BaseDirectory.assign(BaseDir.begin(), BaseDir.end());
- } else if (!isysroot.empty()) {
- // Write out paths relative to the sysroot if possible.
- BaseDirectory = isysroot;
- }
-
- // Module map file
- if (WritingModule && WritingModule->Kind == Module::ModuleMapModule) {
- Record.clear();
-
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- AddPath(WritingModule->PresumedModuleMapFile.empty()
- ? Map.getModuleMapFileForUniquing(WritingModule)->getName()
- : StringRef(WritingModule->PresumedModuleMapFile),
- Record);
-
- // Additional module map files.
- if (auto *AdditionalModMaps =
- Map.getAdditionalModuleMapFiles(WritingModule)) {
- Record.push_back(AdditionalModMaps->size());
- for (const FileEntry *F : *AdditionalModMaps)
- AddPath(F->getName(), Record);
- } else {
- Record.push_back(0);
- }
-
- Stream.EmitRecord(MODULE_MAP_FILE, Record);
- }
-
- // Imports
- if (Chain) {
- serialization::ModuleManager &Mgr = Chain->getModuleManager();
- Record.clear();
-
- for (ModuleFile &M : Mgr) {
- // Skip modules that weren't directly imported.
- if (!M.isDirectlyImported())
- continue;
-
- Record.push_back((unsigned)M.Kind); // FIXME: Stable encoding
- AddSourceLocation(M.ImportLoc, Record);
-
- // If we have calculated signature, there is no need to store
- // the size or timestamp.
- Record.push_back(M.Signature ? 0 : M.File->getSize());
- Record.push_back(M.Signature ? 0 : getTimestampForOutput(M.File));
-
- for (auto I : M.Signature)
- Record.push_back(I);
-
- AddString(M.ModuleName, Record);
- AddPath(M.FileName, Record);
- }
- Stream.EmitRecord(IMPORTS, Record);
- }
-
- // Write the options block.
- Stream.EnterSubblock(OPTIONS_BLOCK_ID, 4);
-
- // Language options.
- Record.clear();
- const LangOptions &LangOpts = Context.getLangOpts();
-#define LANGOPT(Name, Bits, Default, Description) \
- Record.push_back(LangOpts.Name);
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
-#include "clang/Basic/LangOptions.def"
-#define SANITIZER(NAME, ID) \
- Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
-#include "clang/Basic/Sanitizers.def"
-
- Record.push_back(LangOpts.ModuleFeatures.size());
- for (StringRef Feature : LangOpts.ModuleFeatures)
- AddString(Feature, Record);
-
- Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind());
- AddVersionTuple(LangOpts.ObjCRuntime.getVersion(), Record);
-
- AddString(LangOpts.CurrentModule, Record);
-
- // Comment options.
- Record.push_back(LangOpts.CommentOpts.BlockCommandNames.size());
- for (const auto &I : LangOpts.CommentOpts.BlockCommandNames) {
- AddString(I, Record);
- }
- Record.push_back(LangOpts.CommentOpts.ParseAllComments);
-
- // OpenMP offloading options.
- Record.push_back(LangOpts.OMPTargetTriples.size());
- for (auto &T : LangOpts.OMPTargetTriples)
- AddString(T.getTriple(), Record);
-
- AddString(LangOpts.OMPHostIRFile, Record);
-
- Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
-
- // Target options.
- Record.clear();
- const TargetInfo &Target = Context.getTargetInfo();
- const TargetOptions &TargetOpts = Target.getTargetOpts();
- AddString(TargetOpts.Triple, Record);
- AddString(TargetOpts.CPU, Record);
- AddString(TargetOpts.ABI, Record);
- Record.push_back(TargetOpts.FeaturesAsWritten.size());
- for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); I != N; ++I) {
- AddString(TargetOpts.FeaturesAsWritten[I], Record);
- }
- Record.push_back(TargetOpts.Features.size());
- for (unsigned I = 0, N = TargetOpts.Features.size(); I != N; ++I) {
- AddString(TargetOpts.Features[I], Record);
- }
- Stream.EmitRecord(TARGET_OPTIONS, Record);
-
- // File system options.
- Record.clear();
- const FileSystemOptions &FSOpts =
- Context.getSourceManager().getFileManager().getFileSystemOpts();
- AddString(FSOpts.WorkingDir, Record);
- Stream.EmitRecord(FILE_SYSTEM_OPTIONS, Record);
-
- // Header search options.
- Record.clear();
- const HeaderSearchOptions &HSOpts
- = PP.getHeaderSearchInfo().getHeaderSearchOpts();
- AddString(HSOpts.Sysroot, Record);
-
- // Include entries.
- Record.push_back(HSOpts.UserEntries.size());
- for (unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) {
- const HeaderSearchOptions::Entry &Entry = HSOpts.UserEntries[I];
- AddString(Entry.Path, Record);
- Record.push_back(static_cast<unsigned>(Entry.Group));
- Record.push_back(Entry.IsFramework);
- Record.push_back(Entry.IgnoreSysRoot);
- }
-
- // System header prefixes.
- Record.push_back(HSOpts.SystemHeaderPrefixes.size());
- for (unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) {
- AddString(HSOpts.SystemHeaderPrefixes[I].Prefix, Record);
- Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
- }
-
- AddString(HSOpts.ResourceDir, Record);
- AddString(HSOpts.ModuleCachePath, Record);
- AddString(HSOpts.ModuleUserBuildPath, Record);
- Record.push_back(HSOpts.DisableModuleHash);
- Record.push_back(HSOpts.ImplicitModuleMaps);
- Record.push_back(HSOpts.ModuleMapFileHomeIsCwd);
- Record.push_back(HSOpts.UseBuiltinIncludes);
- Record.push_back(HSOpts.UseStandardSystemIncludes);
- Record.push_back(HSOpts.UseStandardCXXIncludes);
- Record.push_back(HSOpts.UseLibcxx);
- // Write out the specific module cache path that contains the module files.
- AddString(PP.getHeaderSearchInfo().getModuleCachePath(), Record);
- Stream.EmitRecord(HEADER_SEARCH_OPTIONS, Record);
-
- // Preprocessor options.
- Record.clear();
- const PreprocessorOptions &PPOpts = PP.getPreprocessorOpts();
-
- // Macro definitions.
- Record.push_back(PPOpts.Macros.size());
- for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
- AddString(PPOpts.Macros[I].first, Record);
- Record.push_back(PPOpts.Macros[I].second);
- }
-
- // Includes
- Record.push_back(PPOpts.Includes.size());
- for (unsigned I = 0, N = PPOpts.Includes.size(); I != N; ++I)
- AddString(PPOpts.Includes[I], Record);
-
- // Macro includes
- Record.push_back(PPOpts.MacroIncludes.size());
- for (unsigned I = 0, N = PPOpts.MacroIncludes.size(); I != N; ++I)
- AddString(PPOpts.MacroIncludes[I], Record);
-
- Record.push_back(PPOpts.UsePredefines);
- // Detailed record is important since it is used for the module cache hash.
- Record.push_back(PPOpts.DetailedRecord);
- AddString(PPOpts.ImplicitPCHInclude, Record);
- Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary));
- Stream.EmitRecord(PREPROCESSOR_OPTIONS, Record);
-
- // Leave the options block.
- Stream.ExitBlock();
-
- // Original file name and file ID
- SourceManager &SM = Context.getSourceManager();
- if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
- auto FileAbbrev = std::make_shared<BitCodeAbbrev>();
- FileAbbrev->Add(BitCodeAbbrevOp(ORIGINAL_FILE));
- FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File ID
- FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
- unsigned FileAbbrevCode = Stream.EmitAbbrev(std::move(FileAbbrev));
-
- Record.clear();
- Record.push_back(ORIGINAL_FILE);
- Record.push_back(SM.getMainFileID().getOpaqueValue());
- EmitRecordWithPath(FileAbbrevCode, Record, MainFile->getName());
- }
-
- Record.clear();
- Record.push_back(SM.getMainFileID().getOpaqueValue());
- Stream.EmitRecord(ORIGINAL_FILE_ID, Record);
-
- // Original PCH directory
- if (!OutputFile.empty() && OutputFile != "-") {
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
- unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
-
- SmallString<128> OutputPath(OutputFile);
-
- SM.getFileManager().makeAbsolutePath(OutputPath);
- StringRef origDir = llvm::sys::path::parent_path(OutputPath);
-
- RecordData::value_type Record[] = {ORIGINAL_PCH_DIR};
- Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir);
- }
-
- WriteInputFiles(Context.SourceMgr,
- PP.getHeaderSearchInfo().getHeaderSearchOpts(),
- PP.getLangOpts().Modules);
- Stream.ExitBlock();
-}
-
-namespace {
-
-/// An input file.
-struct InputFileEntry {
- const FileEntry *File;
- bool IsSystemFile;
- bool IsTransient;
- bool BufferOverridden;
- bool IsTopLevelModuleMap;
-};
-
-} // namespace
-
-void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
- HeaderSearchOptions &HSOpts,
- bool Modules) {
- using namespace llvm;
-
- Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
-
- // Create input-file abbreviation.
- auto IFAbbrev = std::make_shared<BitCodeAbbrev>();
- IFAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE));
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Overridden
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Transient
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Module map
- IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
- unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev));
-
- // Get all ContentCache objects for files, sorted by whether the file is a
- // system one or not. System files go at the back, users files at the front.
- std::deque<InputFileEntry> SortedFiles;
- for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
- // Get this source location entry.
- const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
- assert(&SourceMgr.getSLocEntry(FileID::get(I)) == SLoc);
-
- // We only care about file entries that were not overridden.
- if (!SLoc->isFile())
- continue;
- const SrcMgr::FileInfo &File = SLoc->getFile();
- const SrcMgr::ContentCache *Cache = File.getContentCache();
- if (!Cache->OrigEntry)
- continue;
-
- InputFileEntry Entry;
- Entry.File = Cache->OrigEntry;
- Entry.IsSystemFile = Cache->IsSystemFile;
- Entry.IsTransient = Cache->IsTransient;
- Entry.BufferOverridden = Cache->BufferOverridden;
- Entry.IsTopLevelModuleMap = isModuleMap(File.getFileCharacteristic()) &&
- File.getIncludeLoc().isInvalid();
- if (Cache->IsSystemFile)
- SortedFiles.push_back(Entry);
- else
- SortedFiles.push_front(Entry);
- }
-
- unsigned UserFilesNum = 0;
- // Write out all of the input files.
- std::vector<uint64_t> InputFileOffsets;
- for (const auto &Entry : SortedFiles) {
- uint32_t &InputFileID = InputFileIDs[Entry.File];
- if (InputFileID != 0)
- continue; // already recorded this file.
-
- // Record this entry's offset.
- InputFileOffsets.push_back(Stream.GetCurrentBitNo());
-
- InputFileID = InputFileOffsets.size();
-
- if (!Entry.IsSystemFile)
- ++UserFilesNum;
-
- // Emit size/modification time for this file.
- // And whether this file was overridden.
- RecordData::value_type Record[] = {
- INPUT_FILE,
- InputFileOffsets.size(),
- (uint64_t)Entry.File->getSize(),
- (uint64_t)getTimestampForOutput(Entry.File),
- Entry.BufferOverridden,
- Entry.IsTransient,
- Entry.IsTopLevelModuleMap};
-
- EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName());
- }
-
- Stream.ExitBlock();
-
- // Create input file offsets abbreviation.
- auto OffsetsAbbrev = std::make_shared<BitCodeAbbrev>();
- OffsetsAbbrev->Add(BitCodeAbbrevOp(INPUT_FILE_OFFSETS));
- OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # input files
- OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # non-system
- // input files
- OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Array
- unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(std::move(OffsetsAbbrev));
-
- // Write input file offsets.
- RecordData::value_type Record[] = {INPUT_FILE_OFFSETS,
- InputFileOffsets.size(), UserFilesNum};
- Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, bytes(InputFileOffsets));
-}
-
-//===----------------------------------------------------------------------===//
-// Source Manager Serialization
-//===----------------------------------------------------------------------===//
-
-/// Create an abbreviation for the SLocEntry that refers to a
-/// file.
-static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
- // FileEntry fields.
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Input File ID
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls
- return Stream.EmitAbbrev(std::move(Abbrev));
-}
-
-/// Create an abbreviation for the SLocEntry that refers to a
-/// buffer.
-static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
- return Stream.EmitAbbrev(std::move(Abbrev));
-}
-
-/// Create an abbreviation for the SLocEntry that refers to a
-/// buffer's blob.
-static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream,
- bool Compressed) {
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED
- : SM_SLOC_BUFFER_BLOB));
- if (Compressed)
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Uncompressed size
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
- return Stream.EmitAbbrev(std::move(Abbrev));
-}
-
-/// Create an abbreviation for the SLocEntry that refers to a macro
-/// expansion.
-static unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) {
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SM_SLOC_EXPANSION_ENTRY));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is token range
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length
- return Stream.EmitAbbrev(std::move(Abbrev));
-}
-
-namespace {
-
- // Trait used for the on-disk hash table of header search information.
- class HeaderFileInfoTrait {
- ASTWriter &Writer;
-
- // Keep track of the framework names we've used during serialization.
- SmallVector<char, 128> FrameworkStringData;
- llvm::StringMap<unsigned> FrameworkNameOffset;
-
- public:
- HeaderFileInfoTrait(ASTWriter &Writer) : Writer(Writer) {}
-
- struct key_type {
- StringRef Filename;
- off_t Size;
- time_t ModTime;
- };
- using key_type_ref = const key_type &;
-
- using UnresolvedModule =
- llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
-
- struct data_type {
- const HeaderFileInfo &HFI;
- ArrayRef<ModuleMap::KnownHeader> KnownHeaders;
- UnresolvedModule Unresolved;
- };
- using data_type_ref = const data_type &;
-
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- hash_value_type ComputeHash(key_type_ref key) {
- // The hash is based only on size/time of the file, so that the reader can
- // match even when symlinking or excess path elements ("foo/../", "../")
- // change the form of the name. However, complete path is still the key.
- return llvm::hash_combine(key.Size, key.ModTime);
- }
-
- std::pair<unsigned, unsigned>
- EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
- LE.write<uint16_t>(KeyLen);
- unsigned DataLen = 1 + 2 + 4 + 4;
- for (auto ModInfo : Data.KnownHeaders)
- if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
- DataLen += 4;
- if (Data.Unresolved.getPointer())
- DataLen += 4;
- LE.write<uint8_t>(DataLen);
- return std::make_pair(KeyLen, DataLen);
- }
-
- void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- LE.write<uint64_t>(key.Size);
- KeyLen -= 8;
- LE.write<uint64_t>(key.ModTime);
- KeyLen -= 8;
- Out.write(key.Filename.data(), KeyLen);
- }
-
- void EmitData(raw_ostream &Out, key_type_ref key,
- data_type_ref Data, unsigned DataLen) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- uint64_t Start = Out.tell(); (void)Start;
-
- unsigned char Flags = (Data.HFI.isImport << 5)
- | (Data.HFI.isPragmaOnce << 4)
- | (Data.HFI.DirInfo << 1)
- | Data.HFI.IndexHeaderMapHeader;
- LE.write<uint8_t>(Flags);
- LE.write<uint16_t>(Data.HFI.NumIncludes);
-
- if (!Data.HFI.ControllingMacro)
- LE.write<uint32_t>(Data.HFI.ControllingMacroID);
- else
- LE.write<uint32_t>(Writer.getIdentifierRef(Data.HFI.ControllingMacro));
-
- unsigned Offset = 0;
- if (!Data.HFI.Framework.empty()) {
- // If this header refers into a framework, save the framework name.
- llvm::StringMap<unsigned>::iterator Pos
- = FrameworkNameOffset.find(Data.HFI.Framework);
- if (Pos == FrameworkNameOffset.end()) {
- Offset = FrameworkStringData.size() + 1;
- FrameworkStringData.append(Data.HFI.Framework.begin(),
- Data.HFI.Framework.end());
- FrameworkStringData.push_back(0);
-
- FrameworkNameOffset[Data.HFI.Framework] = Offset;
- } else
- Offset = Pos->second;
- }
- LE.write<uint32_t>(Offset);
-
- auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
- if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
- uint32_t Value = (ModID << 2) | (unsigned)Role;
- assert((Value >> 2) == ModID && "overflow in header module info");
- LE.write<uint32_t>(Value);
- }
- };
-
- // FIXME: If the header is excluded, we should write out some
- // record of that fact.
- for (auto ModInfo : Data.KnownHeaders)
- EmitModule(ModInfo.getModule(), ModInfo.getRole());
- if (Data.Unresolved.getPointer())
- EmitModule(Data.Unresolved.getPointer(), Data.Unresolved.getInt());
-
- assert(Out.tell() - Start == DataLen && "Wrong data length");
- }
-
- const char *strings_begin() const { return FrameworkStringData.begin(); }
- const char *strings_end() const { return FrameworkStringData.end(); }
- };
-
-} // namespace
-
-/// Write the header search block for the list of files that
-///
-/// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
- HeaderFileInfoTrait GeneratorTrait(*this);
- llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
- SmallVector<const char *, 4> SavedStrings;
- unsigned NumHeaderSearchEntries = 0;
-
- // Find all unresolved headers for the current module. We generally will
- // have resolved them before we get here, but not necessarily: we might be
- // compiling a preprocessed module, where there is no requirement for the
- // original files to exist any more.
- const HeaderFileInfo Empty; // So we can take a reference.
- if (WritingModule) {
- llvm::SmallVector<Module *, 16> Worklist(1, WritingModule);
- while (!Worklist.empty()) {
- Module *M = Worklist.pop_back_val();
- if (!M->isAvailable())
- continue;
-
- // Map to disk files where possible, to pick up any missing stat
- // information. This also means we don't need to check the unresolved
- // headers list when emitting resolved headers in the first loop below.
- // FIXME: It'd be preferable to avoid doing this if we were given
- // sufficient stat information in the module map.
- HS.getModuleMap().resolveHeaderDirectives(M);
-
- // If the file didn't exist, we can still create a module if we were given
- // enough information in the module map.
- for (auto U : M->MissingHeaders) {
- // Check that we were given enough information to build a module
- // without this file existing on disk.
- if (!U.Size || (!U.ModTime && IncludeTimestamps)) {
- PP->Diag(U.FileNameLoc, diag::err_module_no_size_mtime_for_header)
- << WritingModule->getFullModuleName() << U.Size.hasValue()
- << U.FileName;
- continue;
- }
-
- // Form the effective relative pathname for the file.
- SmallString<128> Filename(M->Directory->getName());
- llvm::sys::path::append(Filename, U.FileName);
- PreparePathForOutput(Filename);
-
- StringRef FilenameDup = strdup(Filename.c_str());
- SavedStrings.push_back(FilenameDup.data());
-
- HeaderFileInfoTrait::key_type Key = {
- FilenameDup, *U.Size, IncludeTimestamps ? *U.ModTime : 0
- };
- HeaderFileInfoTrait::data_type Data = {
- Empty, {}, {M, ModuleMap::headerKindToRole(U.Kind)}
- };
- // FIXME: Deal with cases where there are multiple unresolved header
- // directives in different submodules for the same header.
- Generator.insert(Key, Data, GeneratorTrait);
- ++NumHeaderSearchEntries;
- }
-
- Worklist.append(M->submodule_begin(), M->submodule_end());
- }
- }
-
- SmallVector<const FileEntry *, 16> FilesByUID;
- HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
-
- if (FilesByUID.size() > HS.header_file_size())
- FilesByUID.resize(HS.header_file_size());
-
- for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
- const FileEntry *File = FilesByUID[UID];
- if (!File)
- continue;
-
- // Get the file info. This will load info from the external source if
- // necessary. Skip emitting this file if we have no information on it
- // as a header file (in which case HFI will be null) or if it hasn't
- // changed since it was loaded. Also skip it if it's for a modular header
- // from a different module; in that case, we rely on the module(s)
- // containing the header to provide this information.
- const HeaderFileInfo *HFI =
- HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
- if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
- continue;
-
- // Massage the file path into an appropriate form.
- StringRef Filename = File->getName();
- SmallString<128> FilenameTmp(Filename);
- if (PreparePathForOutput(FilenameTmp)) {
- // If we performed any translation on the file name at all, we need to
- // save this string, since the generator will refer to it later.
- Filename = StringRef(strdup(FilenameTmp.c_str()));
- SavedStrings.push_back(Filename.data());
- }
-
- HeaderFileInfoTrait::key_type Key = {
- Filename, File->getSize(), getTimestampForOutput(File)
- };
- HeaderFileInfoTrait::data_type Data = {
- *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
- };
- Generator.insert(Key, Data, GeneratorTrait);
- ++NumHeaderSearchEntries;
- }
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> TableData;
- uint32_t BucketOffset;
- {
- using namespace llvm::support;
-
- llvm::raw_svector_ostream Out(TableData);
- // Make sure that no bucket is at offset 0
- endian::write<uint32_t>(Out, 0, little);
- BucketOffset = Generator.Emit(Out, GeneratorTrait);
- }
-
- // Create a blob abbreviation
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(HEADER_SEARCH_TABLE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned TableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- // Write the header search table
- RecordData::value_type Record[] = {HEADER_SEARCH_TABLE, BucketOffset,
- NumHeaderSearchEntries, TableData.size()};
- TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end());
- Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData);
-
- // Free all of the strings we had to duplicate.
- for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I)
- free(const_cast<char *>(SavedStrings[I]));
-}
-
-static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
- unsigned SLocBufferBlobCompressedAbbrv,
- unsigned SLocBufferBlobAbbrv) {
- using RecordDataType = ASTWriter::RecordData::value_type;
-
- // Compress the buffer if possible. We expect that almost all PCM
- // consumers will not want its contents.
- SmallString<0> CompressedBuffer;
- if (llvm::zlib::isAvailable()) {
- llvm::Error E = llvm::zlib::compress(Blob.drop_back(1), CompressedBuffer);
- if (!E) {
- RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED,
- Blob.size() - 1};
- Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
- CompressedBuffer);
- return;
- }
- llvm::consumeError(std::move(E));
- }
-
- RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB};
- Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob);
-}
-
-/// Writes the block containing the serialized form of the
-/// source manager.
-///
-/// TODO: We should probably use an on-disk hash table (stored in a
-/// blob), indexed based on the file name, so that we only create
-/// entries for files that we actually need. In the common case (no
-/// errors), we probably won't have to create file entries for any of
-/// the files in the AST.
-void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
- const Preprocessor &PP) {
- RecordData Record;
-
- // Enter the source manager block.
- Stream.EnterSubblock(SOURCE_MANAGER_BLOCK_ID, 4);
-
- // Abbreviations for the various kinds of source-location entries.
- unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
- unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
- unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream, false);
- unsigned SLocBufferBlobCompressedAbbrv =
- CreateSLocBufferBlobAbbrev(Stream, true);
- unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream);
-
- // Write out the source location entry table. We skip the first
- // entry, which is always the same dummy entry.
- std::vector<uint32_t> SLocEntryOffsets;
- RecordData PreloadSLocs;
- SLocEntryOffsets.reserve(SourceMgr.local_sloc_entry_size() - 1);
- for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size();
- I != N; ++I) {
- // Get this source location entry.
- const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(I);
- FileID FID = FileID::get(I);
- assert(&SourceMgr.getSLocEntry(FID) == SLoc);
-
- // Record the offset of this source-location entry.
- SLocEntryOffsets.push_back(Stream.GetCurrentBitNo());
-
- // Figure out which record code to use.
- unsigned Code;
- if (SLoc->isFile()) {
- const SrcMgr::ContentCache *Cache = SLoc->getFile().getContentCache();
- if (Cache->OrigEntry) {
- Code = SM_SLOC_FILE_ENTRY;
- } else
- Code = SM_SLOC_BUFFER_ENTRY;
- } else
- Code = SM_SLOC_EXPANSION_ENTRY;
- Record.clear();
- Record.push_back(Code);
-
- // Starting offset of this entry within this module, so skip the dummy.
- Record.push_back(SLoc->getOffset() - 2);
- if (SLoc->isFile()) {
- const SrcMgr::FileInfo &File = SLoc->getFile();
- AddSourceLocation(File.getIncludeLoc(), Record);
- Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
- Record.push_back(File.hasLineDirectives());
-
- const SrcMgr::ContentCache *Content = File.getContentCache();
- bool EmitBlob = false;
- if (Content->OrigEntry) {
- assert(Content->OrigEntry == Content->ContentsEntry &&
- "Writing to AST an overridden file is not supported");
-
- // The source location entry is a file. Emit input file ID.
- assert(InputFileIDs[Content->OrigEntry] != 0 && "Missed file entry");
- Record.push_back(InputFileIDs[Content->OrigEntry]);
-
- Record.push_back(File.NumCreatedFIDs);
-
- FileDeclIDsTy::iterator FDI = FileDeclIDs.find(FID);
- if (FDI != FileDeclIDs.end()) {
- Record.push_back(FDI->second->FirstDeclIndex);
- Record.push_back(FDI->second->DeclIDs.size());
- } else {
- Record.push_back(0);
- Record.push_back(0);
- }
-
- Stream.EmitRecordWithAbbrev(SLocFileAbbrv, Record);
-
- if (Content->BufferOverridden || Content->IsTransient)
- EmitBlob = true;
- } else {
- // The source location entry is a buffer. The blob associated
- // with this entry contains the contents of the buffer.
-
- // We add one to the size so that we capture the trailing NULL
- // that is required by llvm::MemoryBuffer::getMemBuffer (on
- // the reader side).
- const llvm::MemoryBuffer *Buffer
- = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
- StringRef Name = Buffer->getBufferIdentifier();
- Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
- StringRef(Name.data(), Name.size() + 1));
- EmitBlob = true;
-
- if (Name == "<built-in>")
- PreloadSLocs.push_back(SLocEntryOffsets.size());
- }
-
- if (EmitBlob) {
- // Include the implicit terminating null character in the on-disk buffer
- // if we're writing it uncompressed.
- const llvm::MemoryBuffer *Buffer =
- Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
- StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1);
- emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv,
- SLocBufferBlobAbbrv);
- }
- } else {
- // The source location entry is a macro expansion.
- const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion();
- AddSourceLocation(Expansion.getSpellingLoc(), Record);
- AddSourceLocation(Expansion.getExpansionLocStart(), Record);
- AddSourceLocation(Expansion.isMacroArgExpansion()
- ? SourceLocation()
- : Expansion.getExpansionLocEnd(),
- Record);
- Record.push_back(Expansion.isExpansionTokenRange());
-
- // Compute the token length for this macro expansion.
- unsigned NextOffset = SourceMgr.getNextLocalOffset();
- if (I + 1 != N)
- NextOffset = SourceMgr.getLocalSLocEntry(I + 1).getOffset();
- Record.push_back(NextOffset - SLoc->getOffset() - 1);
- Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv, Record);
- }
- }
-
- Stream.ExitBlock();
-
- if (SLocEntryOffsets.empty())
- return;
-
- // Write the source-location offsets table into the AST block. This
- // table is used for lazily loading source-location information.
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
- unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- {
- RecordData::value_type Record[] = {
- SOURCE_LOCATION_OFFSETS, SLocEntryOffsets.size(),
- SourceMgr.getNextLocalOffset() - 1 /* skip dummy */};
- Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
- bytes(SLocEntryOffsets));
- }
- // Write the source location entry preloads array, telling the AST
- // reader which source locations entries it should load eagerly.
- Stream.EmitRecord(SOURCE_LOCATION_PRELOADS, PreloadSLocs);
-
- // Write the line table. It depends on remapping working, so it must come
- // after the source location offsets.
- if (SourceMgr.hasLineTable()) {
- LineTableInfo &LineTable = SourceMgr.getLineTable();
-
- Record.clear();
-
- // Emit the needed file names.
- llvm::DenseMap<int, int> FilenameMap;
- FilenameMap[-1] = -1; // For unspecified filenames.
- for (const auto &L : LineTable) {
- if (L.first.ID < 0)
- continue;
- for (auto &LE : L.second) {
- if (FilenameMap.insert(std::make_pair(LE.FilenameID,
- FilenameMap.size() - 1)).second)
- AddPath(LineTable.getFilename(LE.FilenameID), Record);
- }
- }
- Record.push_back(0);
-
- // Emit the line entries
- for (const auto &L : LineTable) {
- // Only emit entries for local files.
- if (L.first.ID < 0)
- continue;
-
- // Emit the file ID
- Record.push_back(L.first.ID);
-
- // Emit the line entries
- Record.push_back(L.second.size());
- for (const auto &LE : L.second) {
- Record.push_back(LE.FileOffset);
- Record.push_back(LE.LineNo);
- Record.push_back(FilenameMap[LE.FilenameID]);
- Record.push_back((unsigned)LE.FileKind);
- Record.push_back(LE.IncludeOffset);
- }
- }
-
- Stream.EmitRecord(SOURCE_MANAGER_LINE_TABLE, Record);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Serialization
-//===----------------------------------------------------------------------===//
-
-static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
- const Preprocessor &PP) {
- if (MacroInfo *MI = MD->getMacroInfo())
- if (MI->isBuiltinMacro())
- return true;
-
- if (IsModule) {
- SourceLocation Loc = MD->getLocation();
- if (Loc.isInvalid())
- return true;
- if (PP.getSourceManager().getFileID(Loc) == PP.getPredefinesFileID())
- return true;
- }
-
- return false;
-}
-
-/// Writes the block containing the serialized form of the
-/// preprocessor.
-void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
- PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
- if (PPRec)
- WritePreprocessorDetail(*PPRec);
-
- RecordData Record;
- RecordData ModuleMacroRecord;
-
- // If the preprocessor __COUNTER__ value has been bumped, remember it.
- if (PP.getCounterValue() != 0) {
- RecordData::value_type Record[] = {PP.getCounterValue()};
- Stream.EmitRecord(PP_COUNTER_VALUE, Record);
- }
-
- if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) {
- assert(!IsModule);
- auto SkipInfo = PP.getPreambleSkipInfo();
- if (SkipInfo.hasValue()) {
- Record.push_back(true);
- AddSourceLocation(SkipInfo->HashTokenLoc, Record);
- AddSourceLocation(SkipInfo->IfTokenLoc, Record);
- Record.push_back(SkipInfo->FoundNonSkipPortion);
- Record.push_back(SkipInfo->FoundElse);
- AddSourceLocation(SkipInfo->ElseLoc, Record);
- } else {
- Record.push_back(false);
- }
- for (const auto &Cond : PP.getPreambleConditionalStack()) {
- AddSourceLocation(Cond.IfLoc, Record);
- Record.push_back(Cond.WasSkipping);
- Record.push_back(Cond.FoundNonSkip);
- Record.push_back(Cond.FoundElse);
- }
- Stream.EmitRecord(PP_CONDITIONAL_STACK, Record);
- Record.clear();
- }
-
- // Enter the preprocessor block.
- Stream.EnterSubblock(PREPROCESSOR_BLOCK_ID, 3);
-
- // If the AST file contains __DATE__ or __TIME__ emit a warning about this.
- // FIXME: Include a location for the use, and say which one was used.
- if (PP.SawDateOrTime())
- PP.Diag(SourceLocation(), diag::warn_module_uses_date_time) << IsModule;
-
- // Loop over all the macro directives that are live at the end of the file,
- // emitting each to the PP section.
-
- // Construct the list of identifiers with macro directives that need to be
- // serialized.
- SmallVector<const IdentifierInfo *, 128> MacroIdentifiers;
- for (auto &Id : PP.getIdentifierTable())
- if (Id.second->hadMacroDefinition() &&
- (!Id.second->isFromAST() ||
- Id.second->hasChangedSinceDeserialization()))
- MacroIdentifiers.push_back(Id.second);
- // Sort the set of macro definitions that need to be serialized by the
- // name of the macro, to provide a stable ordering.
- llvm::sort(MacroIdentifiers, llvm::less_ptr<IdentifierInfo>());
-
- // Emit the macro directives as a list and associate the offset with the
- // identifier they belong to.
- for (const IdentifierInfo *Name : MacroIdentifiers) {
- MacroDirective *MD = PP.getLocalMacroDirectiveHistory(Name);
- auto StartOffset = Stream.GetCurrentBitNo();
-
- // Emit the macro directives in reverse source order.
- for (; MD; MD = MD->getPrevious()) {
- // Once we hit an ignored macro, we're done: the rest of the chain
- // will all be ignored macros.
- if (shouldIgnoreMacro(MD, IsModule, PP))
- break;
-
- AddSourceLocation(MD->getLocation(), Record);
- Record.push_back(MD->getKind());
- if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
- Record.push_back(getMacroRef(DefMD->getInfo(), Name));
- } else if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
- Record.push_back(VisMD->isPublic());
- }
- }
-
- // Write out any exported module macros.
- bool EmittedModuleMacros = false;
- // We write out exported module macros for PCH as well.
- auto Leafs = PP.getLeafModuleMacros(Name);
- SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
- llvm::DenseMap<ModuleMacro*, unsigned> Visits;
- while (!Worklist.empty()) {
- auto *Macro = Worklist.pop_back_val();
-
- // Emit a record indicating this submodule exports this macro.
- ModuleMacroRecord.push_back(
- getSubmoduleID(Macro->getOwningModule()));
- ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name));
- for (auto *M : Macro->overrides())
- ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
-
- Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
- ModuleMacroRecord.clear();
-
- // Enqueue overridden macros once we've visited all their ancestors.
- for (auto *M : Macro->overrides())
- if (++Visits[M] == M->getNumOverridingMacros())
- Worklist.push_back(M);
-
- EmittedModuleMacros = true;
- }
-
- if (Record.empty() && !EmittedModuleMacros)
- continue;
-
- IdentMacroDirectivesOffsetMap[Name] = StartOffset;
- Stream.EmitRecord(PP_MACRO_DIRECTIVE_HISTORY, Record);
- Record.clear();
- }
-
- /// Offsets of each of the macros into the bitstream, indexed by
- /// the local macro ID
- ///
- /// For each identifier that is associated with a macro, this map
- /// provides the offset into the bitstream where that macro is
- /// defined.
- std::vector<uint32_t> MacroOffsets;
-
- for (unsigned I = 0, N = MacroInfosToEmit.size(); I != N; ++I) {
- const IdentifierInfo *Name = MacroInfosToEmit[I].Name;
- MacroInfo *MI = MacroInfosToEmit[I].MI;
- MacroID ID = MacroInfosToEmit[I].ID;
-
- if (ID < FirstMacroID) {
- assert(0 && "Loaded MacroInfo entered MacroInfosToEmit ?");
- continue;
- }
-
- // Record the local offset of this macro.
- unsigned Index = ID - FirstMacroID;
- if (Index == MacroOffsets.size())
- MacroOffsets.push_back(Stream.GetCurrentBitNo());
- else {
- if (Index > MacroOffsets.size())
- MacroOffsets.resize(Index + 1);
-
- MacroOffsets[Index] = Stream.GetCurrentBitNo();
- }
-
- AddIdentifierRef(Name, Record);
- AddSourceLocation(MI->getDefinitionLoc(), Record);
- AddSourceLocation(MI->getDefinitionEndLoc(), Record);
- Record.push_back(MI->isUsed());
- Record.push_back(MI->isUsedForHeaderGuard());
- unsigned Code;
- if (MI->isObjectLike()) {
- Code = PP_MACRO_OBJECT_LIKE;
- } else {
- Code = PP_MACRO_FUNCTION_LIKE;
-
- Record.push_back(MI->isC99Varargs());
- Record.push_back(MI->isGNUVarargs());
- Record.push_back(MI->hasCommaPasting());
- Record.push_back(MI->getNumParams());
- for (const IdentifierInfo *Param : MI->params())
- AddIdentifierRef(Param, Record);
- }
-
- // If we have a detailed preprocessing record, record the macro definition
- // ID that corresponds to this macro.
- if (PPRec)
- Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
-
- Stream.EmitRecord(Code, Record);
- Record.clear();
-
- // Emit the tokens array.
- for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
- // Note that we know that the preprocessor does not have any annotation
- // tokens in it because they are created by the parser, and thus can't
- // be in a macro definition.
- const Token &Tok = MI->getReplacementToken(TokNo);
- AddToken(Tok, Record);
- Stream.EmitRecord(PP_TOKEN, Record);
- Record.clear();
- }
- ++NumMacros;
- }
-
- Stream.ExitBlock();
-
- // Write the offsets table for macro IDs.
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
-
- unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- {
- RecordData::value_type Record[] = {MACRO_OFFSET, MacroOffsets.size(),
- FirstMacroID - NUM_PREDEF_MACRO_IDS};
- Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets));
- }
-}
-
-void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
- if (PPRec.local_begin() == PPRec.local_end())
- return;
-
- SmallVector<PPEntityOffset, 64> PreprocessedEntityOffsets;
-
- // Enter the preprocessor block.
- Stream.EnterSubblock(PREPROCESSOR_DETAIL_BLOCK_ID, 3);
-
- // If the preprocessor has a preprocessing record, emit it.
- unsigned NumPreprocessingRecords = 0;
- using namespace llvm;
-
- // Set up the abbreviation for
- unsigned InclusionAbbrev = 0;
- {
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // imported module
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- }
-
- unsigned FirstPreprocessorEntityID
- = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0)
- + NUM_PREDEF_PP_ENTITY_IDS;
- unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
- RecordData Record;
- for (PreprocessingRecord::iterator E = PPRec.local_begin(),
- EEnd = PPRec.local_end();
- E != EEnd;
- (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
- Record.clear();
-
- PreprocessedEntityOffsets.push_back(
- PPEntityOffset((*E)->getSourceRange(), Stream.GetCurrentBitNo()));
-
- if (auto *MD = dyn_cast<MacroDefinitionRecord>(*E)) {
- // Record this macro definition's ID.
- MacroDefinitions[MD] = NextPreprocessorEntityID;
-
- AddIdentifierRef(MD->getName(), Record);
- Stream.EmitRecord(PPD_MACRO_DEFINITION, Record);
- continue;
- }
-
- if (auto *ME = dyn_cast<MacroExpansion>(*E)) {
- Record.push_back(ME->isBuiltinMacro());
- if (ME->isBuiltinMacro())
- AddIdentifierRef(ME->getName(), Record);
- else
- Record.push_back(MacroDefinitions[ME->getDefinition()]);
- Stream.EmitRecord(PPD_MACRO_EXPANSION, Record);
- continue;
- }
-
- if (auto *ID = dyn_cast<InclusionDirective>(*E)) {
- Record.push_back(PPD_INCLUSION_DIRECTIVE);
- Record.push_back(ID->getFileName().size());
- Record.push_back(ID->wasInQuotes());
- Record.push_back(static_cast<unsigned>(ID->getKind()));
- Record.push_back(ID->importedModule());
- SmallString<64> Buffer;
- Buffer += ID->getFileName();
- // Check that the FileEntry is not null because it was not resolved and
- // we create a PCH even with compiler errors.
- if (ID->getFile())
- Buffer += ID->getFile()->getName();
- Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer);
- continue;
- }
-
- llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter");
- }
- Stream.ExitBlock();
-
- // Write the offsets table for the preprocessing record.
- if (NumPreprocessingRecords > 0) {
- assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords);
-
- // Write the offsets table for identifier IDs.
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first pp entity
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- RecordData::value_type Record[] = {PPD_ENTITIES_OFFSETS,
- FirstPreprocessorEntityID -
- NUM_PREDEF_PP_ENTITY_IDS};
- Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record,
- bytes(PreprocessedEntityOffsets));
- }
-
- // Write the skipped region table for the preprocessing record.
- ArrayRef<SourceRange> SkippedRanges = PPRec.getSkippedRanges();
- if (SkippedRanges.size() > 0) {
- std::vector<PPSkippedRange> SerializedSkippedRanges;
- SerializedSkippedRanges.reserve(SkippedRanges.size());
- for (auto const& Range : SkippedRanges)
- SerializedSkippedRanges.emplace_back(Range);
-
- using namespace llvm;
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(PPD_SKIPPED_RANGES));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned PPESkippedRangeAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Record.clear();
- Record.push_back(PPD_SKIPPED_RANGES);
- Stream.EmitRecordWithBlob(PPESkippedRangeAbbrev, Record,
- bytes(SerializedSkippedRanges));
- }
-}
-
-unsigned ASTWriter::getLocalOrImportedSubmoduleID(Module *Mod) {
- if (!Mod)
- return 0;
-
- llvm::DenseMap<Module *, unsigned>::iterator Known = SubmoduleIDs.find(Mod);
- if (Known != SubmoduleIDs.end())
- return Known->second;
-
- auto *Top = Mod->getTopLevelModule();
- if (Top != WritingModule &&
- (getLangOpts().CompilingPCH ||
- !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule))))
- return 0;
-
- return SubmoduleIDs[Mod] = NextSubmoduleID++;
-}
-
-unsigned ASTWriter::getSubmoduleID(Module *Mod) {
- // FIXME: This can easily happen, if we have a reference to a submodule that
- // did not result in us loading a module file for that submodule. For
- // instance, a cross-top-level-module 'conflict' declaration will hit this.
- unsigned ID = getLocalOrImportedSubmoduleID(Mod);
- assert((ID || !Mod) &&
- "asked for module ID for non-local, non-imported module");
- return ID;
-}
-
-/// Compute the number of modules within the given tree (including the
-/// given module).
-static unsigned getNumberOfModules(Module *Mod) {
- unsigned ChildModules = 0;
- for (auto Sub = Mod->submodule_begin(), SubEnd = Mod->submodule_end();
- Sub != SubEnd; ++Sub)
- ChildModules += getNumberOfModules(*Sub);
-
- return ChildModules + 1;
-}
-
-void ASTWriter::WriteSubmodules(Module *WritingModule) {
- // Enter the submodule description block.
- Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5);
-
- // Write the abbreviations needed for the submodules block.
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Kind
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExternC
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConfigMacrosExh...
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModuleMapIsPriv...
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned DefinitionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_HEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned UmbrellaAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned HeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TOPHEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned TopHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA_DIR));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_REQUIRES));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // State
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Feature
- unsigned RequiresAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXCLUDED_HEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TEXTUAL_HEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
- unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFIG_MACRO));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
- unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_CONFLICT));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Other module
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Message
- unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXPORT_AS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
- unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- // Write the submodule metadata block.
- RecordData::value_type Record[] = {
- getNumberOfModules(WritingModule),
- FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS};
- Stream.EmitRecord(SUBMODULE_METADATA, Record);
-
- // Write all of the submodules.
- std::queue<Module *> Q;
- Q.push(WritingModule);
- while (!Q.empty()) {
- Module *Mod = Q.front();
- Q.pop();
- unsigned ID = getSubmoduleID(Mod);
-
- uint64_t ParentID = 0;
- if (Mod->Parent) {
- assert(SubmoduleIDs[Mod->Parent] && "Submodule parent not written?");
- ParentID = SubmoduleIDs[Mod->Parent];
- }
-
- // Emit the definition of the block.
- {
- RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
- ID,
- ParentID,
- (RecordData::value_type)Mod->Kind,
- Mod->IsFramework,
- Mod->IsExplicit,
- Mod->IsSystem,
- Mod->IsExternC,
- Mod->InferSubmodules,
- Mod->InferExplicitSubmodules,
- Mod->InferExportWildcard,
- Mod->ConfigMacrosExhaustive,
- Mod->ModuleMapIsPrivate};
- Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
- }
-
- // Emit the requirements.
- for (const auto &R : Mod->Requirements) {
- RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.second};
- Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.first);
- }
-
- // Emit the umbrella header, if there is one.
- if (auto UmbrellaHeader = Mod->getUmbrellaHeader()) {
- RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_HEADER};
- Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record,
- UmbrellaHeader.NameAsWritten);
- } else if (auto UmbrellaDir = Mod->getUmbrellaDir()) {
- RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_DIR};
- Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,
- UmbrellaDir.NameAsWritten);
- }
-
- // Emit the headers.
- struct {
- unsigned RecordKind;
- unsigned Abbrev;
- Module::HeaderKind HeaderKind;
- } HeaderLists[] = {
- {SUBMODULE_HEADER, HeaderAbbrev, Module::HK_Normal},
- {SUBMODULE_TEXTUAL_HEADER, TextualHeaderAbbrev, Module::HK_Textual},
- {SUBMODULE_PRIVATE_HEADER, PrivateHeaderAbbrev, Module::HK_Private},
- {SUBMODULE_PRIVATE_TEXTUAL_HEADER, PrivateTextualHeaderAbbrev,
- Module::HK_PrivateTextual},
- {SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Module::HK_Excluded}
- };
- for (auto &HL : HeaderLists) {
- RecordData::value_type Record[] = {HL.RecordKind};
- for (auto &H : Mod->Headers[HL.HeaderKind])
- Stream.EmitRecordWithBlob(HL.Abbrev, Record, H.NameAsWritten);
- }
-
- // Emit the top headers.
- {
- auto TopHeaders = Mod->getTopHeaders(PP->getFileManager());
- RecordData::value_type Record[] = {SUBMODULE_TOPHEADER};
- for (auto *H : TopHeaders)
- Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, H->getName());
- }
-
- // Emit the imports.
- if (!Mod->Imports.empty()) {
- RecordData Record;
- for (auto *I : Mod->Imports)
- Record.push_back(getSubmoduleID(I));
- Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
- }
-
- // Emit the exports.
- if (!Mod->Exports.empty()) {
- RecordData Record;
- for (const auto &E : Mod->Exports) {
- // FIXME: This may fail; we don't require that all exported modules
- // are local or imported.
- Record.push_back(getSubmoduleID(E.getPointer()));
- Record.push_back(E.getInt());
- }
- Stream.EmitRecord(SUBMODULE_EXPORTS, Record);
- }
-
- //FIXME: How do we emit the 'use'd modules? They may not be submodules.
- // Might be unnecessary as use declarations are only used to build the
- // module itself.
-
- // Emit the link libraries.
- for (const auto &LL : Mod->LinkLibraries) {
- RecordData::value_type Record[] = {SUBMODULE_LINK_LIBRARY,
- LL.IsFramework};
- Stream.EmitRecordWithBlob(LinkLibraryAbbrev, Record, LL.Library);
- }
-
- // Emit the conflicts.
- for (const auto &C : Mod->Conflicts) {
- // FIXME: This may fail; we don't require that all conflicting modules
- // are local or imported.
- RecordData::value_type Record[] = {SUBMODULE_CONFLICT,
- getSubmoduleID(C.Other)};
- Stream.EmitRecordWithBlob(ConflictAbbrev, Record, C.Message);
- }
-
- // Emit the configuration macros.
- for (const auto &CM : Mod->ConfigMacros) {
- RecordData::value_type Record[] = {SUBMODULE_CONFIG_MACRO};
- Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM);
- }
-
- // Emit the initializers, if any.
- RecordData Inits;
- for (Decl *D : Context->getModuleInitializers(Mod))
- Inits.push_back(GetDeclRef(D));
- if (!Inits.empty())
- Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
-
- // Emit the name of the re-exported module, if any.
- if (!Mod->ExportAsModule.empty()) {
- RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS};
- Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule);
- }
-
- // Queue up the submodules of this module.
- for (auto *M : Mod->submodules())
- Q.push(M);
- }
-
- Stream.ExitBlock();
-
- assert((NextSubmoduleID - FirstSubmoduleID ==
- getNumberOfModules(WritingModule)) &&
- "Wrong # of submodules; found a reference to a non-local, "
- "non-imported submodule?");
-}
-
-void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
- bool isModule) {
- llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
- DiagStateIDMap;
- unsigned CurrID = 0;
- RecordData Record;
-
- auto EncodeDiagStateFlags =
- [](const DiagnosticsEngine::DiagState *DS) -> unsigned {
- unsigned Result = (unsigned)DS->ExtBehavior;
- for (unsigned Val :
- {(unsigned)DS->IgnoreAllWarnings, (unsigned)DS->EnableAllWarnings,
- (unsigned)DS->WarningsAsErrors, (unsigned)DS->ErrorsAsFatal,
- (unsigned)DS->SuppressSystemWarnings})
- Result = (Result << 1) | Val;
- return Result;
- };
-
- unsigned Flags = EncodeDiagStateFlags(Diag.DiagStatesByLoc.FirstDiagState);
- Record.push_back(Flags);
-
- auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State,
- bool IncludeNonPragmaStates) {
- // Ensure that the diagnostic state wasn't modified since it was created.
- // We will not correctly round-trip this information otherwise.
- assert(Flags == EncodeDiagStateFlags(State) &&
- "diag state flags vary in single AST file");
-
- unsigned &DiagStateID = DiagStateIDMap[State];
- Record.push_back(DiagStateID);
-
- if (DiagStateID == 0) {
- DiagStateID = ++CurrID;
-
- // Add a placeholder for the number of mappings.
- auto SizeIdx = Record.size();
- Record.emplace_back();
- for (const auto &I : *State) {
- if (I.second.isPragma() || IncludeNonPragmaStates) {
- Record.push_back(I.first);
- Record.push_back(I.second.serialize());
- }
- }
- // Update the placeholder.
- Record[SizeIdx] = (Record.size() - SizeIdx) / 2;
- }
- };
-
- AddDiagState(Diag.DiagStatesByLoc.FirstDiagState, isModule);
-
- // Reserve a spot for the number of locations with state transitions.
- auto NumLocationsIdx = Record.size();
- Record.emplace_back();
-
- // Emit the state transitions.
- unsigned NumLocations = 0;
- for (auto &FileIDAndFile : Diag.DiagStatesByLoc.Files) {
- if (!FileIDAndFile.first.isValid() ||
- !FileIDAndFile.second.HasLocalTransitions)
- continue;
- ++NumLocations;
-
- SourceLocation Loc = Diag.SourceMgr->getComposedLoc(FileIDAndFile.first, 0);
- assert(!Loc.isInvalid() && "start loc for valid FileID is invalid");
- AddSourceLocation(Loc, Record);
-
- Record.push_back(FileIDAndFile.second.StateTransitions.size());
- for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
- Record.push_back(StatePoint.Offset);
- AddDiagState(StatePoint.State, false);
- }
- }
-
- // Backpatch the number of locations.
- Record[NumLocationsIdx] = NumLocations;
-
- // Emit CurDiagStateLoc. Do it last in order to match source order.
- //
- // This also protects against a hypothetical corner case with simulating
- // -Werror settings for implicit modules in the ASTReader, where reading
- // CurDiagState out of context could change whether warning pragmas are
- // treated as errors.
- AddSourceLocation(Diag.DiagStatesByLoc.CurDiagStateLoc, Record);
- AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false);
-
- Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record);
-}
-
-//===----------------------------------------------------------------------===//
-// Type Serialization
-//===----------------------------------------------------------------------===//
-
-/// Write the representation of a type to the AST stream.
-void ASTWriter::WriteType(QualType T) {
- TypeIdx &IdxRef = TypeIdxs[T];
- if (IdxRef.getIndex() == 0) // we haven't seen this type before.
- IdxRef = TypeIdx(NextTypeID++);
- TypeIdx Idx = IdxRef;
-
- assert(Idx.getIndex() >= FirstTypeID && "Re-writing a type from a prior AST");
-
- RecordData Record;
-
- // Emit the type's representation.
- ASTTypeWriter W(*this, Record);
- W.Visit(T);
- uint64_t Offset = W.Emit();
-
- // Record the offset for this type.
- unsigned Index = Idx.getIndex() - FirstTypeID;
- if (TypeOffsets.size() == Index)
- TypeOffsets.push_back(Offset);
- else if (TypeOffsets.size() < Index) {
- TypeOffsets.resize(Index + 1);
- TypeOffsets[Index] = Offset;
- } else {
- llvm_unreachable("Types emitted in wrong order");
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Declaration Serialization
-//===----------------------------------------------------------------------===//
-
-/// Write the block containing all of the declaration IDs
-/// lexically declared within the given DeclContext.
-///
-/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
-/// bitstream, or 0 if no block was written.
-uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
- DeclContext *DC) {
- if (DC->decls_empty())
- return 0;
-
- uint64_t Offset = Stream.GetCurrentBitNo();
- SmallVector<uint32_t, 128> KindDeclPairs;
- for (const auto *D : DC->decls()) {
- KindDeclPairs.push_back(D->getKind());
- KindDeclPairs.push_back(GetDeclRef(D));
- }
-
- ++NumLexicalDeclContexts;
- RecordData::value_type Record[] = {DECL_CONTEXT_LEXICAL};
- Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record,
- bytes(KindDeclPairs));
- return Offset;
-}
-
-void ASTWriter::WriteTypeDeclOffsets() {
- using namespace llvm;
-
- // Write the type offsets array
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(TYPE_OFFSET));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base type index
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
- unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- {
- RecordData::value_type Record[] = {TYPE_OFFSET, TypeOffsets.size(),
- FirstTypeID - NUM_PREDEF_TYPE_IDS};
- Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, bytes(TypeOffsets));
- }
-
- // Write the declaration offsets array
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(DECL_OFFSET));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // base decl ID
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
- unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- {
- RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(),
- FirstDeclID - NUM_PREDEF_DECL_IDS};
- Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets));
- }
-}
-
-void ASTWriter::WriteFileDeclIDsMap() {
- using namespace llvm;
-
- SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs(
- FileDeclIDs.begin(), FileDeclIDs.end());
- llvm::sort(SortedFileDeclIDs, llvm::less_first());
-
- // Join the vectors of DeclIDs from all files.
- SmallVector<DeclID, 256> FileGroupedDeclIDs;
- for (auto &FileDeclEntry : SortedFileDeclIDs) {
- DeclIDInFileInfo &Info = *FileDeclEntry.second;
- Info.FirstDeclIndex = FileGroupedDeclIDs.size();
- for (auto &LocDeclEntry : Info.DeclIDs)
- FileGroupedDeclIDs.push_back(LocDeclEntry.second);
- }
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
- RecordData::value_type Record[] = {FILE_SORTED_DECLS,
- FileGroupedDeclIDs.size()};
- Stream.EmitRecordWithBlob(AbbrevCode, Record, bytes(FileGroupedDeclIDs));
-}
-
-void ASTWriter::WriteComments() {
- Stream.EnterSubblock(COMMENTS_BLOCK_ID, 3);
- auto _ = llvm::make_scope_exit([this] { Stream.ExitBlock(); });
- if (!PP->getPreprocessorOpts().WriteCommentListToPCH)
- return;
- ArrayRef<RawComment *> RawComments = Context->Comments.getComments();
- RecordData Record;
- for (const auto *I : RawComments) {
- Record.clear();
- AddSourceRange(I->getSourceRange(), Record);
- Record.push_back(I->getKind());
- Record.push_back(I->isTrailingComment());
- Record.push_back(I->isAlmostTrailingComment());
- Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Global Method Pool and Selector Serialization
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-// Trait used for the on-disk hash table used in the method pool.
-class ASTMethodPoolTrait {
- ASTWriter &Writer;
-
-public:
- using key_type = Selector;
- using key_type_ref = key_type;
-
- struct data_type {
- SelectorID ID;
- ObjCMethodList Instance, Factory;
- };
- using data_type_ref = const data_type &;
-
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) {}
-
- static hash_value_type ComputeHash(Selector Sel) {
- return serialization::ComputeHash(Sel);
- }
-
- std::pair<unsigned, unsigned>
- EmitKeyDataLength(raw_ostream& Out, Selector Sel,
- data_type_ref Methods) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
- LE.write<uint16_t>(KeyLen);
- unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
- for (const ObjCMethodList *Method = &Methods.Instance; Method;
- Method = Method->getNext())
- if (Method->getMethod())
- DataLen += 4;
- for (const ObjCMethodList *Method = &Methods.Factory; Method;
- Method = Method->getNext())
- if (Method->getMethod())
- DataLen += 4;
- LE.write<uint16_t>(DataLen);
- return std::make_pair(KeyLen, DataLen);
- }
-
- void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- uint64_t Start = Out.tell();
- assert((Start >> 32) == 0 && "Selector key offset too large");
- Writer.SetSelectorOffset(Sel, Start);
- unsigned N = Sel.getNumArgs();
- LE.write<uint16_t>(N);
- if (N == 0)
- N = 1;
- for (unsigned I = 0; I != N; ++I)
- LE.write<uint32_t>(
- Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
- }
-
- void EmitData(raw_ostream& Out, key_type_ref,
- data_type_ref Methods, unsigned DataLen) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- uint64_t Start = Out.tell(); (void)Start;
- LE.write<uint32_t>(Methods.ID);
- unsigned NumInstanceMethods = 0;
- for (const ObjCMethodList *Method = &Methods.Instance; Method;
- Method = Method->getNext())
- if (Method->getMethod())
- ++NumInstanceMethods;
-
- unsigned NumFactoryMethods = 0;
- for (const ObjCMethodList *Method = &Methods.Factory; Method;
- Method = Method->getNext())
- if (Method->getMethod())
- ++NumFactoryMethods;
-
- unsigned InstanceBits = Methods.Instance.getBits();
- assert(InstanceBits < 4);
- unsigned InstanceHasMoreThanOneDeclBit =
- Methods.Instance.hasMoreThanOneDecl();
- unsigned FullInstanceBits = (NumInstanceMethods << 3) |
- (InstanceHasMoreThanOneDeclBit << 2) |
- InstanceBits;
- unsigned FactoryBits = Methods.Factory.getBits();
- assert(FactoryBits < 4);
- unsigned FactoryHasMoreThanOneDeclBit =
- Methods.Factory.hasMoreThanOneDecl();
- unsigned FullFactoryBits = (NumFactoryMethods << 3) |
- (FactoryHasMoreThanOneDeclBit << 2) |
- FactoryBits;
- LE.write<uint16_t>(FullInstanceBits);
- LE.write<uint16_t>(FullFactoryBits);
- for (const ObjCMethodList *Method = &Methods.Instance; Method;
- Method = Method->getNext())
- if (Method->getMethod())
- LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));
- for (const ObjCMethodList *Method = &Methods.Factory; Method;
- Method = Method->getNext())
- if (Method->getMethod())
- LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));
-
- assert(Out.tell() - Start == DataLen && "Data length is wrong");
- }
-};
-
-} // namespace
-
-/// Write ObjC data: selectors and the method pool.
-///
-/// The method pool contains both instance and factory methods, stored
-/// in an on-disk hash table indexed by the selector. The hash table also
-/// contains an empty entry for every other selector known to Sema.
-void ASTWriter::WriteSelectors(Sema &SemaRef) {
- using namespace llvm;
-
- // Do we have to do anything at all?
- if (SemaRef.MethodPool.empty() && SelectorIDs.empty())
- return;
- unsigned NumTableEntries = 0;
- // Create and write out the blob that contains selectors and the method pool.
- {
- llvm::OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
- ASTMethodPoolTrait Trait(*this);
-
- // Create the on-disk hash table representation. We walk through every
- // selector we've seen and look it up in the method pool.
- SelectorOffsets.resize(NextSelectorID - FirstSelectorID);
- for (auto &SelectorAndID : SelectorIDs) {
- Selector S = SelectorAndID.first;
- SelectorID ID = SelectorAndID.second;
- Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S);
- ASTMethodPoolTrait::data_type Data = {
- ID,
- ObjCMethodList(),
- ObjCMethodList()
- };
- if (F != SemaRef.MethodPool.end()) {
- Data.Instance = F->second.first;
- Data.Factory = F->second.second;
- }
- // Only write this selector if it's not in an existing AST or something
- // changed.
- if (Chain && ID < FirstSelectorID) {
- // Selector already exists. Did it change?
- bool changed = false;
- for (ObjCMethodList *M = &Data.Instance;
- !changed && M && M->getMethod(); M = M->getNext()) {
- if (!M->getMethod()->isFromASTFile())
- changed = true;
- }
- for (ObjCMethodList *M = &Data.Factory; !changed && M && M->getMethod();
- M = M->getNext()) {
- if (!M->getMethod()->isFromASTFile())
- changed = true;
- }
- if (!changed)
- continue;
- } else if (Data.Instance.getMethod() || Data.Factory.getMethod()) {
- // A new method pool entry.
- ++NumTableEntries;
- }
- Generator.insert(S, Data, Trait);
- }
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> MethodPool;
- uint32_t BucketOffset;
- {
- using namespace llvm::support;
-
- ASTMethodPoolTrait Trait(*this);
- llvm::raw_svector_ostream Out(MethodPool);
- // Make sure that no bucket is at offset 0
- endian::write<uint32_t>(Out, 0, little);
- BucketOffset = Generator.Emit(Out, Trait);
- }
-
- // Create a blob abbreviation
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(METHOD_POOL));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned MethodPoolAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- // Write the method pool
- {
- RecordData::value_type Record[] = {METHOD_POOL, BucketOffset,
- NumTableEntries};
- Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool);
- }
-
- // Create a blob abbreviation for the selector table offsets.
- Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(SELECTOR_OFFSETS));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- // Write the selector offsets table.
- {
- RecordData::value_type Record[] = {
- SELECTOR_OFFSETS, SelectorOffsets.size(),
- FirstSelectorID - NUM_PREDEF_SELECTOR_IDS};
- Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
- bytes(SelectorOffsets));
- }
- }
-}
-
-/// Write the selectors referenced in @selector expression into AST file.
-void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
- using namespace llvm;
-
- if (SemaRef.ReferencedSelectors.empty())
- return;
-
- RecordData Record;
- ASTRecordWriter Writer(*this, Record);
-
- // Note: this writes out all references even for a dependent AST. But it is
- // very tricky to fix, and given that @selector shouldn't really appear in
- // headers, probably not worth it. It's not a correctness issue.
- for (auto &SelectorAndLocation : SemaRef.ReferencedSelectors) {
- Selector Sel = SelectorAndLocation.first;
- SourceLocation Loc = SelectorAndLocation.second;
- Writer.AddSelectorRef(Sel);
- Writer.AddSourceLocation(Loc);
- }
- Writer.Emit(REFERENCED_SELECTOR_POOL);
-}
-
-//===----------------------------------------------------------------------===//
-// Identifier Table Serialization
-//===----------------------------------------------------------------------===//
-
-/// Determine the declaration that should be put into the name lookup table to
-/// represent the given declaration in this module. This is usually D itself,
-/// but if D was imported and merged into a local declaration, we want the most
-/// recent local declaration instead. The chosen declaration will be the most
-/// recent declaration in any module that imports this one.
-static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts,
- NamedDecl *D) {
- if (!LangOpts.Modules || !D->isFromASTFile())
- return D;
-
- if (Decl *Redecl = D->getPreviousDecl()) {
- // For Redeclarable decls, a prior declaration might be local.
- for (; Redecl; Redecl = Redecl->getPreviousDecl()) {
- // If we find a local decl, we're done.
- if (!Redecl->isFromASTFile()) {
- // Exception: in very rare cases (for injected-class-names), not all
- // redeclarations are in the same semantic context. Skip ones in a
- // different context. They don't go in this lookup table at all.
- if (!Redecl->getDeclContext()->getRedeclContext()->Equals(
- D->getDeclContext()->getRedeclContext()))
- continue;
- return cast<NamedDecl>(Redecl);
- }
-
- // If we find a decl from a (chained-)PCH stop since we won't find a
- // local one.
- if (Redecl->getOwningModuleID() == 0)
- break;
- }
- } else if (Decl *First = D->getCanonicalDecl()) {
- // For Mergeable decls, the first decl might be local.
- if (!First->isFromASTFile())
- return cast<NamedDecl>(First);
- }
-
- // All declarations are imported. Our most recent declaration will also be
- // the most recent one in anyone who imports us.
- return D;
-}
-
-namespace {
-
-class ASTIdentifierTableTrait {
- ASTWriter &Writer;
- Preprocessor &PP;
- IdentifierResolver &IdResolver;
- bool IsModule;
- bool NeedDecls;
- ASTWriter::RecordData *InterestingIdentifierOffsets;
-
- /// Determines whether this is an "interesting" identifier that needs a
- /// full IdentifierInfo structure written into the hash table. Notably, this
- /// doesn't check whether the name has macros defined; use PublicMacroIterator
- /// to check that.
- bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) {
- if (MacroOffset ||
- II->isPoisoned() ||
- (IsModule ? II->hasRevertedBuiltin() : II->getObjCOrBuiltinID()) ||
- II->hasRevertedTokenIDToIdentifier() ||
- (NeedDecls && II->getFETokenInfo()))
- return true;
-
- return false;
- }
-
-public:
- using key_type = IdentifierInfo *;
- using key_type_ref = key_type;
-
- using data_type = IdentID;
- using data_type_ref = data_type;
-
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,
- IdentifierResolver &IdResolver, bool IsModule,
- ASTWriter::RecordData *InterestingIdentifierOffsets)
- : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule),
- NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus),
- InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}
-
- bool needDecls() const { return NeedDecls; }
-
- static hash_value_type ComputeHash(const IdentifierInfo* II) {
- return llvm::djbHash(II->getName());
- }
-
- bool isInterestingIdentifier(const IdentifierInfo *II) {
- auto MacroOffset = Writer.getMacroDirectivesOffset(II);
- return isInterestingIdentifier(II, MacroOffset);
- }
-
- bool isInterestingNonMacroIdentifier(const IdentifierInfo *II) {
- return isInterestingIdentifier(II, 0);
- }
-
- std::pair<unsigned, unsigned>
- EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
- unsigned KeyLen = II->getLength() + 1;
- unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
- auto MacroOffset = Writer.getMacroDirectivesOffset(II);
- if (isInterestingIdentifier(II, MacroOffset)) {
- DataLen += 2; // 2 bytes for builtin ID
- DataLen += 2; // 2 bytes for flags
- if (MacroOffset)
- DataLen += 4; // MacroDirectives offset.
-
- if (NeedDecls) {
- for (IdentifierResolver::iterator D = IdResolver.begin(II),
- DEnd = IdResolver.end();
- D != DEnd; ++D)
- DataLen += 4;
- }
- }
-
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
-
- assert((uint16_t)DataLen == DataLen && (uint16_t)KeyLen == KeyLen);
- LE.write<uint16_t>(DataLen);
- // We emit the key length after the data length so that every
- // string is preceded by a 16-bit length. This matches the PTH
- // format for storing identifiers.
- LE.write<uint16_t>(KeyLen);
- return std::make_pair(KeyLen, DataLen);
- }
-
- void EmitKey(raw_ostream& Out, const IdentifierInfo* II,
- unsigned KeyLen) {
- // Record the location of the key data. This is used when generating
- // the mapping from persistent IDs to strings.
- Writer.SetIdentifierOffset(II, Out.tell());
-
- // Emit the offset of the key/data length information to the interesting
- // identifiers table if necessary.
- if (InterestingIdentifierOffsets && isInterestingIdentifier(II))
- InterestingIdentifierOffsets->push_back(Out.tell() - 4);
-
- Out.write(II->getNameStart(), KeyLen);
- }
-
- void EmitData(raw_ostream& Out, IdentifierInfo* II,
- IdentID ID, unsigned) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
-
- auto MacroOffset = Writer.getMacroDirectivesOffset(II);
- if (!isInterestingIdentifier(II, MacroOffset)) {
- LE.write<uint32_t>(ID << 1);
- return;
- }
-
- LE.write<uint32_t>((ID << 1) | 0x01);
- uint32_t Bits = (uint32_t)II->getObjCOrBuiltinID();
- assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
- LE.write<uint16_t>(Bits);
- Bits = 0;
- bool HadMacroDefinition = MacroOffset != 0;
- Bits = (Bits << 1) | unsigned(HadMacroDefinition);
- Bits = (Bits << 1) | unsigned(II->isExtensionToken());
- Bits = (Bits << 1) | unsigned(II->isPoisoned());
- Bits = (Bits << 1) | unsigned(II->hasRevertedBuiltin());
- Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
- Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
- LE.write<uint16_t>(Bits);
-
- if (HadMacroDefinition)
- LE.write<uint32_t>(MacroOffset);
-
- if (NeedDecls) {
- // Emit the declaration IDs in reverse order, because the
- // IdentifierResolver provides the declarations as they would be
- // visible (e.g., the function "stat" would come before the struct
- // "stat"), but the ASTReader adds declarations to the end of the list
- // (so we need to see the struct "stat" before the function "stat").
- // Only emit declarations that aren't from a chained PCH, though.
- SmallVector<NamedDecl *, 16> Decls(IdResolver.begin(II),
- IdResolver.end());
- for (SmallVectorImpl<NamedDecl *>::reverse_iterator D = Decls.rbegin(),
- DEnd = Decls.rend();
- D != DEnd; ++D)
- LE.write<uint32_t>(
- Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), *D)));
- }
- }
-};
-
-} // namespace
-
-/// Write the identifier table into the AST file.
-///
-/// The identifier table consists of a blob containing string data
-/// (the actual identifiers themselves) and a separate "offsets" index
-/// that maps identifier IDs to locations within the blob.
-void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
- IdentifierResolver &IdResolver,
- bool IsModule) {
- using namespace llvm;
-
- RecordData InterestingIdents;
-
- // Create and write out the blob that contains the identifier
- // strings.
- {
- llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
- ASTIdentifierTableTrait Trait(
- *this, PP, IdResolver, IsModule,
- (getLangOpts().CPlusPlus && IsModule) ? &InterestingIdents : nullptr);
-
- // Look for any identifiers that were named while processing the
- // headers, but are otherwise not needed. We add these to the hash
- // table to enable checking of the predefines buffer in the case
- // where the user adds new macro definitions when building the AST
- // file.
- SmallVector<const IdentifierInfo *, 128> IIs;
- for (const auto &ID : PP.getIdentifierTable())
- IIs.push_back(ID.second);
- // Sort the identifiers lexicographically before getting them references so
- // that their order is stable.
- llvm::sort(IIs, llvm::less_ptr<IdentifierInfo>());
- for (const IdentifierInfo *II : IIs)
- if (Trait.isInterestingNonMacroIdentifier(II))
- getIdentifierRef(II);
-
- // Create the on-disk hash table representation. We only store offsets
- // for identifiers that appear here for the first time.
- IdentifierOffsets.resize(NextIdentID - FirstIdentID);
- for (auto IdentIDPair : IdentifierIDs) {
- auto *II = const_cast<IdentifierInfo *>(IdentIDPair.first);
- IdentID ID = IdentIDPair.second;
- assert(II && "NULL identifier in identifier table");
- // Write out identifiers if either the ID is local or the identifier has
- // changed since it was loaded.
- if (ID >= FirstIdentID || !Chain || !II->isFromAST()
- || II->hasChangedSinceDeserialization() ||
- (Trait.needDecls() &&
- II->hasFETokenInfoChangedSinceDeserialization()))
- Generator.insert(II, ID, Trait);
- }
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> IdentifierTable;
- uint32_t BucketOffset;
- {
- using namespace llvm::support;
-
- llvm::raw_svector_ostream Out(IdentifierTable);
- // Make sure that no bucket is at offset 0
- endian::write<uint32_t>(Out, 0, little);
- BucketOffset = Generator.Emit(Out, Trait);
- }
-
- // Create a blob abbreviation
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_TABLE));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- // Write the identifier table
- RecordData::value_type Record[] = {IDENTIFIER_TABLE, BucketOffset};
- Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable);
- }
-
- // Write the offsets table for identifier IDs.
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
-#ifndef NDEBUG
- for (unsigned I = 0, N = IdentifierOffsets.size(); I != N; ++I)
- assert(IdentifierOffsets[I] && "Missing identifier offset?");
-#endif
-
- RecordData::value_type Record[] = {IDENTIFIER_OFFSET,
- IdentifierOffsets.size(),
- FirstIdentID - NUM_PREDEF_IDENT_IDS};
- Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
- bytes(IdentifierOffsets));
-
- // In C++, write the list of interesting identifiers (those that are
- // defined as macros, poisoned, or similar unusual things).
- if (!InterestingIdents.empty())
- Stream.EmitRecord(INTERESTING_IDENTIFIERS, InterestingIdents);
-}
-
-//===----------------------------------------------------------------------===//
-// DeclContext's Name Lookup Table Serialization
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-// Trait used for the on-disk hash table used in the method pool.
-class ASTDeclContextNameLookupTrait {
- ASTWriter &Writer;
- llvm::SmallVector<DeclID, 64> DeclIDs;
-
-public:
- using key_type = DeclarationNameKey;
- using key_type_ref = key_type;
-
- /// A start and end index into DeclIDs, representing a sequence of decls.
- using data_type = std::pair<unsigned, unsigned>;
- using data_type_ref = const data_type &;
-
- using hash_value_type = unsigned;
- using offset_type = unsigned;
-
- explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) {}
-
- template<typename Coll>
- data_type getData(const Coll &Decls) {
- unsigned Start = DeclIDs.size();
- for (NamedDecl *D : Decls) {
- DeclIDs.push_back(
- Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), D)));
- }
- return std::make_pair(Start, DeclIDs.size());
- }
-
- data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) {
- unsigned Start = DeclIDs.size();
- for (auto ID : FromReader)
- DeclIDs.push_back(ID);
- return std::make_pair(Start, DeclIDs.size());
- }
-
- static bool EqualKey(key_type_ref a, key_type_ref b) {
- return a == b;
- }
-
- hash_value_type ComputeHash(DeclarationNameKey Name) {
- return Name.getHash();
- }
-
- void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
- assert(Writer.hasChain() &&
- "have reference to loaded module file but no chain?");
-
- using namespace llvm::support;
-
- endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F), little);
- }
-
- std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
- DeclarationNameKey Name,
- data_type_ref Lookup) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- unsigned KeyLen = 1;
- switch (Name.getKind()) {
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXDeductionGuideName:
- KeyLen += 4;
- break;
- case DeclarationName::CXXOperatorName:
- KeyLen += 1;
- break;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
- LE.write<uint16_t>(KeyLen);
-
- // 4 bytes for each DeclID.
- unsigned DataLen = 4 * (Lookup.second - Lookup.first);
- assert(uint16_t(DataLen) == DataLen &&
- "too many decls for serialized lookup result");
- LE.write<uint16_t>(DataLen);
-
- return std::make_pair(KeyLen, DataLen);
- }
-
- void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- LE.write<uint8_t>(Name.getKind());
- switch (Name.getKind()) {
- case DeclarationName::Identifier:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXDeductionGuideName:
- LE.write<uint32_t>(Writer.getIdentifierRef(Name.getIdentifier()));
- return;
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- LE.write<uint32_t>(Writer.getSelectorRef(Name.getSelector()));
- return;
- case DeclarationName::CXXOperatorName:
- assert(Name.getOperatorKind() < NUM_OVERLOADED_OPERATORS &&
- "Invalid operator?");
- LE.write<uint8_t>(Name.getOperatorKind());
- return;
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXUsingDirective:
- return;
- }
-
- llvm_unreachable("Invalid name kind?");
- }
-
- void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
- unsigned DataLen) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- uint64_t Start = Out.tell(); (void)Start;
- for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
- LE.write<uint32_t>(DeclIDs[I]);
- assert(Out.tell() - Start == DataLen && "Data length is wrong");
- }
-};
-
-} // namespace
-
-bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
- DeclContext *DC) {
- return Result.hasExternalDecls() &&
- DC->hasNeedToReconcileExternalVisibleStorage();
-}
-
-bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
- DeclContext *DC) {
- for (auto *D : Result.getLookupResult())
- if (!getDeclForLocalLookup(getLangOpts(), D)->isFromASTFile())
- return false;
-
- return true;
-}
-
-void
-ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
- llvm::SmallVectorImpl<char> &LookupTable) {
- assert(!ConstDC->hasLazyLocalLexicalLookups() &&
- !ConstDC->hasLazyExternalLexicalLookups() &&
- "must call buildLookups first");
-
- // FIXME: We need to build the lookups table, which is logically const.
- auto *DC = const_cast<DeclContext*>(ConstDC);
- assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
-
- // Create the on-disk hash table representation.
- MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
- ASTDeclContextNameLookupTrait> Generator;
- ASTDeclContextNameLookupTrait Trait(*this);
-
- // The first step is to collect the declaration names which we need to
- // serialize into the name lookup table, and to collect them in a stable
- // order.
- SmallVector<DeclarationName, 16> Names;
-
- // We also build up small sets of the constructor and conversion function
- // names which are visible.
- llvm::SmallSet<DeclarationName, 8> ConstructorNameSet, ConversionNameSet;
-
- for (auto &Lookup : *DC->buildLookup()) {
- auto &Name = Lookup.first;
- auto &Result = Lookup.second;
-
- // If there are no local declarations in our lookup result, we
- // don't need to write an entry for the name at all. If we can't
- // write out a lookup set without performing more deserialization,
- // just skip this entry.
- if (isLookupResultExternal(Result, DC) &&
- isLookupResultEntirelyExternal(Result, DC))
- continue;
-
- // We also skip empty results. If any of the results could be external and
- // the currently available results are empty, then all of the results are
- // external and we skip it above. So the only way we get here with an empty
- // results is when no results could have been external *and* we have
- // external results.
- //
- // FIXME: While we might want to start emitting on-disk entries for negative
- // lookups into a decl context as an optimization, today we *have* to skip
- // them because there are names with empty lookup results in decl contexts
- // which we can't emit in any stable ordering: we lookup constructors and
- // conversion functions in the enclosing namespace scope creating empty
- // results for them. This in almost certainly a bug in Clang's name lookup,
- // but that is likely to be hard or impossible to fix and so we tolerate it
- // here by omitting lookups with empty results.
- if (Lookup.second.getLookupResult().empty())
- continue;
-
- switch (Lookup.first.getNameKind()) {
- default:
- Names.push_back(Lookup.first);
- break;
-
- case DeclarationName::CXXConstructorName:
- assert(isa<CXXRecordDecl>(DC) &&
- "Cannot have a constructor name outside of a class!");
- ConstructorNameSet.insert(Name);
- break;
-
- case DeclarationName::CXXConversionFunctionName:
- assert(isa<CXXRecordDecl>(DC) &&
- "Cannot have a conversion function name outside of a class!");
- ConversionNameSet.insert(Name);
- break;
- }
- }
-
- // Sort the names into a stable order.
- llvm::sort(Names);
-
- if (auto *D = dyn_cast<CXXRecordDecl>(DC)) {
- // We need to establish an ordering of constructor and conversion function
- // names, and they don't have an intrinsic ordering.
-
- // First we try the easy case by forming the current context's constructor
- // name and adding that name first. This is a very useful optimization to
- // avoid walking the lexical declarations in many cases, and it also
- // handles the only case where a constructor name can come from some other
- // lexical context -- when that name is an implicit constructor merged from
- // another declaration in the redecl chain. Any non-implicit constructor or
- // conversion function which doesn't occur in all the lexical contexts
- // would be an ODR violation.
- auto ImplicitCtorName = Context->DeclarationNames.getCXXConstructorName(
- Context->getCanonicalType(Context->getRecordType(D)));
- if (ConstructorNameSet.erase(ImplicitCtorName))
- Names.push_back(ImplicitCtorName);
-
- // If we still have constructors or conversion functions, we walk all the
- // names in the decl and add the constructors and conversion functions
- // which are visible in the order they lexically occur within the context.
- if (!ConstructorNameSet.empty() || !ConversionNameSet.empty())
- for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls())
- if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
- auto Name = ChildND->getDeclName();
- switch (Name.getNameKind()) {
- default:
- continue;
-
- case DeclarationName::CXXConstructorName:
- if (ConstructorNameSet.erase(Name))
- Names.push_back(Name);
- break;
-
- case DeclarationName::CXXConversionFunctionName:
- if (ConversionNameSet.erase(Name))
- Names.push_back(Name);
- break;
- }
-
- if (ConstructorNameSet.empty() && ConversionNameSet.empty())
- break;
- }
-
- assert(ConstructorNameSet.empty() && "Failed to find all of the visible "
- "constructors by walking all the "
- "lexical members of the context.");
- assert(ConversionNameSet.empty() && "Failed to find all of the visible "
- "conversion functions by walking all "
- "the lexical members of the context.");
- }
-
- // Next we need to do a lookup with each name into this decl context to fully
- // populate any results from external sources. We don't actually use the
- // results of these lookups because we only want to use the results after all
- // results have been loaded and the pointers into them will be stable.
- for (auto &Name : Names)
- DC->lookup(Name);
-
- // Now we need to insert the results for each name into the hash table. For
- // constructor names and conversion function names, we actually need to merge
- // all of the results for them into one list of results each and insert
- // those.
- SmallVector<NamedDecl *, 8> ConstructorDecls;
- SmallVector<NamedDecl *, 8> ConversionDecls;
-
- // Now loop over the names, either inserting them or appending for the two
- // special cases.
- for (auto &Name : Names) {
- DeclContext::lookup_result Result = DC->noload_lookup(Name);
-
- switch (Name.getNameKind()) {
- default:
- Generator.insert(Name, Trait.getData(Result), Trait);
- break;
-
- case DeclarationName::CXXConstructorName:
- ConstructorDecls.append(Result.begin(), Result.end());
- break;
-
- case DeclarationName::CXXConversionFunctionName:
- ConversionDecls.append(Result.begin(), Result.end());
- break;
- }
- }
-
- // Handle our two special cases if we ended up having any. We arbitrarily use
- // the first declaration's name here because the name itself isn't part of
- // the key, only the kind of name is used.
- if (!ConstructorDecls.empty())
- Generator.insert(ConstructorDecls.front()->getDeclName(),
- Trait.getData(ConstructorDecls), Trait);
- if (!ConversionDecls.empty())
- Generator.insert(ConversionDecls.front()->getDeclName(),
- Trait.getData(ConversionDecls), Trait);
-
- // Create the on-disk hash table. Also emit the existing imported and
- // merged table if there is one.
- auto *Lookups = Chain ? Chain->getLoadedLookupTables(DC) : nullptr;
- Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr);
-}
-
-/// Write the block containing all of the declaration IDs
-/// visible from the given DeclContext.
-///
-/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
-/// bitstream, or 0 if no block was written.
-uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
- DeclContext *DC) {
- // If we imported a key declaration of this namespace, write the visible
- // lookup results as an update record for it rather than including them
- // on this declaration. We will only look at key declarations on reload.
- if (isa<NamespaceDecl>(DC) && Chain &&
- Chain->getKeyDeclaration(cast<Decl>(DC))->isFromASTFile()) {
- // Only do this once, for the first local declaration of the namespace.
- for (auto *Prev = cast<NamespaceDecl>(DC)->getPreviousDecl(); Prev;
- Prev = Prev->getPreviousDecl())
- if (!Prev->isFromASTFile())
- return 0;
-
- // Note that we need to emit an update record for the primary context.
- UpdatedDeclContexts.insert(DC->getPrimaryContext());
-
- // Make sure all visible decls are written. They will be recorded later. We
- // do this using a side data structure so we can sort the names into
- // a deterministic order.
- StoredDeclsMap *Map = DC->getPrimaryContext()->buildLookup();
- SmallVector<std::pair<DeclarationName, DeclContext::lookup_result>, 16>
- LookupResults;
- if (Map) {
- LookupResults.reserve(Map->size());
- for (auto &Entry : *Map)
- LookupResults.push_back(
- std::make_pair(Entry.first, Entry.second.getLookupResult()));
- }
-
- llvm::sort(LookupResults, llvm::less_first());
- for (auto &NameAndResult : LookupResults) {
- DeclarationName Name = NameAndResult.first;
- DeclContext::lookup_result Result = NameAndResult.second;
- if (Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
- // We have to work around a name lookup bug here where negative lookup
- // results for these names get cached in namespace lookup tables (these
- // names should never be looked up in a namespace).
- assert(Result.empty() && "Cannot have a constructor or conversion "
- "function name in a namespace!");
- continue;
- }
-
- for (NamedDecl *ND : Result)
- if (!ND->isFromASTFile())
- GetDeclRef(ND);
- }
-
- return 0;
- }
-
- if (DC->getPrimaryContext() != DC)
- return 0;
-
- // Skip contexts which don't support name lookup.
- if (!DC->isLookupContext())
- return 0;
-
- // If not in C++, we perform name lookup for the translation unit via the
- // IdentifierInfo chains, don't bother to build a visible-declarations table.
- if (DC->isTranslationUnit() && !Context.getLangOpts().CPlusPlus)
- return 0;
-
- // Serialize the contents of the mapping used for lookup. Note that,
- // although we have two very different code paths, the serialized
- // representation is the same for both cases: a declaration name,
- // followed by a size, followed by references to the visible
- // declarations that have that name.
- uint64_t Offset = Stream.GetCurrentBitNo();
- StoredDeclsMap *Map = DC->buildLookup();
- if (!Map || Map->empty())
- return 0;
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> LookupTable;
- GenerateNameLookupTable(DC, LookupTable);
-
- // Write the lookup table
- RecordData::value_type Record[] = {DECL_CONTEXT_VISIBLE};
- Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
- LookupTable);
- ++NumVisibleDeclContexts;
- return Offset;
-}
-
-/// Write an UPDATE_VISIBLE block for the given context.
-///
-/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing
-/// DeclContext in a dependent AST file. As such, they only exist for the TU
-/// (in C++), for namespaces, and for classes with forward-declared unscoped
-/// enumeration members (in C++11).
-void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
- StoredDeclsMap *Map = DC->getLookupPtr();
- if (!Map || Map->empty())
- return;
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> LookupTable;
- GenerateNameLookupTable(DC, LookupTable);
-
- // If we're updating a namespace, select a key declaration as the key for the
- // update record; those are the only ones that will be checked on reload.
- if (isa<NamespaceDecl>(DC))
- DC = cast<DeclContext>(Chain->getKeyDeclaration(cast<Decl>(DC)));
-
- // Write the lookup table
- RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast<Decl>(DC))};
- Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
-}
-
-/// Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
-void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) {
- RecordData::value_type Record[] = {Opts.getInt()};
- Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record);
-}
-
-/// Write an OPENCL_EXTENSIONS block for the given OpenCLOptions.
-void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) {
- if (!SemaRef.Context.getLangOpts().OpenCL)
- return;
-
- const OpenCLOptions &Opts = SemaRef.getOpenCLOptions();
- RecordData Record;
- for (const auto &I:Opts.OptMap) {
- AddString(I.getKey(), Record);
- auto V = I.getValue();
- Record.push_back(V.Supported ? 1 : 0);
- Record.push_back(V.Enabled ? 1 : 0);
- Record.push_back(V.Avail);
- Record.push_back(V.Core);
- }
- Stream.EmitRecord(OPENCL_EXTENSIONS, Record);
-}
-
-void ASTWriter::WriteOpenCLExtensionTypes(Sema &SemaRef) {
- if (!SemaRef.Context.getLangOpts().OpenCL)
- return;
-
- RecordData Record;
- for (const auto &I : SemaRef.OpenCLTypeExtMap) {
- Record.push_back(
- static_cast<unsigned>(getTypeID(I.first->getCanonicalTypeInternal())));
- Record.push_back(I.second.size());
- for (auto Ext : I.second)
- AddString(Ext, Record);
- }
- Stream.EmitRecord(OPENCL_EXTENSION_TYPES, Record);
-}
-
-void ASTWriter::WriteOpenCLExtensionDecls(Sema &SemaRef) {
- if (!SemaRef.Context.getLangOpts().OpenCL)
- return;
-
- RecordData Record;
- for (const auto &I : SemaRef.OpenCLDeclExtMap) {
- Record.push_back(getDeclID(I.first));
- Record.push_back(static_cast<unsigned>(I.second.size()));
- for (auto Ext : I.second)
- AddString(Ext, Record);
- }
- Stream.EmitRecord(OPENCL_EXTENSION_DECLS, Record);
-}
-
-void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) {
- if (SemaRef.ForceCUDAHostDeviceDepth > 0) {
- RecordData::value_type Record[] = {SemaRef.ForceCUDAHostDeviceDepth};
- Stream.EmitRecord(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH, Record);
- }
-}
-
-void ASTWriter::WriteObjCCategories() {
- SmallVector<ObjCCategoriesInfo, 2> CategoriesMap;
- RecordData Categories;
-
- for (unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) {
- unsigned Size = 0;
- unsigned StartIndex = Categories.size();
-
- ObjCInterfaceDecl *Class = ObjCClassesWithCategories[I];
-
- // Allocate space for the size.
- Categories.push_back(0);
-
- // Add the categories.
- for (ObjCInterfaceDecl::known_categories_iterator
- Cat = Class->known_categories_begin(),
- CatEnd = Class->known_categories_end();
- Cat != CatEnd; ++Cat, ++Size) {
- assert(getDeclID(*Cat) != 0 && "Bogus category");
- AddDeclRef(*Cat, Categories);
- }
-
- // Update the size.
- Categories[StartIndex] = Size;
-
- // Record this interface -> category map.
- ObjCCategoriesInfo CatInfo = { getDeclID(Class), StartIndex };
- CategoriesMap.push_back(CatInfo);
- }
-
- // Sort the categories map by the definition ID, since the reader will be
- // performing binary searches on this information.
- llvm::array_pod_sort(CategoriesMap.begin(), CategoriesMap.end());
-
- // Emit the categories map.
- using namespace llvm;
-
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(OBJC_CATEGORIES_MAP));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
-
- RecordData::value_type Record[] = {OBJC_CATEGORIES_MAP, CategoriesMap.size()};
- Stream.EmitRecordWithBlob(AbbrevID, Record,
- reinterpret_cast<char *>(CategoriesMap.data()),
- CategoriesMap.size() * sizeof(ObjCCategoriesInfo));
-
- // Emit the category lists.
- Stream.EmitRecord(OBJC_CATEGORIES, Categories);
-}
-
-void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) {
- Sema::LateParsedTemplateMapT &LPTMap = SemaRef.LateParsedTemplateMap;
-
- if (LPTMap.empty())
- return;
-
- RecordData Record;
- for (auto &LPTMapEntry : LPTMap) {
- const FunctionDecl *FD = LPTMapEntry.first;
- LateParsedTemplate &LPT = *LPTMapEntry.second;
- AddDeclRef(FD, Record);
- AddDeclRef(LPT.D, Record);
- Record.push_back(LPT.Toks.size());
-
- for (const auto &Tok : LPT.Toks) {
- AddToken(Tok, Record);
- }
- }
- Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record);
-}
-
-/// Write the state of 'pragma clang optimize' at the end of the module.
-void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
- RecordData Record;
- SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation();
- AddSourceLocation(PragmaLoc, Record);
- Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record);
-}
-
-/// Write the state of 'pragma ms_struct' at the end of the module.
-void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) {
- RecordData Record;
- Record.push_back(SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF);
- Stream.EmitRecord(MSSTRUCT_PRAGMA_OPTIONS, Record);
-}
-
-/// Write the state of 'pragma pointers_to_members' at the end of the
-//module.
-void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) {
- RecordData Record;
- Record.push_back(SemaRef.MSPointerToMemberRepresentationMethod);
- AddSourceLocation(SemaRef.ImplicitMSInheritanceAttrLoc, Record);
- Stream.EmitRecord(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Record);
-}
-
-/// Write the state of 'pragma pack' at the end of the module.
-void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
- // Don't serialize pragma pack state for modules, since it should only take
- // effect on a per-submodule basis.
- if (WritingModule)
- return;
-
- RecordData Record;
- Record.push_back(SemaRef.PackStack.CurrentValue);
- AddSourceLocation(SemaRef.PackStack.CurrentPragmaLocation, Record);
- Record.push_back(SemaRef.PackStack.Stack.size());
- for (const auto &StackEntry : SemaRef.PackStack.Stack) {
- Record.push_back(StackEntry.Value);
- AddSourceLocation(StackEntry.PragmaLocation, Record);
- AddSourceLocation(StackEntry.PragmaPushLocation, Record);
- AddString(StackEntry.StackSlotLabel, Record);
- }
- Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record);
-}
-
-void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
- ModuleFileExtensionWriter &Writer) {
- // Enter the extension block.
- Stream.EnterSubblock(EXTENSION_BLOCK_ID, 4);
-
- // Emit the metadata record abbreviation.
- auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
- Abv->Add(llvm::BitCodeAbbrevOp(EXTENSION_METADATA));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
- unsigned Abbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Emit the metadata record.
- RecordData Record;
- auto Metadata = Writer.getExtension()->getExtensionMetadata();
- Record.push_back(EXTENSION_METADATA);
- Record.push_back(Metadata.MajorVersion);
- Record.push_back(Metadata.MinorVersion);
- Record.push_back(Metadata.BlockName.size());
- Record.push_back(Metadata.UserInfo.size());
- SmallString<64> Buffer;
- Buffer += Metadata.BlockName;
- Buffer += Metadata.UserInfo;
- Stream.EmitRecordWithBlob(Abbrev, Record, Buffer);
-
- // Emit the contents of the extension block.
- Writer.writeExtensionContents(SemaRef, Stream);
-
- // Exit the extension block.
- Stream.ExitBlock();
-}
-
-//===----------------------------------------------------------------------===//
-// General Serialization Routines
-//===----------------------------------------------------------------------===//
-
-void ASTRecordWriter::AddAttr(const Attr *A) {
- auto &Record = *this;
- if (!A)
- return Record.push_back(0);
- Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs
- Record.AddSourceRange(A->getRange());
-
-#include "clang/Serialization/AttrPCHWrite.inc"
-}
-
-/// Emit the list of attributes to the specified record.
-void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
- push_back(Attrs.size());
- for (const auto *A : Attrs)
- AddAttr(A);
-}
-
-void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) {
- AddSourceLocation(Tok.getLocation(), Record);
- Record.push_back(Tok.getLength());
-
- // FIXME: When reading literal tokens, reconstruct the literal pointer
- // if it is needed.
- AddIdentifierRef(Tok.getIdentifierInfo(), Record);
- // FIXME: Should translate token kind to a stable encoding.
- Record.push_back(Tok.getKind());
- // FIXME: Should translate token flags to a stable encoding.
- Record.push_back(Tok.getFlags());
-}
-
-void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {
- Record.push_back(Str.size());
- Record.insert(Record.end(), Str.begin(), Str.end());
-}
-
-bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) {
- assert(Context && "should have context when outputting path");
-
- bool Changed =
- cleanPathForOutput(Context->getSourceManager().getFileManager(), Path);
-
- // Remove a prefix to make the path relative, if relevant.
- const char *PathBegin = Path.data();
- const char *PathPtr =
- adjustFilenameForRelocatableAST(PathBegin, BaseDirectory);
- if (PathPtr != PathBegin) {
- Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin));
- Changed = true;
- }
-
- return Changed;
-}
-
-void ASTWriter::AddPath(StringRef Path, RecordDataImpl &Record) {
- SmallString<128> FilePath(Path);
- PreparePathForOutput(FilePath);
- AddString(FilePath, Record);
-}
-
-void ASTWriter::EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
- StringRef Path) {
- SmallString<128> FilePath(Path);
- PreparePathForOutput(FilePath);
- Stream.EmitRecordWithBlob(Abbrev, Record, FilePath);
-}
-
-void ASTWriter::AddVersionTuple(const VersionTuple &Version,
- RecordDataImpl &Record) {
- Record.push_back(Version.getMajor());
- if (Optional<unsigned> Minor = Version.getMinor())
- Record.push_back(*Minor + 1);
- else
- Record.push_back(0);
- if (Optional<unsigned> Subminor = Version.getSubminor())
- Record.push_back(*Subminor + 1);
- else
- Record.push_back(0);
-}
-
-/// Note that the identifier II occurs at the given offset
-/// within the identifier table.
-void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
- IdentID ID = IdentifierIDs[II];
- // Only store offsets new to this AST file. Other identifier names are looked
- // up earlier in the chain and thus don't need an offset.
- if (ID >= FirstIdentID)
- IdentifierOffsets[ID - FirstIdentID] = Offset;
-}
-
-/// Note that the selector Sel occurs at the given offset
-/// within the method pool/selector table.
-void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
- unsigned ID = SelectorIDs[Sel];
- assert(ID && "Unknown selector");
- // Don't record offsets for selectors that are also available in a different
- // file.
- if (ID < FirstSelectorID)
- return;
- SelectorOffsets[ID - FirstSelectorID] = Offset;
-}
-
-ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
- SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache,
- ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool IncludeTimestamps)
- : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache),
- IncludeTimestamps(IncludeTimestamps) {
- for (const auto &Ext : Extensions) {
- if (auto Writer = Ext->createExtensionWriter(*this))
- ModuleFileExtensionWriters.push_back(std::move(Writer));
- }
-}
-
-ASTWriter::~ASTWriter() {
- llvm::DeleteContainerSeconds(FileDeclIDs);
-}
-
-const LangOptions &ASTWriter::getLangOpts() const {
- assert(WritingAST && "can't determine lang opts when not writing AST");
- return Context->getLangOpts();
-}
-
-time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
- return IncludeTimestamps ? E->getModificationTime() : 0;
-}
-
-ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
- const std::string &OutputFile,
- Module *WritingModule, StringRef isysroot,
- bool hasErrors) {
- WritingAST = true;
-
- ASTHasCompilerErrors = hasErrors;
-
- // Emit the file header.
- Stream.Emit((unsigned)'C', 8);
- Stream.Emit((unsigned)'P', 8);
- Stream.Emit((unsigned)'C', 8);
- Stream.Emit((unsigned)'H', 8);
-
- WriteBlockInfoBlock();
-
- Context = &SemaRef.Context;
- PP = &SemaRef.PP;
- this->WritingModule = WritingModule;
- ASTFileSignature Signature =
- WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule);
- Context = nullptr;
- PP = nullptr;
- this->WritingModule = nullptr;
- this->BaseDirectory.clear();
-
- WritingAST = false;
- if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
- // Construct MemoryBuffer and update buffer manager.
- PCMCache.addBuffer(OutputFile,
- llvm::MemoryBuffer::getMemBufferCopy(
- StringRef(Buffer.begin(), Buffer.size())));
- }
- return Signature;
-}
-
-template<typename Vector>
-static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
- ASTWriter::RecordData &Record) {
- for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
- I != E; ++I) {
- Writer.AddDeclRef(*I, Record);
- }
-}
-
-ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
- const std::string &OutputFile,
- Module *WritingModule) {
- using namespace llvm;
-
- bool isModule = WritingModule != nullptr;
-
- // Make sure that the AST reader knows to finalize itself.
- if (Chain)
- Chain->finalizeForWriting();
-
- ASTContext &Context = SemaRef.Context;
- Preprocessor &PP = SemaRef.PP;
-
- // Set up predefined declaration IDs.
- auto RegisterPredefDecl = [&] (Decl *D, PredefinedDeclIDs ID) {
- if (D) {
- assert(D->isCanonicalDecl() && "predefined decl is not canonical");
- DeclIDs[D] = ID;
- }
- };
- RegisterPredefDecl(Context.getTranslationUnitDecl(),
- PREDEF_DECL_TRANSLATION_UNIT_ID);
- RegisterPredefDecl(Context.ObjCIdDecl, PREDEF_DECL_OBJC_ID_ID);
- RegisterPredefDecl(Context.ObjCSelDecl, PREDEF_DECL_OBJC_SEL_ID);
- RegisterPredefDecl(Context.ObjCClassDecl, PREDEF_DECL_OBJC_CLASS_ID);
- RegisterPredefDecl(Context.ObjCProtocolClassDecl,
- PREDEF_DECL_OBJC_PROTOCOL_ID);
- RegisterPredefDecl(Context.Int128Decl, PREDEF_DECL_INT_128_ID);
- RegisterPredefDecl(Context.UInt128Decl, PREDEF_DECL_UNSIGNED_INT_128_ID);
- RegisterPredefDecl(Context.ObjCInstanceTypeDecl,
- PREDEF_DECL_OBJC_INSTANCETYPE_ID);
- RegisterPredefDecl(Context.BuiltinVaListDecl, PREDEF_DECL_BUILTIN_VA_LIST_ID);
- RegisterPredefDecl(Context.VaListTagDecl, PREDEF_DECL_VA_LIST_TAG);
- RegisterPredefDecl(Context.BuiltinMSVaListDecl,
- PREDEF_DECL_BUILTIN_MS_VA_LIST_ID);
- RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID);
- RegisterPredefDecl(Context.MakeIntegerSeqDecl,
- PREDEF_DECL_MAKE_INTEGER_SEQ_ID);
- RegisterPredefDecl(Context.CFConstantStringTypeDecl,
- PREDEF_DECL_CF_CONSTANT_STRING_ID);
- RegisterPredefDecl(Context.CFConstantStringTagDecl,
- PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID);
- RegisterPredefDecl(Context.TypePackElementDecl,
- PREDEF_DECL_TYPE_PACK_ELEMENT_ID);
-
- // Build a record containing all of the tentative definitions in this file, in
- // TentativeDefinitions order. Generally, this record will be empty for
- // headers.
- RecordData TentativeDefinitions;
- AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions);
-
- // Build a record containing all of the file scoped decls in this file.
- RecordData UnusedFileScopedDecls;
- if (!isModule)
- AddLazyVectorDecls(*this, SemaRef.UnusedFileScopedDecls,
- UnusedFileScopedDecls);
-
- // Build a record containing all of the delegating constructors we still need
- // to resolve.
- RecordData DelegatingCtorDecls;
- if (!isModule)
- AddLazyVectorDecls(*this, SemaRef.DelegatingCtorDecls, DelegatingCtorDecls);
-
- // Write the set of weak, undeclared identifiers. We always write the
- // entire table, since later PCH files in a PCH chain are only interested in
- // the results at the end of the chain.
- RecordData WeakUndeclaredIdentifiers;
- for (auto &WeakUndeclaredIdentifier : SemaRef.WeakUndeclaredIdentifiers) {
- IdentifierInfo *II = WeakUndeclaredIdentifier.first;
- WeakInfo &WI = WeakUndeclaredIdentifier.second;
- AddIdentifierRef(II, WeakUndeclaredIdentifiers);
- AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers);
- AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers);
- WeakUndeclaredIdentifiers.push_back(WI.getUsed());
- }
-
- // Build a record containing all of the ext_vector declarations.
- RecordData ExtVectorDecls;
- AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
-
- // Build a record containing all of the VTable uses information.
- RecordData VTableUses;
- if (!SemaRef.VTableUses.empty()) {
- for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
- AddDeclRef(SemaRef.VTableUses[I].first, VTableUses);
- AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
- VTableUses.push_back(SemaRef.VTablesUsed[SemaRef.VTableUses[I].first]);
- }
- }
-
- // Build a record containing all of the UnusedLocalTypedefNameCandidates.
- RecordData UnusedLocalTypedefNameCandidates;
- for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
- AddDeclRef(TD, UnusedLocalTypedefNameCandidates);
-
- // Build a record containing all of pending implicit instantiations.
- RecordData PendingInstantiations;
- for (const auto &I : SemaRef.PendingInstantiations) {
- AddDeclRef(I.first, PendingInstantiations);
- AddSourceLocation(I.second, PendingInstantiations);
- }
- assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
- "There are local ones at end of translation unit!");
-
- // Build a record containing some declaration references.
- RecordData SemaDeclRefs;
- if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
- AddDeclRef(SemaRef.getStdNamespace(), SemaDeclRefs);
- AddDeclRef(SemaRef.getStdBadAlloc(), SemaDeclRefs);
- AddDeclRef(SemaRef.getStdAlignValT(), SemaDeclRefs);
- }
-
- RecordData CUDASpecialDeclRefs;
- if (Context.getcudaConfigureCallDecl()) {
- AddDeclRef(Context.getcudaConfigureCallDecl(), CUDASpecialDeclRefs);
- }
-
- // Build a record containing all of the known namespaces.
- RecordData KnownNamespaces;
- for (const auto &I : SemaRef.KnownNamespaces) {
- if (!I.second)
- AddDeclRef(I.first, KnownNamespaces);
- }
-
- // Build a record of all used, undefined objects that require definitions.
- RecordData UndefinedButUsed;
-
- SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
- SemaRef.getUndefinedButUsed(Undefined);
- for (const auto &I : Undefined) {
- AddDeclRef(I.first, UndefinedButUsed);
- AddSourceLocation(I.second, UndefinedButUsed);
- }
-
- // Build a record containing all delete-expressions that we would like to
- // analyze later in AST.
- RecordData DeleteExprsToAnalyze;
-
- if (!isModule) {
- for (const auto &DeleteExprsInfo :
- SemaRef.getMismatchingDeleteExpressions()) {
- AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze);
- DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size());
- for (const auto &DeleteLoc : DeleteExprsInfo.second) {
- AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze);
- DeleteExprsToAnalyze.push_back(DeleteLoc.second);
- }
- }
- }
-
- // Write the control block
- WriteControlBlock(PP, Context, isysroot, OutputFile);
-
- // Write the remaining AST contents.
- Stream.EnterSubblock(AST_BLOCK_ID, 5);
-
- // This is so that older clang versions, before the introduction
- // of the control block, can read and reject the newer PCH format.
- {
- RecordData Record = {VERSION_MAJOR};
- Stream.EmitRecord(METADATA_OLD_FORMAT, Record);
- }
-
- // Create a lexical update block containing all of the declarations in the
- // translation unit that do not come from other AST files.
- const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
- SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
- for (const auto *D : TU->noload_decls()) {
- if (!D->isFromASTFile()) {
- NewGlobalKindDeclPairs.push_back(D->getKind());
- NewGlobalKindDeclPairs.push_back(GetDeclRef(D));
- }
- }
-
- auto Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
- unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
- {
- RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
- Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
- bytes(NewGlobalKindDeclPairs));
- }
-
- // And a visible updates block for the translation unit.
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
- Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
- UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
- WriteDeclContextVisibleUpdate(TU);
-
- // If we have any extern "C" names, write out a visible update for them.
- if (Context.ExternCContext)
- WriteDeclContextVisibleUpdate(Context.ExternCContext);
-
- // If the translation unit has an anonymous namespace, and we don't already
- // have an update block for it, write it as an update block.
- // FIXME: Why do we not do this if there's already an update block?
- if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
- ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
- if (Record.empty())
- Record.push_back(DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS));
- }
-
- // Add update records for all mangling numbers and static local numbers.
- // These aren't really update records, but this is a convenient way of
- // tagging this rare extra data onto the declarations.
- for (const auto &Number : Context.MangleNumbers)
- if (!Number.first->isFromASTFile())
- DeclUpdates[Number.first].push_back(DeclUpdate(UPD_MANGLING_NUMBER,
- Number.second));
- for (const auto &Number : Context.StaticLocalNumbers)
- if (!Number.first->isFromASTFile())
- DeclUpdates[Number.first].push_back(DeclUpdate(UPD_STATIC_LOCAL_NUMBER,
- Number.second));
-
- // Make sure visible decls, added to DeclContexts previously loaded from
- // an AST file, are registered for serialization. Likewise for template
- // specializations added to imported templates.
- for (const auto *I : DeclsToEmitEvenIfUnreferenced) {
- GetDeclRef(I);
- }
-
- // Make sure all decls associated with an identifier are registered for
- // serialization, if we're storing decls with identifiers.
- if (!WritingModule || !getLangOpts().CPlusPlus) {
- llvm::SmallVector<const IdentifierInfo*, 256> IIs;
- for (const auto &ID : PP.getIdentifierTable()) {
- const IdentifierInfo *II = ID.second;
- if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization())
- IIs.push_back(II);
- }
- // Sort the identifiers to visit based on their name.
- llvm::sort(IIs, llvm::less_ptr<IdentifierInfo>());
- for (const IdentifierInfo *II : IIs) {
- for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II),
- DEnd = SemaRef.IdResolver.end();
- D != DEnd; ++D) {
- GetDeclRef(*D);
- }
- }
- }
-
- // For method pool in the module, if it contains an entry for a selector,
- // the entry should be complete, containing everything introduced by that
- // module and all modules it imports. It's possible that the entry is out of
- // date, so we need to pull in the new content here.
-
- // It's possible that updateOutOfDateSelector can update SelectorIDs. To be
- // safe, we copy all selectors out.
- llvm::SmallVector<Selector, 256> AllSelectors;
- for (auto &SelectorAndID : SelectorIDs)
- AllSelectors.push_back(SelectorAndID.first);
- for (auto &Selector : AllSelectors)
- SemaRef.updateOutOfDateSelector(Selector);
-
- // Form the record of special types.
- RecordData SpecialTypes;
- AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
- AddTypeRef(Context.getFILEType(), SpecialTypes);
- AddTypeRef(Context.getjmp_bufType(), SpecialTypes);
- AddTypeRef(Context.getsigjmp_bufType(), SpecialTypes);
- AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes);
- AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes);
- AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
- AddTypeRef(Context.getucontext_tType(), SpecialTypes);
-
- if (Chain) {
- // Write the mapping information describing our module dependencies and how
- // each of those modules were mapped into our own offset/ID space, so that
- // the reader can build the appropriate mapping to its own offset/ID space.
- // The map consists solely of a blob with the following format:
- // *(module-kind:i8
- // module-name-len:i16 module-name:len*i8
- // source-location-offset:i32
- // identifier-id:i32
- // preprocessed-entity-id:i32
- // macro-definition-id:i32
- // submodule-id:i32
- // selector-id:i32
- // declaration-id:i32
- // c++-base-specifiers-id:i32
- // type-id:i32)
- //
- // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or
- // MK_ExplicitModule, then the module-name is the module name. Otherwise,
- // it is the module file name.
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
- SmallString<2048> Buffer;
- {
- llvm::raw_svector_ostream Out(Buffer);
- for (ModuleFile &M : Chain->ModuleMgr) {
- using namespace llvm::support;
-
- endian::Writer LE(Out, little);
- LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
- StringRef Name =
- M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule
- ? M.ModuleName
- : M.FileName;
- LE.write<uint16_t>(Name.size());
- Out.write(Name.data(), Name.size());
-
- // Note: if a base ID was uint max, it would not be possible to load
- // another module after it or have more than one entity inside it.
- uint32_t None = std::numeric_limits<uint32_t>::max();
-
- auto writeBaseIDOrNone = [&](uint32_t BaseID, bool ShouldWrite) {
- assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high");
- if (ShouldWrite)
- LE.write<uint32_t>(BaseID);
- else
- LE.write<uint32_t>(None);
- };
-
- // These values should be unique within a chain, since they will be read
- // as keys into ContinuousRangeMaps.
- writeBaseIDOrNone(M.SLocEntryBaseOffset, M.LocalNumSLocEntries);
- writeBaseIDOrNone(M.BaseIdentifierID, M.LocalNumIdentifiers);
- writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros);
- writeBaseIDOrNone(M.BasePreprocessedEntityID,
- M.NumPreprocessedEntities);
- writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
- writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
- writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls);
- writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes);
- }
- }
- RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
- Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
- Buffer.data(), Buffer.size());
- }
-
- RecordData DeclUpdatesOffsetsRecord;
-
- // Keep writing types, declarations, and declaration update records
- // until we've emitted all of them.
- Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5);
- WriteTypeAbbrevs();
- WriteDeclAbbrevs();
- do {
- WriteDeclUpdatesBlocks(DeclUpdatesOffsetsRecord);
- while (!DeclTypesToEmit.empty()) {
- DeclOrType DOT = DeclTypesToEmit.front();
- DeclTypesToEmit.pop();
- if (DOT.isType())
- WriteType(DOT.getType());
- else
- WriteDecl(Context, DOT.getDecl());
- }
- } while (!DeclUpdates.empty());
- Stream.ExitBlock();
-
- DoneWritingDeclsAndTypes = true;
-
- // These things can only be done once we've written out decls and types.
- WriteTypeDeclOffsets();
- if (!DeclUpdatesOffsetsRecord.empty())
- Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
- WriteFileDeclIDsMap();
- WriteSourceManagerBlock(Context.getSourceManager(), PP);
- WriteComments();
- WritePreprocessor(PP, isModule);
- WriteHeaderSearch(PP.getHeaderSearchInfo());
- WriteSelectors(SemaRef);
- WriteReferencedSelectorsPool(SemaRef);
- WriteLateParsedTemplates(SemaRef);
- WriteIdentifierTable(PP, SemaRef.IdResolver, isModule);
- WriteFPPragmaOptions(SemaRef.getFPOptions());
- WriteOpenCLExtensions(SemaRef);
- WriteOpenCLExtensionTypes(SemaRef);
- WriteCUDAPragmas(SemaRef);
-
- // If we're emitting a module, write out the submodule information.
- if (WritingModule)
- WriteSubmodules(WritingModule);
-
- // We need to have information about submodules to correctly deserialize
- // decls from OpenCLExtensionDecls block
- WriteOpenCLExtensionDecls(SemaRef);
-
- Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
-
- // Write the record containing external, unnamed definitions.
- if (!EagerlyDeserializedDecls.empty())
- Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
-
- if (!ModularCodegenDecls.empty())
- Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls);
-
- // Write the record containing tentative definitions.
- if (!TentativeDefinitions.empty())
- Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
-
- // Write the record containing unused file scoped decls.
- if (!UnusedFileScopedDecls.empty())
- Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
-
- // Write the record containing weak undeclared identifiers.
- if (!WeakUndeclaredIdentifiers.empty())
- Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
- WeakUndeclaredIdentifiers);
-
- // Write the record containing ext_vector type names.
- if (!ExtVectorDecls.empty())
- Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
-
- // Write the record containing VTable uses information.
- if (!VTableUses.empty())
- Stream.EmitRecord(VTABLE_USES, VTableUses);
-
- // Write the record containing potentially unused local typedefs.
- if (!UnusedLocalTypedefNameCandidates.empty())
- Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
- UnusedLocalTypedefNameCandidates);
-
- // Write the record containing pending implicit instantiations.
- if (!PendingInstantiations.empty())
- Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
-
- // Write the record containing declaration references of Sema.
- if (!SemaDeclRefs.empty())
- Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
-
- // Write the record containing CUDA-specific declaration references.
- if (!CUDASpecialDeclRefs.empty())
- Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs);
-
- // Write the delegating constructors.
- if (!DelegatingCtorDecls.empty())
- Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
-
- // Write the known namespaces.
- if (!KnownNamespaces.empty())
- Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
-
- // Write the undefined internal functions and variables, and inline functions.
- if (!UndefinedButUsed.empty())
- Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
-
- if (!DeleteExprsToAnalyze.empty())
- Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
-
- // Write the visible updates to DeclContexts.
- for (auto *DC : UpdatedDeclContexts)
- WriteDeclContextVisibleUpdate(DC);
-
- if (!WritingModule) {
- // Write the submodules that were imported, if any.
- struct ModuleInfo {
- uint64_t ID;
- Module *M;
- ModuleInfo(uint64_t ID, Module *M) : ID(ID), M(M) {}
- };
- llvm::SmallVector<ModuleInfo, 64> Imports;
- for (const auto *I : Context.local_imports()) {
- assert(SubmoduleIDs.find(I->getImportedModule()) != SubmoduleIDs.end());
- Imports.push_back(ModuleInfo(SubmoduleIDs[I->getImportedModule()],
- I->getImportedModule()));
- }
-
- if (!Imports.empty()) {
- auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
- return A.ID < B.ID;
- };
- auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) {
- return A.ID == B.ID;
- };
-
- // Sort and deduplicate module IDs.
- llvm::sort(Imports, Cmp);
- Imports.erase(std::unique(Imports.begin(), Imports.end(), Eq),
- Imports.end());
-
- RecordData ImportedModules;
- for (const auto &Import : Imports) {
- ImportedModules.push_back(Import.ID);
- // FIXME: If the module has macros imported then later has declarations
- // imported, this location won't be the right one as a location for the
- // declaration imports.
- AddSourceLocation(PP.getModuleImportLoc(Import.M), ImportedModules);
- }
-
- Stream.EmitRecord(IMPORTED_MODULES, ImportedModules);
- }
- }
-
- WriteObjCCategories();
- if(!WritingModule) {
- WriteOptimizePragmaOptions(SemaRef);
- WriteMSStructPragmaOptions(SemaRef);
- WriteMSPointersToMembersPragmaOptions(SemaRef);
- }
- WritePackPragmaOptions(SemaRef);
-
- // Some simple statistics
- RecordData::value_type Record[] = {
- NumStatements, NumMacros, NumLexicalDeclContexts, NumVisibleDeclContexts};
- Stream.EmitRecord(STATISTICS, Record);
- Stream.ExitBlock();
-
- // Write the module file extension blocks.
- for (const auto &ExtWriter : ModuleFileExtensionWriters)
- WriteModuleFileExtension(SemaRef, *ExtWriter);
-
- return writeUnhashedControlBlock(PP, Context);
-}
-
-void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
- if (DeclUpdates.empty())
- return;
-
- DeclUpdateMap LocalUpdates;
- LocalUpdates.swap(DeclUpdates);
-
- for (auto &DeclUpdate : LocalUpdates) {
- const Decl *D = DeclUpdate.first;
-
- bool HasUpdatedBody = false;
- RecordData RecordData;
- ASTRecordWriter Record(*this, RecordData);
- for (auto &Update : DeclUpdate.second) {
- DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind();
-
- // An updated body is emitted last, so that the reader doesn't need
- // to skip over the lazy body to reach statements for other records.
- if (Kind == UPD_CXX_ADDED_FUNCTION_DEFINITION)
- HasUpdatedBody = true;
- else
- Record.push_back(Kind);
-
- switch (Kind) {
- case UPD_CXX_ADDED_IMPLICIT_MEMBER:
- case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
- case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
- assert(Update.getDecl() && "no decl to add?");
- Record.push_back(GetDeclRef(Update.getDecl()));
- break;
-
- case UPD_CXX_ADDED_FUNCTION_DEFINITION:
- break;
-
- case UPD_CXX_POINT_OF_INSTANTIATION:
- // FIXME: Do we need to also save the template specialization kind here?
- Record.AddSourceLocation(Update.getLoc());
- break;
-
- case UPD_CXX_ADDED_VAR_DEFINITION: {
- const VarDecl *VD = cast<VarDecl>(D);
- Record.push_back(VD->isInline());
- Record.push_back(VD->isInlineSpecified());
- if (VD->getInit()) {
- Record.push_back(!VD->isInitKnownICE() ? 1
- : (VD->isInitICE() ? 3 : 2));
- Record.AddStmt(const_cast<Expr*>(VD->getInit()));
- } else {
- Record.push_back(0);
- }
- break;
- }
-
- case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT:
- Record.AddStmt(const_cast<Expr *>(
- cast<ParmVarDecl>(Update.getDecl())->getDefaultArg()));
- break;
-
- case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER:
- Record.AddStmt(
- cast<FieldDecl>(Update.getDecl())->getInClassInitializer());
- break;
-
- case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
- auto *RD = cast<CXXRecordDecl>(D);
- UpdatedDeclContexts.insert(RD->getPrimaryContext());
- Record.push_back(RD->isParamDestroyedInCallee());
- Record.push_back(RD->getArgPassingRestrictions());
- Record.AddCXXDefinitionData(RD);
- Record.AddOffset(WriteDeclContextLexicalBlock(
- *Context, const_cast<CXXRecordDecl *>(RD)));
-
- // This state is sometimes updated by template instantiation, when we
- // switch from the specialization referring to the template declaration
- // to it referring to the template definition.
- if (auto *MSInfo = RD->getMemberSpecializationInfo()) {
- Record.push_back(MSInfo->getTemplateSpecializationKind());
- Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
- } else {
- auto *Spec = cast<ClassTemplateSpecializationDecl>(RD);
- Record.push_back(Spec->getTemplateSpecializationKind());
- Record.AddSourceLocation(Spec->getPointOfInstantiation());
-
- // The instantiation might have been resolved to a partial
- // specialization. If so, record which one.
- auto From = Spec->getInstantiatedFrom();
- if (auto PartialSpec =
- From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
- Record.push_back(true);
- Record.AddDeclRef(PartialSpec);
- Record.AddTemplateArgumentList(
- &Spec->getTemplateInstantiationArgs());
- } else {
- Record.push_back(false);
- }
- }
- Record.push_back(RD->getTagKind());
- Record.AddSourceLocation(RD->getLocation());
- Record.AddSourceLocation(RD->getBeginLoc());
- Record.AddSourceRange(RD->getBraceRange());
-
- // Instantiation may change attributes; write them all out afresh.
- Record.push_back(D->hasAttrs());
- if (D->hasAttrs())
- Record.AddAttributes(D->getAttrs());
-
- // FIXME: Ensure we don't get here for explicit instantiations.
- break;
- }
-
- case UPD_CXX_RESOLVED_DTOR_DELETE:
- Record.AddDeclRef(Update.getDecl());
- Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg());
- break;
-
- case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
- addExceptionSpec(
- cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(),
- Record);
- break;
-
- case UPD_CXX_DEDUCED_RETURN_TYPE:
- Record.push_back(GetOrCreateTypeID(Update.getType()));
- break;
-
- case UPD_DECL_MARKED_USED:
- break;
-
- case UPD_MANGLING_NUMBER:
- case UPD_STATIC_LOCAL_NUMBER:
- Record.push_back(Update.getNumber());
- break;
-
- case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
- Record.AddSourceRange(
- D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
- break;
-
- case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
- Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType());
- Record.AddSourceRange(
- D->getAttr<OMPDeclareTargetDeclAttr>()->getRange());
- break;
-
- case UPD_DECL_EXPORTED:
- Record.push_back(getSubmoduleID(Update.getModule()));
- break;
-
- case UPD_ADDED_ATTR_TO_RECORD:
- Record.AddAttributes(llvm::makeArrayRef(Update.getAttr()));
- break;
- }
- }
-
- if (HasUpdatedBody) {
- const auto *Def = cast<FunctionDecl>(D);
- Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);
- Record.push_back(Def->isInlined());
- Record.AddSourceLocation(Def->getInnerLocStart());
- Record.AddFunctionDefinition(Def);
- }
-
- OffsetsRecord.push_back(GetDeclRef(D));
- OffsetsRecord.push_back(Record.Emit(DECL_UPDATES));
- }
-}
-
-void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) {
- uint32_t Raw = Loc.getRawEncoding();
- Record.push_back((Raw << 1) | (Raw >> 31));
-}
-
-void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) {
- AddSourceLocation(Range.getBegin(), Record);
- AddSourceLocation(Range.getEnd(), Record);
-}
-
-void ASTRecordWriter::AddAPInt(const llvm::APInt &Value) {
- Record->push_back(Value.getBitWidth());
- const uint64_t *Words = Value.getRawData();
- Record->append(Words, Words + Value.getNumWords());
-}
-
-void ASTRecordWriter::AddAPSInt(const llvm::APSInt &Value) {
- Record->push_back(Value.isUnsigned());
- AddAPInt(Value);
-}
-
-void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) {
- AddAPInt(Value.bitcastToAPInt());
-}
-
-void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) {
- Record.push_back(getIdentifierRef(II));
-}
-
-IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
- if (!II)
- return 0;
-
- IdentID &ID = IdentifierIDs[II];
- if (ID == 0)
- ID = NextIdentID++;
- return ID;
-}
-
-MacroID ASTWriter::getMacroRef(MacroInfo *MI, const IdentifierInfo *Name) {
- // Don't emit builtin macros like __LINE__ to the AST file unless they
- // have been redefined by the header (in which case they are not
- // isBuiltinMacro).
- if (!MI || MI->isBuiltinMacro())
- return 0;
-
- MacroID &ID = MacroIDs[MI];
- if (ID == 0) {
- ID = NextMacroID++;
- MacroInfoToEmitData Info = { Name, MI, ID };
- MacroInfosToEmit.push_back(Info);
- }
- return ID;
-}
-
-MacroID ASTWriter::getMacroID(MacroInfo *MI) {
- if (!MI || MI->isBuiltinMacro())
- return 0;
-
- assert(MacroIDs.find(MI) != MacroIDs.end() && "Macro not emitted!");
- return MacroIDs[MI];
-}
-
-uint64_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) {
- return IdentMacroDirectivesOffsetMap.lookup(Name);
-}
-
-void ASTRecordWriter::AddSelectorRef(const Selector SelRef) {
- Record->push_back(Writer->getSelectorRef(SelRef));
-}
-
-SelectorID ASTWriter::getSelectorRef(Selector Sel) {
- if (Sel.getAsOpaquePtr() == nullptr) {
- return 0;
- }
-
- SelectorID SID = SelectorIDs[Sel];
- if (SID == 0 && Chain) {
- // This might trigger a ReadSelector callback, which will set the ID for
- // this selector.
- Chain->LoadSelector(Sel);
- SID = SelectorIDs[Sel];
- }
- if (SID == 0) {
- SID = NextSelectorID++;
- SelectorIDs[Sel] = SID;
- }
- return SID;
-}
-
-void ASTRecordWriter::AddCXXTemporary(const CXXTemporary *Temp) {
- AddDeclRef(Temp->getDestructor());
-}
-
-void ASTRecordWriter::AddTemplateArgumentLocInfo(
- TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg) {
- switch (Kind) {
- case TemplateArgument::Expression:
- AddStmt(Arg.getAsExpr());
- break;
- case TemplateArgument::Type:
- AddTypeSourceInfo(Arg.getAsTypeSourceInfo());
- break;
- case TemplateArgument::Template:
- AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc());
- AddSourceLocation(Arg.getTemplateNameLoc());
- break;
- case TemplateArgument::TemplateExpansion:
- AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc());
- AddSourceLocation(Arg.getTemplateNameLoc());
- AddSourceLocation(Arg.getTemplateEllipsisLoc());
- break;
- case TemplateArgument::Null:
- case TemplateArgument::Integral:
- case TemplateArgument::Declaration:
- case TemplateArgument::NullPtr:
- case TemplateArgument::Pack:
- // FIXME: Is this right?
- break;
- }
-}
-
-void ASTRecordWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) {
- AddTemplateArgument(Arg.getArgument());
-
- if (Arg.getArgument().getKind() == TemplateArgument::Expression) {
- bool InfoHasSameExpr
- = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
- Record->push_back(InfoHasSameExpr);
- if (InfoHasSameExpr)
- return; // Avoid storing the same expr twice.
- }
- AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo());
-}
-
-void ASTRecordWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo) {
- if (!TInfo) {
- AddTypeRef(QualType());
- return;
- }
-
- AddTypeRef(TInfo->getType());
- AddTypeLoc(TInfo->getTypeLoc());
-}
-
-void ASTRecordWriter::AddTypeLoc(TypeLoc TL) {
- TypeLocWriter TLW(*this);
- for (; !TL.isNull(); TL = TL.getNextTypeLoc())
- TLW.Visit(TL);
-}
-
-void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) {
- Record.push_back(GetOrCreateTypeID(T));
-}
-
-TypeID ASTWriter::GetOrCreateTypeID(QualType T) {
- assert(Context);
- return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx {
- if (T.isNull())
- return TypeIdx();
- assert(!T.getLocalFastQualifiers());
-
- TypeIdx &Idx = TypeIdxs[T];
- if (Idx.getIndex() == 0) {
- if (DoneWritingDeclsAndTypes) {
- assert(0 && "New type seen after serializing all the types to emit!");
- return TypeIdx();
- }
-
- // We haven't seen this type before. Assign it a new ID and put it
- // into the queue of types to emit.
- Idx = TypeIdx(NextTypeID++);
- DeclTypesToEmit.push(T);
- }
- return Idx;
- });
-}
-
-TypeID ASTWriter::getTypeID(QualType T) const {
- assert(Context);
- return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx {
- if (T.isNull())
- return TypeIdx();
- assert(!T.getLocalFastQualifiers());
-
- TypeIdxMap::const_iterator I = TypeIdxs.find(T);
- assert(I != TypeIdxs.end() && "Type not emitted!");
- return I->second;
- });
-}
-
-void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
- Record.push_back(GetDeclRef(D));
-}
-
-DeclID ASTWriter::GetDeclRef(const Decl *D) {
- assert(WritingAST && "Cannot request a declaration ID before AST writing");
-
- if (!D) {
- return 0;
- }
-
- // If D comes from an AST file, its declaration ID is already known and
- // fixed.
- if (D->isFromASTFile())
- return D->getGlobalID();
-
- assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
- DeclID &ID = DeclIDs[D];
- if (ID == 0) {
- if (DoneWritingDeclsAndTypes) {
- assert(0 && "New decl seen after serializing all the decls to emit!");
- return 0;
- }
-
- // We haven't seen this declaration before. Give it a new ID and
- // enqueue it in the list of declarations to emit.
- ID = NextDeclID++;
- DeclTypesToEmit.push(const_cast<Decl *>(D));
- }
-
- return ID;
-}
-
-DeclID ASTWriter::getDeclID(const Decl *D) {
- if (!D)
- return 0;
-
- // If D comes from an AST file, its declaration ID is already known and
- // fixed.
- if (D->isFromASTFile())
- return D->getGlobalID();
-
- assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!");
- return DeclIDs[D];
-}
-
-void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) {
- assert(ID);
- assert(D);
-
- SourceLocation Loc = D->getLocation();
- if (Loc.isInvalid())
- return;
-
- // We only keep track of the file-level declarations of each file.
- if (!D->getLexicalDeclContext()->isFileContext())
- return;
- // FIXME: ParmVarDecls that are part of a function type of a parameter of
- // a function/objc method, should not have TU as lexical context.
- // TemplateTemplateParmDecls that are part of an alias template, should not
- // have TU as lexical context.
- if (isa<ParmVarDecl>(D) || isa<TemplateTemplateParmDecl>(D))
- return;
-
- SourceManager &SM = Context->getSourceManager();
- SourceLocation FileLoc = SM.getFileLoc(Loc);
- assert(SM.isLocalSourceLocation(FileLoc));
- FileID FID;
- unsigned Offset;
- std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
- if (FID.isInvalid())
- return;
- assert(SM.getSLocEntry(FID).isFile());
-
- DeclIDInFileInfo *&Info = FileDeclIDs[FID];
- if (!Info)
- Info = new DeclIDInFileInfo();
-
- std::pair<unsigned, serialization::DeclID> LocDecl(Offset, ID);
- LocDeclIDsTy &Decls = Info->DeclIDs;
-
- if (Decls.empty() || Decls.back().first <= Offset) {
- Decls.push_back(LocDecl);
- return;
- }
-
- LocDeclIDsTy::iterator I =
- std::upper_bound(Decls.begin(), Decls.end(), LocDecl, llvm::less_first());
-
- Decls.insert(I, LocDecl);
-}
-
-void ASTRecordWriter::AddDeclarationName(DeclarationName Name) {
- // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc.
- Record->push_back(Name.getNameKind());
- switch (Name.getNameKind()) {
- case DeclarationName::Identifier:
- AddIdentifierRef(Name.getAsIdentifierInfo());
- break;
-
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- AddSelectorRef(Name.getObjCSelector());
- break;
-
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- AddTypeRef(Name.getCXXNameType());
- break;
-
- case DeclarationName::CXXDeductionGuideName:
- AddDeclRef(Name.getCXXDeductionGuideTemplate());
- break;
-
- case DeclarationName::CXXOperatorName:
- Record->push_back(Name.getCXXOverloadedOperator());
- break;
-
- case DeclarationName::CXXLiteralOperatorName:
- AddIdentifierRef(Name.getCXXLiteralIdentifier());
- break;
-
- case DeclarationName::CXXUsingDirective:
- // No extra data to emit
- break;
- }
-}
-
-unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) {
- assert(needsAnonymousDeclarationNumber(D) &&
- "expected an anonymous declaration");
-
- // Number the anonymous declarations within this context, if we've not
- // already done so.
- auto It = AnonymousDeclarationNumbers.find(D);
- if (It == AnonymousDeclarationNumbers.end()) {
- auto *DC = D->getLexicalDeclContext();
- numberAnonymousDeclsWithin(DC, [&](const NamedDecl *ND, unsigned Number) {
- AnonymousDeclarationNumbers[ND] = Number;
- });
-
- It = AnonymousDeclarationNumbers.find(D);
- assert(It != AnonymousDeclarationNumbers.end() &&
- "declaration not found within its lexical context");
- }
-
- return It->second;
-}
-
-void ASTRecordWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
- DeclarationName Name) {
- switch (Name.getNameKind()) {
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- AddTypeSourceInfo(DNLoc.NamedType.TInfo);
- break;
-
- case DeclarationName::CXXOperatorName:
- AddSourceLocation(SourceLocation::getFromRawEncoding(
- DNLoc.CXXOperatorName.BeginOpNameLoc));
- AddSourceLocation(
- SourceLocation::getFromRawEncoding(DNLoc.CXXOperatorName.EndOpNameLoc));
- break;
-
- case DeclarationName::CXXLiteralOperatorName:
- AddSourceLocation(SourceLocation::getFromRawEncoding(
- DNLoc.CXXLiteralOperatorName.OpNameLoc));
- break;
-
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXUsingDirective:
- case DeclarationName::CXXDeductionGuideName:
- break;
- }
-}
-
-void ASTRecordWriter::AddDeclarationNameInfo(
- const DeclarationNameInfo &NameInfo) {
- AddDeclarationName(NameInfo.getName());
- AddSourceLocation(NameInfo.getLoc());
- AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName());
-}
-
-void ASTRecordWriter::AddQualifierInfo(const QualifierInfo &Info) {
- AddNestedNameSpecifierLoc(Info.QualifierLoc);
- Record->push_back(Info.NumTemplParamLists);
- for (unsigned i = 0, e = Info.NumTemplParamLists; i != e; ++i)
- AddTemplateParameterList(Info.TemplParamLists[i]);
-}
-
-void ASTRecordWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
- // Nested name specifiers usually aren't too long. I think that 8 would
- // typically accommodate the vast majority.
- SmallVector<NestedNameSpecifier *, 8> NestedNames;
-
- // Push each of the NNS's onto a stack for serialization in reverse order.
- while (NNS) {
- NestedNames.push_back(NNS);
- NNS = NNS->getPrefix();
- }
-
- Record->push_back(NestedNames.size());
- while(!NestedNames.empty()) {
- NNS = NestedNames.pop_back_val();
- NestedNameSpecifier::SpecifierKind Kind = NNS->getKind();
- Record->push_back(Kind);
- switch (Kind) {
- case NestedNameSpecifier::Identifier:
- AddIdentifierRef(NNS->getAsIdentifier());
- break;
-
- case NestedNameSpecifier::Namespace:
- AddDeclRef(NNS->getAsNamespace());
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- AddDeclRef(NNS->getAsNamespaceAlias());
- break;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- AddTypeRef(QualType(NNS->getAsType(), 0));
- Record->push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
- break;
-
- case NestedNameSpecifier::Global:
- // Don't need to write an associated value.
- break;
-
- case NestedNameSpecifier::Super:
- AddDeclRef(NNS->getAsRecordDecl());
- break;
- }
- }
-}
-
-void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
- // Nested name specifiers usually aren't too long. I think that 8 would
- // typically accommodate the vast majority.
- SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
-
- // Push each of the nested-name-specifiers's onto a stack for
- // serialization in reverse order.
- while (NNS) {
- NestedNames.push_back(NNS);
- NNS = NNS.getPrefix();
- }
-
- Record->push_back(NestedNames.size());
- while(!NestedNames.empty()) {
- NNS = NestedNames.pop_back_val();
- NestedNameSpecifier::SpecifierKind Kind
- = NNS.getNestedNameSpecifier()->getKind();
- Record->push_back(Kind);
- switch (Kind) {
- case NestedNameSpecifier::Identifier:
- AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
-
- case NestedNameSpecifier::Namespace:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- Record->push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
- AddTypeRef(NNS.getTypeLoc().getType());
- AddTypeLoc(NNS.getTypeLoc());
- AddSourceLocation(NNS.getLocalSourceRange().getEnd());
- break;
-
- case NestedNameSpecifier::Global:
- AddSourceLocation(NNS.getLocalSourceRange().getEnd());
- break;
-
- case NestedNameSpecifier::Super:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
- }
- }
-}
-
-void ASTRecordWriter::AddTemplateName(TemplateName Name) {
- TemplateName::NameKind Kind = Name.getKind();
- Record->push_back(Kind);
- switch (Kind) {
- case TemplateName::Template:
- AddDeclRef(Name.getAsTemplateDecl());
- break;
-
- case TemplateName::OverloadedTemplate: {
- OverloadedTemplateStorage *OvT = Name.getAsOverloadedTemplate();
- Record->push_back(OvT->size());
- for (const auto &I : *OvT)
- AddDeclRef(I);
- break;
- }
-
- case TemplateName::QualifiedTemplate: {
- QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName();
- AddNestedNameSpecifier(QualT->getQualifier());
- Record->push_back(QualT->hasTemplateKeyword());
- AddDeclRef(QualT->getTemplateDecl());
- break;
- }
-
- case TemplateName::DependentTemplate: {
- DependentTemplateName *DepT = Name.getAsDependentTemplateName();
- AddNestedNameSpecifier(DepT->getQualifier());
- Record->push_back(DepT->isIdentifier());
- if (DepT->isIdentifier())
- AddIdentifierRef(DepT->getIdentifier());
- else
- Record->push_back(DepT->getOperator());
- break;
- }
-
- case TemplateName::SubstTemplateTemplateParm: {
- SubstTemplateTemplateParmStorage *subst
- = Name.getAsSubstTemplateTemplateParm();
- AddDeclRef(subst->getParameter());
- AddTemplateName(subst->getReplacement());
- break;
- }
-
- case TemplateName::SubstTemplateTemplateParmPack: {
- SubstTemplateTemplateParmPackStorage *SubstPack
- = Name.getAsSubstTemplateTemplateParmPack();
- AddDeclRef(SubstPack->getParameterPack());
- AddTemplateArgument(SubstPack->getArgumentPack());
- break;
- }
- }
-}
-
-void ASTRecordWriter::AddTemplateArgument(const TemplateArgument &Arg) {
- Record->push_back(Arg.getKind());
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- break;
- case TemplateArgument::Type:
- AddTypeRef(Arg.getAsType());
- break;
- case TemplateArgument::Declaration:
- AddDeclRef(Arg.getAsDecl());
- AddTypeRef(Arg.getParamTypeForDecl());
- break;
- case TemplateArgument::NullPtr:
- AddTypeRef(Arg.getNullPtrType());
- break;
- case TemplateArgument::Integral:
- AddAPSInt(Arg.getAsIntegral());
- AddTypeRef(Arg.getIntegralType());
- break;
- case TemplateArgument::Template:
- AddTemplateName(Arg.getAsTemplateOrTemplatePattern());
- break;
- case TemplateArgument::TemplateExpansion:
- AddTemplateName(Arg.getAsTemplateOrTemplatePattern());
- if (Optional<unsigned> NumExpansions = Arg.getNumTemplateExpansions())
- Record->push_back(*NumExpansions + 1);
- else
- Record->push_back(0);
- break;
- case TemplateArgument::Expression:
- AddStmt(Arg.getAsExpr());
- break;
- case TemplateArgument::Pack:
- Record->push_back(Arg.pack_size());
- for (const auto &P : Arg.pack_elements())
- AddTemplateArgument(P);
- break;
- }
-}
-
-void ASTRecordWriter::AddTemplateParameterList(
- const TemplateParameterList *TemplateParams) {
- assert(TemplateParams && "No TemplateParams!");
- AddSourceLocation(TemplateParams->getTemplateLoc());
- AddSourceLocation(TemplateParams->getLAngleLoc());
- AddSourceLocation(TemplateParams->getRAngleLoc());
- // TODO: Concepts
- Record->push_back(TemplateParams->size());
- for (const auto &P : *TemplateParams)
- AddDeclRef(P);
-}
-
-/// Emit a template argument list.
-void ASTRecordWriter::AddTemplateArgumentList(
- const TemplateArgumentList *TemplateArgs) {
- assert(TemplateArgs && "No TemplateArgs!");
- Record->push_back(TemplateArgs->size());
- for (int i = 0, e = TemplateArgs->size(); i != e; ++i)
- AddTemplateArgument(TemplateArgs->get(i));
-}
-
-void ASTRecordWriter::AddASTTemplateArgumentListInfo(
- const ASTTemplateArgumentListInfo *ASTTemplArgList) {
- assert(ASTTemplArgList && "No ASTTemplArgList!");
- AddSourceLocation(ASTTemplArgList->LAngleLoc);
- AddSourceLocation(ASTTemplArgList->RAngleLoc);
- Record->push_back(ASTTemplArgList->NumTemplateArgs);
- const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs();
- for (int i = 0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i)
- AddTemplateArgumentLoc(TemplArgs[i]);
-}
-
-void ASTRecordWriter::AddUnresolvedSet(const ASTUnresolvedSet &Set) {
- Record->push_back(Set.size());
- for (ASTUnresolvedSet::const_iterator
- I = Set.begin(), E = Set.end(); I != E; ++I) {
- AddDeclRef(I.getDecl());
- Record->push_back(I.getAccess());
- }
-}
-
-// FIXME: Move this out of the main ASTRecordWriter interface.
-void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
- Record->push_back(Base.isVirtual());
- Record->push_back(Base.isBaseOfClass());
- Record->push_back(Base.getAccessSpecifierAsWritten());
- Record->push_back(Base.getInheritConstructors());
- AddTypeSourceInfo(Base.getTypeSourceInfo());
- AddSourceRange(Base.getSourceRange());
- AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc()
- : SourceLocation());
-}
-
-static uint64_t EmitCXXBaseSpecifiers(ASTWriter &W,
- ArrayRef<CXXBaseSpecifier> Bases) {
- ASTWriter::RecordData Record;
- ASTRecordWriter Writer(W, Record);
- Writer.push_back(Bases.size());
-
- for (auto &Base : Bases)
- Writer.AddCXXBaseSpecifier(Base);
-
- return Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS);
-}
-
-// FIXME: Move this out of the main ASTRecordWriter interface.
-void ASTRecordWriter::AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases) {
- AddOffset(EmitCXXBaseSpecifiers(*Writer, Bases));
-}
-
-static uint64_t
-EmitCXXCtorInitializers(ASTWriter &W,
- ArrayRef<CXXCtorInitializer *> CtorInits) {
- ASTWriter::RecordData Record;
- ASTRecordWriter Writer(W, Record);
- Writer.push_back(CtorInits.size());
-
- for (auto *Init : CtorInits) {
- if (Init->isBaseInitializer()) {
- Writer.push_back(CTOR_INITIALIZER_BASE);
- Writer.AddTypeSourceInfo(Init->getTypeSourceInfo());
- Writer.push_back(Init->isBaseVirtual());
- } else if (Init->isDelegatingInitializer()) {
- Writer.push_back(CTOR_INITIALIZER_DELEGATING);
- Writer.AddTypeSourceInfo(Init->getTypeSourceInfo());
- } else if (Init->isMemberInitializer()){
- Writer.push_back(CTOR_INITIALIZER_MEMBER);
- Writer.AddDeclRef(Init->getMember());
- } else {
- Writer.push_back(CTOR_INITIALIZER_INDIRECT_MEMBER);
- Writer.AddDeclRef(Init->getIndirectMember());
- }
-
- Writer.AddSourceLocation(Init->getMemberLocation());
- Writer.AddStmt(Init->getInit());
- Writer.AddSourceLocation(Init->getLParenLoc());
- Writer.AddSourceLocation(Init->getRParenLoc());
- Writer.push_back(Init->isWritten());
- if (Init->isWritten())
- Writer.push_back(Init->getSourceOrder());
- }
-
- return Writer.Emit(serialization::DECL_CXX_CTOR_INITIALIZERS);
-}
-
-// FIXME: Move this out of the main ASTRecordWriter interface.
-void ASTRecordWriter::AddCXXCtorInitializers(
- ArrayRef<CXXCtorInitializer *> CtorInits) {
- AddOffset(EmitCXXCtorInitializers(*Writer, CtorInits));
-}
-
-void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
- auto &Data = D->data();
- Record->push_back(Data.IsLambda);
- Record->push_back(Data.UserDeclaredConstructor);
- Record->push_back(Data.UserDeclaredSpecialMembers);
- Record->push_back(Data.Aggregate);
- Record->push_back(Data.PlainOldData);
- Record->push_back(Data.Empty);
- Record->push_back(Data.Polymorphic);
- Record->push_back(Data.Abstract);
- Record->push_back(Data.IsStandardLayout);
- Record->push_back(Data.IsCXX11StandardLayout);
- Record->push_back(Data.HasBasesWithFields);
- Record->push_back(Data.HasBasesWithNonStaticDataMembers);
- Record->push_back(Data.HasPrivateFields);
- Record->push_back(Data.HasProtectedFields);
- Record->push_back(Data.HasPublicFields);
- Record->push_back(Data.HasMutableFields);
- Record->push_back(Data.HasVariantMembers);
- Record->push_back(Data.HasOnlyCMembers);
- Record->push_back(Data.HasInClassInitializer);
- Record->push_back(Data.HasUninitializedReferenceMember);
- Record->push_back(Data.HasUninitializedFields);
- Record->push_back(Data.HasInheritedConstructor);
- Record->push_back(Data.HasInheritedAssignment);
- Record->push_back(Data.NeedOverloadResolutionForCopyConstructor);
- Record->push_back(Data.NeedOverloadResolutionForMoveConstructor);
- Record->push_back(Data.NeedOverloadResolutionForMoveAssignment);
- Record->push_back(Data.NeedOverloadResolutionForDestructor);
- Record->push_back(Data.DefaultedCopyConstructorIsDeleted);
- Record->push_back(Data.DefaultedMoveConstructorIsDeleted);
- Record->push_back(Data.DefaultedMoveAssignmentIsDeleted);
- Record->push_back(Data.DefaultedDestructorIsDeleted);
- Record->push_back(Data.HasTrivialSpecialMembers);
- Record->push_back(Data.HasTrivialSpecialMembersForCall);
- Record->push_back(Data.DeclaredNonTrivialSpecialMembers);
- Record->push_back(Data.DeclaredNonTrivialSpecialMembersForCall);
- Record->push_back(Data.HasIrrelevantDestructor);
- Record->push_back(Data.HasConstexprNonCopyMoveConstructor);
- Record->push_back(Data.HasDefaultedDefaultConstructor);
- Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr);
- Record->push_back(Data.HasConstexprDefaultConstructor);
- Record->push_back(Data.HasNonLiteralTypeFieldsOrBases);
- Record->push_back(Data.ComputedVisibleConversions);
- Record->push_back(Data.UserProvidedDefaultConstructor);
- Record->push_back(Data.DeclaredSpecialMembers);
- Record->push_back(Data.ImplicitCopyConstructorCanHaveConstParamForVBase);
- Record->push_back(Data.ImplicitCopyConstructorCanHaveConstParamForNonVBase);
- Record->push_back(Data.ImplicitCopyAssignmentHasConstParam);
- Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam);
- Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam);
-
- // getODRHash will compute the ODRHash if it has not been previously computed.
- Record->push_back(D->getODRHash());
- bool ModulesDebugInfo = Writer->Context->getLangOpts().ModulesDebugInfo &&
- Writer->WritingModule && !D->isDependentType();
- Record->push_back(ModulesDebugInfo);
- if (ModulesDebugInfo)
- Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D));
-
- // IsLambda bit is already saved.
-
- Record->push_back(Data.NumBases);
- if (Data.NumBases > 0)
- AddCXXBaseSpecifiers(Data.bases());
-
- // FIXME: Make VBases lazily computed when needed to avoid storing them.
- Record->push_back(Data.NumVBases);
- if (Data.NumVBases > 0)
- AddCXXBaseSpecifiers(Data.vbases());
-
- AddUnresolvedSet(Data.Conversions.get(*Writer->Context));
- AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context));
- // Data.Definition is the owning decl, no need to write it.
- AddDeclRef(D->getFirstFriend());
-
- // Add lambda-specific data.
- if (Data.IsLambda) {
- auto &Lambda = D->getLambdaData();
- Record->push_back(Lambda.Dependent);
- Record->push_back(Lambda.IsGenericLambda);
- Record->push_back(Lambda.CaptureDefault);
- Record->push_back(Lambda.NumCaptures);
- Record->push_back(Lambda.NumExplicitCaptures);
- Record->push_back(Lambda.ManglingNumber);
- AddDeclRef(D->getLambdaContextDecl());
- AddTypeSourceInfo(Lambda.MethodTyInfo);
- for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
- const LambdaCapture &Capture = Lambda.Captures[I];
- AddSourceLocation(Capture.getLocation());
- Record->push_back(Capture.isImplicit());
- Record->push_back(Capture.getCaptureKind());
- switch (Capture.getCaptureKind()) {
- case LCK_StarThis:
- case LCK_This:
- case LCK_VLAType:
- break;
- case LCK_ByCopy:
- case LCK_ByRef:
- VarDecl *Var =
- Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
- AddDeclRef(Var);
- AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc()
- : SourceLocation());
- break;
- }
- }
- }
-}
-
-void ASTWriter::ReaderInitialized(ASTReader *Reader) {
- assert(Reader && "Cannot remove chain");
- assert((!Chain || Chain == Reader) && "Cannot replace chain");
- assert(FirstDeclID == NextDeclID &&
- FirstTypeID == NextTypeID &&
- FirstIdentID == NextIdentID &&
- FirstMacroID == NextMacroID &&
- FirstSubmoduleID == NextSubmoduleID &&
- FirstSelectorID == NextSelectorID &&
- "Setting chain after writing has started.");
-
- Chain = Reader;
-
- // Note, this will get called multiple times, once one the reader starts up
- // and again each time it's done reading a PCH or module.
- FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();
- FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();
- FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers();
- FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros();
- FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
- FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
- NextDeclID = FirstDeclID;
- NextTypeID = FirstTypeID;
- NextIdentID = FirstIdentID;
- NextMacroID = FirstMacroID;
- NextSelectorID = FirstSelectorID;
- NextSubmoduleID = FirstSubmoduleID;
-}
-
-void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
- // Always keep the highest ID. See \p TypeRead() for more information.
- IdentID &StoredID = IdentifierIDs[II];
- if (ID > StoredID)
- StoredID = ID;
-}
-
-void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
- // Always keep the highest ID. See \p TypeRead() for more information.
- MacroID &StoredID = MacroIDs[MI];
- if (ID > StoredID)
- StoredID = ID;
-}
-
-void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
- // Always take the highest-numbered type index. This copes with an interesting
- // case for chained AST writing where we schedule writing the type and then,
- // later, deserialize the type from another AST. In this case, we want to
- // keep the higher-numbered entry so that we can properly write it out to
- // the AST file.
- TypeIdx &StoredIdx = TypeIdxs[T];
- if (Idx.getIndex() >= StoredIdx.getIndex())
- StoredIdx = Idx;
-}
-
-void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
- // Always keep the highest ID. See \p TypeRead() for more information.
- SelectorID &StoredID = SelectorIDs[S];
- if (ID > StoredID)
- StoredID = ID;
-}
-
-void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID,
- MacroDefinitionRecord *MD) {
- assert(MacroDefinitions.find(MD) == MacroDefinitions.end());
- MacroDefinitions[MD] = ID;
-}
-
-void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
- assert(SubmoduleIDs.find(Mod) == SubmoduleIDs.end());
- SubmoduleIDs[Mod] = ID;
-}
-
-void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(D->isCompleteDefinition());
- assert(!WritingAST && "Already writing the AST!");
- if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
- // We are interested when a PCH decl is modified.
- if (RD->isFromASTFile()) {
- // A forward reference was mutated into a definition. Rewrite it.
- // FIXME: This happens during template instantiation, should we
- // have created a new definition decl instead ?
- assert(isTemplateInstantiation(RD->getTemplateSpecializationKind()) &&
- "completed a tag from another module but not by instantiation?");
- DeclUpdates[RD].push_back(
- DeclUpdate(UPD_CXX_INSTANTIATED_CLASS_DEFINITION));
- }
- }
-}
-
-static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
- if (D->isFromASTFile())
- return true;
-
- // The predefined __va_list_tag struct is imported if we imported any decls.
- // FIXME: This is a gross hack.
- return D == D->getASTContext().getVaListTagDecl();
-}
-
-void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(DC->isLookupContext() &&
- "Should not add lookup results to non-lookup contexts!");
-
- // TU is handled elsewhere.
- if (isa<TranslationUnitDecl>(DC))
- return;
-
- // Namespaces are handled elsewhere, except for template instantiations of
- // FunctionTemplateDecls in namespaces. We are interested in cases where the
- // local instantiations are added to an imported context. Only happens when
- // adding ADL lookup candidates, for example templated friends.
- if (isa<NamespaceDecl>(DC) && D->getFriendObjectKind() == Decl::FOK_None &&
- !isa<FunctionTemplateDecl>(D))
- return;
-
- // We're only interested in cases where a local declaration is added to an
- // imported context.
- if (D->isFromASTFile() || !isImportedDeclContext(Chain, cast<Decl>(DC)))
- return;
-
- assert(DC == DC->getPrimaryContext() && "added to non-primary context");
- assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
- assert(!WritingAST && "Already writing the AST!");
- if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) {
- // We're adding a visible declaration to a predefined decl context. Ensure
- // that we write out all of its lookup results so we don't get a nasty
- // surprise when we try to emit its lookup table.
- for (auto *Child : DC->decls())
- DeclsToEmitEvenIfUnreferenced.push_back(Child);
- }
- DeclsToEmitEvenIfUnreferenced.push_back(D);
-}
-
-void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(D->isImplicit());
-
- // We're only interested in cases where a local declaration is added to an
- // imported context.
- if (D->isFromASTFile() || !isImportedDeclContext(Chain, RD))
- return;
-
- if (!isa<CXXMethodDecl>(D))
- return;
-
- // A decl coming from PCH was modified.
- assert(RD->isCompleteDefinition());
- assert(!WritingAST && "Already writing the AST!");
- DeclUpdates[RD].push_back(DeclUpdate(UPD_CXX_ADDED_IMPLICIT_MEMBER, D));
-}
-
-void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!DoneWritingDeclsAndTypes && "Already done writing updates!");
- if (!Chain) return;
- Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
- // If we don't already know the exception specification for this redecl
- // chain, add an update record for it.
- if (isUnresolvedExceptionSpec(cast<FunctionDecl>(D)
- ->getType()
- ->castAs<FunctionProtoType>()
- ->getExceptionSpecType()))
- DeclUpdates[D].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC);
- });
-}
-
-void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!Chain) return;
- Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
- DeclUpdates[D].push_back(
- DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType));
- });
-}
-
-void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete,
- Expr *ThisArg) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- assert(Delete && "Not given an operator delete");
- if (!Chain) return;
- Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
- DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_RESOLVED_DTOR_DELETE, Delete));
- });
-}
-
-void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return; // Declaration not imported from PCH.
-
- // Implicit function decl from a PCH was defined.
- DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
-}
-
-void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_VAR_DEFINITION));
-}
-
-void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
-}
-
-void ASTWriter::InstantiationRequested(const ValueDecl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- // Since the actual instantiation is delayed, this really means that we need
- // to update the instantiation location.
- SourceLocation POI;
- if (auto *VD = dyn_cast<VarDecl>(D))
- POI = VD->getPointOfInstantiation();
- else
- POI = cast<FunctionDecl>(D)->getPointOfInstantiation();
- DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_POINT_OF_INSTANTIATION, POI));
-}
-
-void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- DeclUpdates[D].push_back(
- DeclUpdate(UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT, D));
-}
-
-void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- DeclUpdates[D].push_back(
- DeclUpdate(UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER, D));
-}
-
-void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
- const ObjCInterfaceDecl *IFD) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!IFD->isFromASTFile())
- return; // Declaration not imported from PCH.
-
- assert(IFD->getDefinition() && "Category on a class without a definition?");
- ObjCClassesWithCategories.insert(
- const_cast<ObjCInterfaceDecl *>(IFD->getDefinition()));
-}
-
-void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
-
- // If there is *any* declaration of the entity that's not from an AST file,
- // we can skip writing the update record. We make sure that isUsed() triggers
- // completion of the redeclaration chain of the entity.
- for (auto Prev = D->getMostRecentDecl(); Prev; Prev = Prev->getPreviousDecl())
- if (IsLocalDecl(Prev))
- return;
-
- DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED));
-}
-
-void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE));
-}
-
-void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
- const Attr *Attr) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!D->isFromASTFile())
- return;
-
- DeclUpdates[D].push_back(
- DeclUpdate(UPD_DECL_MARKED_OPENMP_DECLARETARGET, Attr));
-}
-
-void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- assert(D->isHidden() && "expected a hidden declaration");
- DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M));
-}
-
-void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
- const RecordDecl *Record) {
- if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
- if (!Record->isFromASTFile())
- return;
- DeclUpdates[Record].push_back(DeclUpdate(UPD_ADDED_ATTR_TO_RECORD, Attr));
-}
-
-void ASTWriter::AddedCXXTemplateSpecialization(
- const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
-
- if (!TD->getFirstDecl()->isFromASTFile())
- return;
- if (Chain && Chain->isProcessingUpdateRecords())
- return;
-
- DeclsToEmitEvenIfUnreferenced.push_back(D);
-}
-
-void ASTWriter::AddedCXXTemplateSpecialization(
- const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
-
- if (!TD->getFirstDecl()->isFromASTFile())
- return;
- if (Chain && Chain->isProcessingUpdateRecords())
- return;
-
- DeclsToEmitEvenIfUnreferenced.push_back(D);
-}
-
-void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
- const FunctionDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
-
- if (!TD->getFirstDecl()->isFromASTFile())
- return;
- if (Chain && Chain->isProcessingUpdateRecords())
- return;
-
- DeclsToEmitEvenIfUnreferenced.push_back(D);
-}
-
-//===----------------------------------------------------------------------===//
-//// OMPClause Serialization
-////===----------------------------------------------------------------------===//
-
-void OMPClauseWriter::writeClause(OMPClause *C) {
- Record.push_back(C->getClauseKind());
- Visit(C);
- Record.AddSourceLocation(C->getBeginLoc());
- Record.AddSourceLocation(C->getEndLoc());
-}
-
-void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
- Record.push_back(C->getCaptureRegion());
- Record.AddStmt(C->getPreInitStmt());
-}
-
-void OMPClauseWriter::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) {
- VisitOMPClauseWithPreInit(C);
- Record.AddStmt(C->getPostUpdateExpr());
-}
-
-void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.push_back(C->getNameModifier());
- Record.AddSourceLocation(C->getNameModifierLoc());
- Record.AddSourceLocation(C->getColonLoc());
- Record.AddStmt(C->getCondition());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
- Record.AddStmt(C->getCondition());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.AddStmt(C->getNumThreads());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
- Record.AddStmt(C->getSafelen());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
- Record.AddStmt(C->getSimdlen());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
- Record.AddStmt(C->getNumForLoops());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
- Record.push_back(C->getDefaultKind());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getDefaultKindKwLoc());
-}
-
-void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
- Record.push_back(C->getProcBindKind());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getProcBindKindKwLoc());
-}
-
-void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.push_back(C->getScheduleKind());
- Record.push_back(C->getFirstScheduleModifier());
- Record.push_back(C->getSecondScheduleModifier());
- Record.AddStmt(C->getChunkSize());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getFirstScheduleModifierLoc());
- Record.AddSourceLocation(C->getSecondScheduleModifierLoc());
- Record.AddSourceLocation(C->getScheduleKindLoc());
- Record.AddSourceLocation(C->getCommaLoc());
-}
-
-void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) {
- Record.push_back(C->getLoopNumIterations().size());
- Record.AddStmt(C->getNumForLoops());
- for (Expr *NumIter : C->getLoopNumIterations())
- Record.AddStmt(NumIter);
- for (unsigned I = 0, E = C->getLoopNumIterations().size(); I <E; ++I)
- Record.AddStmt(C->getLoopCounter(I));
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {}
-
-void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
-
-void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
-
-void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}
-
-void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
-
-void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {}
-
-void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
-
-void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
-
-void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
-
-void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
-
-void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {}
-
-void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
- Record.push_back(C->varlist_size());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->private_copies()) {
- Record.AddStmt(VE);
- }
-}
-
-void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
- Record.push_back(C->varlist_size());
- VisitOMPClauseWithPreInit(C);
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->private_copies()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->inits()) {
- Record.AddStmt(VE);
- }
-}
-
-void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
- Record.push_back(C->varlist_size());
- VisitOMPClauseWithPostUpdate(C);
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (auto *E : C->private_copies())
- Record.AddStmt(E);
- for (auto *E : C->source_exprs())
- Record.AddStmt(E);
- for (auto *E : C->destination_exprs())
- Record.AddStmt(E);
- for (auto *E : C->assignment_ops())
- Record.AddStmt(E);
-}
-
-void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
- Record.push_back(C->varlist_size());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
-}
-
-void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
- Record.push_back(C->varlist_size());
- VisitOMPClauseWithPostUpdate(C);
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getColonLoc());
- Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
- Record.AddDeclarationNameInfo(C->getNameInfo());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (auto *VE : C->privates())
- Record.AddStmt(VE);
- for (auto *E : C->lhs_exprs())
- Record.AddStmt(E);
- for (auto *E : C->rhs_exprs())
- Record.AddStmt(E);
- for (auto *E : C->reduction_ops())
- Record.AddStmt(E);
-}
-
-void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
- Record.push_back(C->varlist_size());
- VisitOMPClauseWithPostUpdate(C);
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getColonLoc());
- Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
- Record.AddDeclarationNameInfo(C->getNameInfo());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (auto *VE : C->privates())
- Record.AddStmt(VE);
- for (auto *E : C->lhs_exprs())
- Record.AddStmt(E);
- for (auto *E : C->rhs_exprs())
- Record.AddStmt(E);
- for (auto *E : C->reduction_ops())
- Record.AddStmt(E);
-}
-
-void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) {
- Record.push_back(C->varlist_size());
- VisitOMPClauseWithPostUpdate(C);
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getColonLoc());
- Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
- Record.AddDeclarationNameInfo(C->getNameInfo());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (auto *VE : C->privates())
- Record.AddStmt(VE);
- for (auto *E : C->lhs_exprs())
- Record.AddStmt(E);
- for (auto *E : C->rhs_exprs())
- Record.AddStmt(E);
- for (auto *E : C->reduction_ops())
- Record.AddStmt(E);
- for (auto *E : C->taskgroup_descriptors())
- Record.AddStmt(E);
-}
-
-void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
- Record.push_back(C->varlist_size());
- VisitOMPClauseWithPostUpdate(C);
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getColonLoc());
- Record.push_back(C->getModifier());
- Record.AddSourceLocation(C->getModifierLoc());
- for (auto *VE : C->varlists()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->privates()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->inits()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->updates()) {
- Record.AddStmt(VE);
- }
- for (auto *VE : C->finals()) {
- Record.AddStmt(VE);
- }
- Record.AddStmt(C->getStep());
- Record.AddStmt(C->getCalcStep());
-}
-
-void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
- Record.push_back(C->varlist_size());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getColonLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- Record.AddStmt(C->getAlignment());
-}
-
-void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
- Record.push_back(C->varlist_size());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (auto *E : C->source_exprs())
- Record.AddStmt(E);
- for (auto *E : C->destination_exprs())
- Record.AddStmt(E);
- for (auto *E : C->assignment_ops())
- Record.AddStmt(E);
-}
-
-void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
- Record.push_back(C->varlist_size());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (auto *E : C->source_exprs())
- Record.AddStmt(E);
- for (auto *E : C->destination_exprs())
- Record.AddStmt(E);
- for (auto *E : C->assignment_ops())
- Record.AddStmt(E);
-}
-
-void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
- Record.push_back(C->varlist_size());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
-}
-
-void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) {
- Record.push_back(C->varlist_size());
- Record.push_back(C->getNumLoops());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.push_back(C->getDependencyKind());
- Record.AddSourceLocation(C->getDependencyLoc());
- Record.AddSourceLocation(C->getColonLoc());
- for (auto *VE : C->varlists())
- Record.AddStmt(VE);
- for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
- Record.AddStmt(C->getLoopData(I));
-}
-
-void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.AddStmt(C->getDevice());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
- Record.push_back(C->varlist_size());
- Record.push_back(C->getUniqueDeclarationsNum());
- Record.push_back(C->getTotalComponentListNum());
- Record.push_back(C->getTotalComponentsNum());
- Record.AddSourceLocation(C->getLParenLoc());
- for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) {
- Record.push_back(C->getMapTypeModifier(I));
- Record.AddSourceLocation(C->getMapTypeModifierLoc(I));
- }
- Record.push_back(C->getMapType());
- Record.AddSourceLocation(C->getMapLoc());
- Record.AddSourceLocation(C->getColonLoc());
- for (auto *E : C->varlists())
- Record.AddStmt(E);
- for (auto *D : C->all_decls())
- Record.AddDeclRef(D);
- for (auto N : C->all_num_lists())
- Record.push_back(N);
- for (auto N : C->all_lists_sizes())
- Record.push_back(N);
- for (auto &M : C->all_components()) {
- Record.AddStmt(M.getAssociatedExpression());
- Record.AddDeclRef(M.getAssociatedDeclaration());
- }
-}
-
-void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.AddStmt(C->getNumTeams());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.AddStmt(C->getThreadLimit());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) {
- Record.AddStmt(C->getPriority());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
- Record.AddStmt(C->getGrainsize());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
- Record.AddStmt(C->getNumTasks());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) {
- Record.AddStmt(C->getHint());
- Record.AddSourceLocation(C->getLParenLoc());
-}
-
-void OMPClauseWriter::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) {
- VisitOMPClauseWithPreInit(C);
- Record.push_back(C->getDistScheduleKind());
- Record.AddStmt(C->getChunkSize());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getDistScheduleKindLoc());
- Record.AddSourceLocation(C->getCommaLoc());
-}
-
-void OMPClauseWriter::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
- Record.push_back(C->getDefaultmapKind());
- Record.push_back(C->getDefaultmapModifier());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getDefaultmapModifierLoc());
- Record.AddSourceLocation(C->getDefaultmapKindLoc());
-}
-
-void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) {
- Record.push_back(C->varlist_size());
- Record.push_back(C->getUniqueDeclarationsNum());
- Record.push_back(C->getTotalComponentListNum());
- Record.push_back(C->getTotalComponentsNum());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *E : C->varlists())
- Record.AddStmt(E);
- for (auto *D : C->all_decls())
- Record.AddDeclRef(D);
- for (auto N : C->all_num_lists())
- Record.push_back(N);
- for (auto N : C->all_lists_sizes())
- Record.push_back(N);
- for (auto &M : C->all_components()) {
- Record.AddStmt(M.getAssociatedExpression());
- Record.AddDeclRef(M.getAssociatedDeclaration());
- }
-}
-
-void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) {
- Record.push_back(C->varlist_size());
- Record.push_back(C->getUniqueDeclarationsNum());
- Record.push_back(C->getTotalComponentListNum());
- Record.push_back(C->getTotalComponentsNum());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *E : C->varlists())
- Record.AddStmt(E);
- for (auto *D : C->all_decls())
- Record.AddDeclRef(D);
- for (auto N : C->all_num_lists())
- Record.push_back(N);
- for (auto N : C->all_lists_sizes())
- Record.push_back(N);
- for (auto &M : C->all_components()) {
- Record.AddStmt(M.getAssociatedExpression());
- Record.AddDeclRef(M.getAssociatedDeclaration());
- }
-}
-
-void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
- Record.push_back(C->varlist_size());
- Record.push_back(C->getUniqueDeclarationsNum());
- Record.push_back(C->getTotalComponentListNum());
- Record.push_back(C->getTotalComponentsNum());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *E : C->varlists())
- Record.AddStmt(E);
- for (auto *VE : C->private_copies())
- Record.AddStmt(VE);
- for (auto *VE : C->inits())
- Record.AddStmt(VE);
- for (auto *D : C->all_decls())
- Record.AddDeclRef(D);
- for (auto N : C->all_num_lists())
- Record.push_back(N);
- for (auto N : C->all_lists_sizes())
- Record.push_back(N);
- for (auto &M : C->all_components()) {
- Record.AddStmt(M.getAssociatedExpression());
- Record.AddDeclRef(M.getAssociatedDeclaration());
- }
-}
-
-void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
- Record.push_back(C->varlist_size());
- Record.push_back(C->getUniqueDeclarationsNum());
- Record.push_back(C->getTotalComponentListNum());
- Record.push_back(C->getTotalComponentsNum());
- Record.AddSourceLocation(C->getLParenLoc());
- for (auto *E : C->varlists())
- Record.AddStmt(E);
- for (auto *D : C->all_decls())
- Record.AddDeclRef(D);
- for (auto N : C->all_num_lists())
- Record.push_back(N);
- for (auto N : C->all_lists_sizes())
- Record.push_back(N);
- for (auto &M : C->all_components()) {
- Record.AddStmt(M.getAssociatedExpression());
- Record.AddDeclRef(M.getAssociatedDeclaration());
- }
-}
-
-void OMPClauseWriter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
-
-void OMPClauseWriter::VisitOMPUnifiedSharedMemoryClause(
- OMPUnifiedSharedMemoryClause *) {}
-
-void OMPClauseWriter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {}
-
-void
-OMPClauseWriter::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) {
-}
-
-void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
- OMPAtomicDefaultMemOrderClause *C) {
- Record.push_back(C->getAtomicDefaultMemOrderKind());
- Record.AddSourceLocation(C->getLParenLoc());
- Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
deleted file mode 100644
index 002b43f8112..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp
+++ /dev/null
@@ -1,2355 +0,0 @@
-//===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements serialization for Declarations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTCommon.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclContextInternals.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/OpenMPClause.h"
-#include "clang/AST/PrettyDeclStackTrace.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Serialization/ASTReader.h"
-#include "clang/Serialization/ASTWriter.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-#include "llvm/Support/ErrorHandling.h"
-using namespace clang;
-using namespace serialization;
-
-//===----------------------------------------------------------------------===//
-// Declaration serialization
-//===----------------------------------------------------------------------===//
-
-namespace clang {
- class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
- ASTWriter &Writer;
- ASTContext &Context;
- ASTRecordWriter Record;
-
- serialization::DeclCode Code;
- unsigned AbbrevToUse;
-
- public:
- ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
- ASTWriter::RecordDataImpl &Record)
- : Writer(Writer), Context(Context), Record(Writer, Record),
- Code((serialization::DeclCode)0), AbbrevToUse(0) {}
-
- uint64_t Emit(Decl *D) {
- if (!Code)
- llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
- D->getDeclKindName() + "'");
- return Record.Emit(Code, AbbrevToUse);
- }
-
- void Visit(Decl *D);
-
- void VisitDecl(Decl *D);
- void VisitPragmaCommentDecl(PragmaCommentDecl *D);
- void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D);
- void VisitTranslationUnitDecl(TranslationUnitDecl *D);
- void VisitNamedDecl(NamedDecl *D);
- void VisitLabelDecl(LabelDecl *LD);
- void VisitNamespaceDecl(NamespaceDecl *D);
- void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
- void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- void VisitTypeDecl(TypeDecl *D);
- void VisitTypedefNameDecl(TypedefNameDecl *D);
- void VisitTypedefDecl(TypedefDecl *D);
- void VisitTypeAliasDecl(TypeAliasDecl *D);
- void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
- void VisitTagDecl(TagDecl *D);
- void VisitEnumDecl(EnumDecl *D);
- void VisitRecordDecl(RecordDecl *D);
- void VisitCXXRecordDecl(CXXRecordDecl *D);
- void VisitClassTemplateSpecializationDecl(
- ClassTemplateSpecializationDecl *D);
- void VisitClassTemplatePartialSpecializationDecl(
- ClassTemplatePartialSpecializationDecl *D);
- void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
- void VisitVarTemplatePartialSpecializationDecl(
- VarTemplatePartialSpecializationDecl *D);
- void VisitClassScopeFunctionSpecializationDecl(
- ClassScopeFunctionSpecializationDecl *D);
- void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- void VisitValueDecl(ValueDecl *D);
- void VisitEnumConstantDecl(EnumConstantDecl *D);
- void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
- void VisitDeclaratorDecl(DeclaratorDecl *D);
- void VisitFunctionDecl(FunctionDecl *D);
- void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D);
- void VisitCXXMethodDecl(CXXMethodDecl *D);
- void VisitCXXConstructorDecl(CXXConstructorDecl *D);
- void VisitCXXDestructorDecl(CXXDestructorDecl *D);
- void VisitCXXConversionDecl(CXXConversionDecl *D);
- void VisitFieldDecl(FieldDecl *D);
- void VisitMSPropertyDecl(MSPropertyDecl *D);
- void VisitIndirectFieldDecl(IndirectFieldDecl *D);
- void VisitVarDecl(VarDecl *D);
- void VisitImplicitParamDecl(ImplicitParamDecl *D);
- void VisitParmVarDecl(ParmVarDecl *D);
- void VisitDecompositionDecl(DecompositionDecl *D);
- void VisitBindingDecl(BindingDecl *D);
- void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- void VisitTemplateDecl(TemplateDecl *D);
- void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
- void VisitClassTemplateDecl(ClassTemplateDecl *D);
- void VisitVarTemplateDecl(VarTemplateDecl *D);
- void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
- void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
- void VisitUsingDecl(UsingDecl *D);
- void VisitUsingPackDecl(UsingPackDecl *D);
- void VisitUsingShadowDecl(UsingShadowDecl *D);
- void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
- void VisitLinkageSpecDecl(LinkageSpecDecl *D);
- void VisitExportDecl(ExportDecl *D);
- void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
- void VisitImportDecl(ImportDecl *D);
- void VisitAccessSpecDecl(AccessSpecDecl *D);
- void VisitFriendDecl(FriendDecl *D);
- void VisitFriendTemplateDecl(FriendTemplateDecl *D);
- void VisitStaticAssertDecl(StaticAssertDecl *D);
- void VisitBlockDecl(BlockDecl *D);
- void VisitCapturedDecl(CapturedDecl *D);
- void VisitEmptyDecl(EmptyDecl *D);
-
- void VisitDeclContext(DeclContext *DC);
- template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
-
-
- // FIXME: Put in the same order is DeclNodes.td?
- void VisitObjCMethodDecl(ObjCMethodDecl *D);
- void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
- void VisitObjCContainerDecl(ObjCContainerDecl *D);
- void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
- void VisitObjCIvarDecl(ObjCIvarDecl *D);
- void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
- void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
- void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
- void VisitObjCImplDecl(ObjCImplDecl *D);
- void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
- void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
- void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
- void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
- void VisitOMPRequiresDecl(OMPRequiresDecl *D);
- void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
- void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
-
- /// Add an Objective-C type parameter list to the given record.
- void AddObjCTypeParamList(ObjCTypeParamList *typeParams) {
- // Empty type parameter list.
- if (!typeParams) {
- Record.push_back(0);
- return;
- }
-
- Record.push_back(typeParams->size());
- for (auto typeParam : *typeParams) {
- Record.AddDeclRef(typeParam);
- }
- Record.AddSourceLocation(typeParams->getLAngleLoc());
- Record.AddSourceLocation(typeParams->getRAngleLoc());
- }
-
- /// Add to the record the first declaration from each module file that
- /// provides a declaration of D. The intent is to provide a sufficient
- /// set such that reloading this set will load all current redeclarations.
- void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
- llvm::MapVector<ModuleFile*, const Decl*> Firsts;
- // FIXME: We can skip entries that we know are implied by others.
- for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
- if (R->isFromASTFile())
- Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
- else if (IncludeLocal)
- Firsts[nullptr] = R;
- }
- for (const auto &F : Firsts)
- Record.AddDeclRef(F.second);
- }
-
- /// Get the specialization decl from an entry in the specialization list.
- template <typename EntryType>
- typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
- getSpecializationDecl(EntryType &T) {
- return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T);
- }
-
- /// Get the list of partial specializations from a template's common ptr.
- template<typename T>
- decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
- return Common->PartialSpecializations;
- }
- ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) {
- return None;
- }
-
- template<typename DeclTy>
- void AddTemplateSpecializations(DeclTy *D) {
- auto *Common = D->getCommonPtr();
-
- // If we have any lazy specializations, and the external AST source is
- // our chained AST reader, we can just write out the DeclIDs. Otherwise,
- // we need to resolve them to actual declarations.
- if (Writer.Chain != Writer.Context->getExternalSource() &&
- Common->LazySpecializations) {
- D->LoadLazySpecializations();
- assert(!Common->LazySpecializations);
- }
-
- ArrayRef<DeclID> LazySpecializations;
- if (auto *LS = Common->LazySpecializations)
- LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
-
- // Add a slot to the record for the number of specializations.
- unsigned I = Record.size();
- Record.push_back(0);
-
- // AddFirstDeclFromEachModule might trigger deserialization, invalidating
- // *Specializations iterators.
- llvm::SmallVector<const Decl*, 16> Specs;
- for (auto &Entry : Common->Specializations)
- Specs.push_back(getSpecializationDecl(Entry));
- for (auto &Entry : getPartialSpecializations(Common))
- Specs.push_back(getSpecializationDecl(Entry));
-
- for (auto *D : Specs) {
- assert(D->isCanonicalDecl() && "non-canonical decl in set");
- AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
- }
- Record.append(LazySpecializations.begin(), LazySpecializations.end());
-
- // Update the size entry we added earlier.
- Record[I] = Record.size() - I - 1;
- }
-
- /// Ensure that this template specialization is associated with the specified
- /// template on reload.
- void RegisterTemplateSpecialization(const Decl *Template,
- const Decl *Specialization) {
- Template = Template->getCanonicalDecl();
-
- // If the canonical template is local, we'll write out this specialization
- // when we emit it.
- // FIXME: We can do the same thing if there is any local declaration of
- // the template, to avoid emitting an update record.
- if (!Template->isFromASTFile())
- return;
-
- // We only need to associate the first local declaration of the
- // specialization. The other declarations will get pulled in by it.
- if (Writer.getFirstLocalDecl(Specialization) != Specialization)
- return;
-
- Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate(
- UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization));
- }
- };
-}
-
-void ASTDeclWriter::Visit(Decl *D) {
- DeclVisitor<ASTDeclWriter>::Visit(D);
-
- // Source locations require array (variable-length) abbreviations. The
- // abbreviation infrastructure requires that arrays are encoded last, so
- // we handle it here in the case of those classes derived from DeclaratorDecl
- if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
- if (auto *TInfo = DD->getTypeSourceInfo())
- Record.AddTypeLoc(TInfo->getTypeLoc());
- }
-
- // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
- // have been written. We want it last because we will not read it back when
- // retrieving it from the AST, we'll just lazily set the offset.
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- Record.push_back(FD->doesThisDeclarationHaveABody());
- if (FD->doesThisDeclarationHaveABody())
- Record.AddFunctionDefinition(FD);
- }
-
- // If this declaration is also a DeclContext, write blocks for the
- // declarations that lexically stored inside its context and those
- // declarations that are visible from its context.
- if (DeclContext *DC = dyn_cast<DeclContext>(D))
- VisitDeclContext(DC);
-}
-
-void ASTDeclWriter::VisitDecl(Decl *D) {
- Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
- if (D->getDeclContext() != D->getLexicalDeclContext())
- Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
- else
- Record.push_back(0);
- Record.push_back(D->isInvalidDecl());
- Record.push_back(D->hasAttrs());
- if (D->hasAttrs())
- Record.AddAttributes(D->getAttrs());
- Record.push_back(D->isImplicit());
- Record.push_back(D->isUsed(false));
- Record.push_back(D->isReferenced());
- Record.push_back(D->isTopLevelDeclInObjCContainer());
- Record.push_back(D->getAccess());
- Record.push_back(D->isModulePrivate());
- Record.push_back(Writer.getSubmoduleID(D->getOwningModule()));
-
- // If this declaration injected a name into a context different from its
- // lexical context, and that context is an imported namespace, we need to
- // update its visible declarations to include this name.
- //
- // This happens when we instantiate a class with a friend declaration or a
- // function with a local extern declaration, for instance.
- //
- // FIXME: Can we handle this in AddedVisibleDecl instead?
- if (D->isOutOfLine()) {
- auto *DC = D->getDeclContext();
- while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
- if (!NS->isFromASTFile())
- break;
- Writer.UpdatedDeclContexts.insert(NS->getPrimaryContext());
- if (!NS->isInlineNamespace())
- break;
- DC = NS->getParent();
- }
- }
-}
-
-void ASTDeclWriter::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
- StringRef Arg = D->getArg();
- Record.push_back(Arg.size());
- VisitDecl(D);
- Record.AddSourceLocation(D->getBeginLoc());
- Record.push_back(D->getCommentKind());
- Record.AddString(Arg);
- Code = serialization::DECL_PRAGMA_COMMENT;
-}
-
-void ASTDeclWriter::VisitPragmaDetectMismatchDecl(
- PragmaDetectMismatchDecl *D) {
- StringRef Name = D->getName();
- StringRef Value = D->getValue();
- Record.push_back(Name.size() + 1 + Value.size());
- VisitDecl(D);
- Record.AddSourceLocation(D->getBeginLoc());
- Record.AddString(Name);
- Record.AddString(Value);
- Code = serialization::DECL_PRAGMA_DETECT_MISMATCH;
-}
-
-void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
- llvm_unreachable("Translation units aren't directly serialized");
-}
-
-void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
- VisitDecl(D);
- Record.AddDeclarationName(D->getDeclName());
- Record.push_back(needsAnonymousDeclarationNumber(D)
- ? Writer.getAnonymousDeclarationNumber(D)
- : 0);
-}
-
-void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getBeginLoc());
- Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
-}
-
-void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
- VisitRedeclarable(D);
- VisitTypeDecl(D);
- Record.AddTypeSourceInfo(D->getTypeSourceInfo());
- Record.push_back(D->isModed());
- if (D->isModed())
- Record.AddTypeRef(D->getUnderlyingType());
- Record.AddDeclRef(D->getAnonDeclWithTypedefName(false));
-}
-
-void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
- VisitTypedefNameDecl(D);
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->isTopLevelDeclInObjCContainer() &&
- !D->isModulePrivate() &&
- !needsAnonymousDeclarationNumber(D) &&
- D->getDeclName().getNameKind() == DeclarationName::Identifier)
- AbbrevToUse = Writer.getDeclTypedefAbbrev();
-
- Code = serialization::DECL_TYPEDEF;
-}
-
-void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
- VisitTypedefNameDecl(D);
- Record.AddDeclRef(D->getDescribedAliasTemplate());
- Code = serialization::DECL_TYPEALIAS;
-}
-
-void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
- VisitRedeclarable(D);
- VisitTypeDecl(D);
- Record.push_back(D->getIdentifierNamespace());
- Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
- if (!isa<CXXRecordDecl>(D))
- Record.push_back(D->isCompleteDefinition());
- Record.push_back(D->isEmbeddedInDeclarator());
- Record.push_back(D->isFreeStanding());
- Record.push_back(D->isCompleteDefinitionRequired());
- Record.AddSourceRange(D->getBraceRange());
-
- if (D->hasExtInfo()) {
- Record.push_back(1);
- Record.AddQualifierInfo(*D->getExtInfo());
- } else if (auto *TD = D->getTypedefNameForAnonDecl()) {
- Record.push_back(2);
- Record.AddDeclRef(TD);
- Record.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo());
- } else {
- Record.push_back(0);
- }
-}
-
-void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
- VisitTagDecl(D);
- Record.AddTypeSourceInfo(D->getIntegerTypeSourceInfo());
- if (!D->getIntegerTypeSourceInfo())
- Record.AddTypeRef(D->getIntegerType());
- Record.AddTypeRef(D->getPromotionType());
- Record.push_back(D->getNumPositiveBits());
- Record.push_back(D->getNumNegativeBits());
- Record.push_back(D->isScoped());
- Record.push_back(D->isScopedUsingClassTag());
- Record.push_back(D->isFixed());
- Record.push_back(D->getODRHash());
-
- if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
- Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
- Record.push_back(MemberInfo->getTemplateSpecializationKind());
- Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
- } else {
- Record.AddDeclRef(nullptr);
- }
-
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->hasExtInfo() &&
- !D->getTypedefNameForAnonDecl() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
- !D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
- !CXXRecordDecl::classofKind(D->getKind()) &&
- !D->getIntegerTypeSourceInfo() &&
- !D->getMemberSpecializationInfo() &&
- !needsAnonymousDeclarationNumber(D) &&
- D->getDeclName().getNameKind() == DeclarationName::Identifier)
- AbbrevToUse = Writer.getDeclEnumAbbrev();
-
- Code = serialization::DECL_ENUM;
-}
-
-void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
- VisitTagDecl(D);
- Record.push_back(D->hasFlexibleArrayMember());
- Record.push_back(D->isAnonymousStructOrUnion());
- Record.push_back(D->hasObjectMember());
- Record.push_back(D->hasVolatileMember());
- Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize());
- Record.push_back(D->isNonTrivialToPrimitiveCopy());
- Record.push_back(D->isNonTrivialToPrimitiveDestroy());
- Record.push_back(D->isParamDestroyedInCallee());
- Record.push_back(D->getArgPassingRestrictions());
-
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->hasExtInfo() &&
- !D->getTypedefNameForAnonDecl() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
- !D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
- !CXXRecordDecl::classofKind(D->getKind()) &&
- !needsAnonymousDeclarationNumber(D) &&
- D->getDeclName().getNameKind() == DeclarationName::Identifier)
- AbbrevToUse = Writer.getDeclRecordAbbrev();
-
- Code = serialization::DECL_RECORD;
-}
-
-void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
- VisitNamedDecl(D);
- Record.AddTypeRef(D->getType());
-}
-
-void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
- VisitValueDecl(D);
- Record.push_back(D->getInitExpr()? 1 : 0);
- if (D->getInitExpr())
- Record.AddStmt(D->getInitExpr());
- Record.AddAPSInt(D->getInitVal());
-
- Code = serialization::DECL_ENUM_CONSTANT;
-}
-
-void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
- VisitValueDecl(D);
- Record.AddSourceLocation(D->getInnerLocStart());
- Record.push_back(D->hasExtInfo());
- if (D->hasExtInfo())
- Record.AddQualifierInfo(*D->getExtInfo());
- // The location information is deferred until the end of the record.
- Record.AddTypeRef(D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType()
- : QualType());
-}
-
-void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
- VisitRedeclarable(D);
- VisitDeclaratorDecl(D);
- Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
- Record.push_back(D->getIdentifierNamespace());
-
- // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
- // after everything else is written.
- Record.push_back(static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
- Record.push_back(D->isInlineSpecified());
- Record.push_back(D->isInlined());
- Record.push_back(D->isExplicitSpecified());
- Record.push_back(D->isVirtualAsWritten());
- Record.push_back(D->isPure());
- Record.push_back(D->hasInheritedPrototype());
- Record.push_back(D->hasWrittenPrototype());
- Record.push_back(D->isDeletedBit());
- Record.push_back(D->isTrivial());
- Record.push_back(D->isTrivialForCall());
- Record.push_back(D->isDefaulted());
- Record.push_back(D->isExplicitlyDefaulted());
- Record.push_back(D->hasImplicitReturnZero());
- Record.push_back(D->isConstexpr());
- Record.push_back(D->usesSEHTry());
- Record.push_back(D->hasSkippedBody());
- Record.push_back(D->isMultiVersion());
- Record.push_back(D->isLateTemplateParsed());
- Record.push_back(D->getLinkageInternal());
- Record.AddSourceLocation(D->getEndLoc());
-
- Record.push_back(D->getODRHash());
-
- Record.push_back(D->getTemplatedKind());
- switch (D->getTemplatedKind()) {
- case FunctionDecl::TK_NonTemplate:
- break;
- case FunctionDecl::TK_FunctionTemplate:
- Record.AddDeclRef(D->getDescribedFunctionTemplate());
- break;
- case FunctionDecl::TK_MemberSpecialization: {
- MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
- Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
- Record.push_back(MemberInfo->getTemplateSpecializationKind());
- Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
- break;
- }
- case FunctionDecl::TK_FunctionTemplateSpecialization: {
- FunctionTemplateSpecializationInfo *
- FTSInfo = D->getTemplateSpecializationInfo();
-
- RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
-
- Record.AddDeclRef(FTSInfo->getTemplate());
- Record.push_back(FTSInfo->getTemplateSpecializationKind());
-
- // Template arguments.
- Record.AddTemplateArgumentList(FTSInfo->TemplateArguments);
-
- // Template args as written.
- Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
- if (FTSInfo->TemplateArgumentsAsWritten) {
- Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
- for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
- i!=e; ++i)
- Record.AddTemplateArgumentLoc(
- (*FTSInfo->TemplateArgumentsAsWritten)[i]);
- Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc);
- Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc);
- }
-
- Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
-
- if (D->isCanonicalDecl()) {
- // Write the template that contains the specializations set. We will
- // add a FunctionTemplateSpecializationInfo to it when reading.
- Record.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl());
- }
- break;
- }
- case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
- DependentFunctionTemplateSpecializationInfo *
- DFTSInfo = D->getDependentSpecializationInfo();
-
- // Templates.
- Record.push_back(DFTSInfo->getNumTemplates());
- for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
- Record.AddDeclRef(DFTSInfo->getTemplate(i));
-
- // Templates args.
- Record.push_back(DFTSInfo->getNumTemplateArgs());
- for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
- Record.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i));
- Record.AddSourceLocation(DFTSInfo->getLAngleLoc());
- Record.AddSourceLocation(DFTSInfo->getRAngleLoc());
- break;
- }
- }
-
- Record.push_back(D->param_size());
- for (auto P : D->parameters())
- Record.AddDeclRef(P);
- Code = serialization::DECL_FUNCTION;
-}
-
-void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
- VisitFunctionDecl(D);
- Record.push_back(D->isCopyDeductionCandidate());
- Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
-}
-
-void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
- VisitNamedDecl(D);
- // FIXME: convert to LazyStmtPtr?
- // Unlike C/C++, method bodies will never be in header files.
- bool HasBodyStuff = D->getBody() != nullptr ||
- D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr;
- Record.push_back(HasBodyStuff);
- if (HasBodyStuff) {
- Record.AddStmt(D->getBody());
- Record.AddDeclRef(D->getSelfDecl());
- Record.AddDeclRef(D->getCmdDecl());
- }
- Record.push_back(D->isInstanceMethod());
- Record.push_back(D->isVariadic());
- Record.push_back(D->isPropertyAccessor());
- Record.push_back(D->isDefined());
- Record.push_back(D->isOverriding());
- Record.push_back(D->hasSkippedBody());
-
- Record.push_back(D->isRedeclaration());
- Record.push_back(D->hasRedeclaration());
- if (D->hasRedeclaration()) {
- assert(Context.getObjCMethodRedeclaration(D));
- Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
- }
-
- // FIXME: stable encoding for @required/@optional
- Record.push_back(D->getImplementationControl());
- // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
- Record.push_back(D->getObjCDeclQualifier());
- Record.push_back(D->hasRelatedResultType());
- Record.AddTypeRef(D->getReturnType());
- Record.AddTypeSourceInfo(D->getReturnTypeSourceInfo());
- Record.AddSourceLocation(D->getEndLoc());
- Record.push_back(D->param_size());
- for (const auto *P : D->parameters())
- Record.AddDeclRef(P);
-
- Record.push_back(D->getSelLocsKind());
- unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
- SourceLocation *SelLocs = D->getStoredSelLocs();
- Record.push_back(NumStoredSelLocs);
- for (unsigned i = 0; i != NumStoredSelLocs; ++i)
- Record.AddSourceLocation(SelLocs[i]);
-
- Code = serialization::DECL_OBJC_METHOD;
-}
-
-void ASTDeclWriter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
- VisitTypedefNameDecl(D);
- Record.push_back(D->Variance);
- Record.push_back(D->Index);
- Record.AddSourceLocation(D->VarianceLoc);
- Record.AddSourceLocation(D->ColonLoc);
-
- Code = serialization::DECL_OBJC_TYPE_PARAM;
-}
-
-void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getAtStartLoc());
- Record.AddSourceRange(D->getAtEndRange());
- // Abstract class (no need to define a stable serialization::DECL code).
-}
-
-void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
- VisitRedeclarable(D);
- VisitObjCContainerDecl(D);
- Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
- AddObjCTypeParamList(D->TypeParamList);
-
- Record.push_back(D->isThisDeclarationADefinition());
- if (D->isThisDeclarationADefinition()) {
- // Write the DefinitionData
- ObjCInterfaceDecl::DefinitionData &Data = D->data();
-
- Record.AddTypeSourceInfo(D->getSuperClassTInfo());
- Record.AddSourceLocation(D->getEndOfDefinitionLoc());
- Record.push_back(Data.HasDesignatedInitializers);
-
- // Write out the protocols that are directly referenced by the @interface.
- Record.push_back(Data.ReferencedProtocols.size());
- for (const auto *P : D->protocols())
- Record.AddDeclRef(P);
- for (const auto &PL : D->protocol_locs())
- Record.AddSourceLocation(PL);
-
- // Write out the protocols that are transitively referenced.
- Record.push_back(Data.AllReferencedProtocols.size());
- for (ObjCList<ObjCProtocolDecl>::iterator
- P = Data.AllReferencedProtocols.begin(),
- PEnd = Data.AllReferencedProtocols.end();
- P != PEnd; ++P)
- Record.AddDeclRef(*P);
-
-
- if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
- // Ensure that we write out the set of categories for this class.
- Writer.ObjCClassesWithCategories.insert(D);
-
- // Make sure that the categories get serialized.
- for (; Cat; Cat = Cat->getNextClassCategoryRaw())
- (void)Writer.GetDeclRef(Cat);
- }
- }
-
- Code = serialization::DECL_OBJC_INTERFACE;
-}
-
-void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
- VisitFieldDecl(D);
- // FIXME: stable encoding for @public/@private/@protected/@package
- Record.push_back(D->getAccessControl());
- Record.push_back(D->getSynthesize());
-
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
- !D->isModulePrivate() &&
- !D->getBitWidth() &&
- !D->hasExtInfo() &&
- D->getDeclName())
- AbbrevToUse = Writer.getDeclObjCIvarAbbrev();
-
- Code = serialization::DECL_OBJC_IVAR;
-}
-
-void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
- VisitRedeclarable(D);
- VisitObjCContainerDecl(D);
-
- Record.push_back(D->isThisDeclarationADefinition());
- if (D->isThisDeclarationADefinition()) {
- Record.push_back(D->protocol_size());
- for (const auto *I : D->protocols())
- Record.AddDeclRef(I);
- for (const auto &PL : D->protocol_locs())
- Record.AddSourceLocation(PL);
- }
-
- Code = serialization::DECL_OBJC_PROTOCOL;
-}
-
-void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
- VisitFieldDecl(D);
- Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
-}
-
-void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
- VisitObjCContainerDecl(D);
- Record.AddSourceLocation(D->getCategoryNameLoc());
- Record.AddSourceLocation(D->getIvarLBraceLoc());
- Record.AddSourceLocation(D->getIvarRBraceLoc());
- Record.AddDeclRef(D->getClassInterface());
- AddObjCTypeParamList(D->TypeParamList);
- Record.push_back(D->protocol_size());
- for (const auto *I : D->protocols())
- Record.AddDeclRef(I);
- for (const auto &PL : D->protocol_locs())
- Record.AddSourceLocation(PL);
- Code = serialization::DECL_OBJC_CATEGORY;
-}
-
-void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
- VisitNamedDecl(D);
- Record.AddDeclRef(D->getClassInterface());
- Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
-}
-
-void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getAtLoc());
- Record.AddSourceLocation(D->getLParenLoc());
- Record.AddTypeRef(D->getType());
- Record.AddTypeSourceInfo(D->getTypeSourceInfo());
- // FIXME: stable encoding
- Record.push_back((unsigned)D->getPropertyAttributes());
- Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
- // FIXME: stable encoding
- Record.push_back((unsigned)D->getPropertyImplementation());
- Record.AddDeclarationName(D->getGetterName());
- Record.AddSourceLocation(D->getGetterNameLoc());
- Record.AddDeclarationName(D->getSetterName());
- Record.AddSourceLocation(D->getSetterNameLoc());
- Record.AddDeclRef(D->getGetterMethodDecl());
- Record.AddDeclRef(D->getSetterMethodDecl());
- Record.AddDeclRef(D->getPropertyIvarDecl());
- Code = serialization::DECL_OBJC_PROPERTY;
-}
-
-void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
- VisitObjCContainerDecl(D);
- Record.AddDeclRef(D->getClassInterface());
- // Abstract class (no need to define a stable serialization::DECL code).
-}
-
-void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
- VisitObjCImplDecl(D);
- Record.AddSourceLocation(D->getCategoryNameLoc());
- Code = serialization::DECL_OBJC_CATEGORY_IMPL;
-}
-
-void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
- VisitObjCImplDecl(D);
- Record.AddDeclRef(D->getSuperClass());
- Record.AddSourceLocation(D->getSuperClassLoc());
- Record.AddSourceLocation(D->getIvarLBraceLoc());
- Record.AddSourceLocation(D->getIvarRBraceLoc());
- Record.push_back(D->hasNonZeroConstructors());
- Record.push_back(D->hasDestructors());
- Record.push_back(D->NumIvarInitializers);
- if (D->NumIvarInitializers)
- Record.AddCXXCtorInitializers(
- llvm::makeArrayRef(D->init_begin(), D->init_end()));
- Code = serialization::DECL_OBJC_IMPLEMENTATION;
-}
-
-void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
- VisitDecl(D);
- Record.AddSourceLocation(D->getBeginLoc());
- Record.AddDeclRef(D->getPropertyDecl());
- Record.AddDeclRef(D->getPropertyIvarDecl());
- Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
- Record.AddStmt(D->getGetterCXXConstructor());
- Record.AddStmt(D->getSetterCXXAssignment());
- Code = serialization::DECL_OBJC_PROPERTY_IMPL;
-}
-
-void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
- VisitDeclaratorDecl(D);
- Record.push_back(D->isMutable());
-
- FieldDecl::InitStorageKind ISK = D->InitStorage.getInt();
- Record.push_back(ISK);
- if (ISK == FieldDecl::ISK_CapturedVLAType)
- Record.AddTypeRef(QualType(D->getCapturedVLAType(), 0));
- else if (ISK)
- Record.AddStmt(D->getInClassInitializer());
-
- Record.AddStmt(D->getBitWidth());
-
- if (!D->getDeclName())
- Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
-
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
- !D->isTopLevelDeclInObjCContainer() &&
- !D->isModulePrivate() &&
- !D->getBitWidth() &&
- !D->hasInClassInitializer() &&
- !D->hasCapturedVLAType() &&
- !D->hasExtInfo() &&
- !ObjCIvarDecl::classofKind(D->getKind()) &&
- !ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
- D->getDeclName())
- AbbrevToUse = Writer.getDeclFieldAbbrev();
-
- Code = serialization::DECL_FIELD;
-}
-
-void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
- VisitDeclaratorDecl(D);
- Record.AddIdentifierRef(D->getGetterId());
- Record.AddIdentifierRef(D->getSetterId());
- Code = serialization::DECL_MS_PROPERTY;
-}
-
-void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
- VisitValueDecl(D);
- Record.push_back(D->getChainingSize());
-
- for (const auto *P : D->chain())
- Record.AddDeclRef(P);
- Code = serialization::DECL_INDIRECTFIELD;
-}
-
-void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
- VisitRedeclarable(D);
- VisitDeclaratorDecl(D);
- Record.push_back(D->getStorageClass());
- Record.push_back(D->getTSCSpec());
- Record.push_back(D->getInitStyle());
- Record.push_back(D->isARCPseudoStrong());
- if (!isa<ParmVarDecl>(D)) {
- Record.push_back(D->isThisDeclarationADemotedDefinition());
- Record.push_back(D->isExceptionVariable());
- Record.push_back(D->isNRVOVariable());
- Record.push_back(D->isCXXForRangeDecl());
- Record.push_back(D->isObjCForDecl());
- Record.push_back(D->isInline());
- Record.push_back(D->isInlineSpecified());
- Record.push_back(D->isConstexpr());
- Record.push_back(D->isInitCapture());
- Record.push_back(D->isPreviousDeclInSameBlockScope());
- if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D))
- Record.push_back(static_cast<unsigned>(IPD->getParameterKind()));
- else
- Record.push_back(0);
- Record.push_back(D->isEscapingByref());
- }
- Record.push_back(D->getLinkageInternal());
-
- if (D->getInit()) {
- Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2));
- Record.AddStmt(D->getInit());
- } else {
- Record.push_back(0);
- }
-
- if (D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) {
- ASTContext::BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
- Record.AddStmt(Init.getCopyExpr());
- if (Init.getCopyExpr())
- Record.push_back(Init.canThrow());
- }
-
- if (D->getStorageDuration() == SD_Static) {
- bool ModulesCodegen = false;
- if (Writer.WritingModule &&
- !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
- !isa<VarTemplateSpecializationDecl>(D)) {
- // When building a C++ Modules TS module interface unit, a strong
- // definition in the module interface is provided by the compilation of
- // that module interface unit, not by its users. (Inline variables are
- // still emitted in module users.)
- ModulesCodegen =
- (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit &&
- Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal);
- }
- Record.push_back(ModulesCodegen);
- if (ModulesCodegen)
- Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
- }
-
- enum {
- VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
- };
- if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
- Record.push_back(VarTemplate);
- Record.AddDeclRef(TemplD);
- } else if (MemberSpecializationInfo *SpecInfo
- = D->getMemberSpecializationInfo()) {
- Record.push_back(StaticDataMemberSpecialization);
- Record.AddDeclRef(SpecInfo->getInstantiatedFrom());
- Record.push_back(SpecInfo->getTemplateSpecializationKind());
- Record.AddSourceLocation(SpecInfo->getPointOfInstantiation());
- } else {
- Record.push_back(VarNotTemplate);
- }
-
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
- !D->isTopLevelDeclInObjCContainer() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
- !needsAnonymousDeclarationNumber(D) &&
- D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->hasExtInfo() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- D->getKind() == Decl::Var &&
- !D->isInline() &&
- !D->isConstexpr() &&
- !D->isInitCapture() &&
- !D->isPreviousDeclInSameBlockScope() &&
- !(D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) &&
- !D->isEscapingByref() &&
- D->getStorageDuration() != SD_Static &&
- !D->getMemberSpecializationInfo())
- AbbrevToUse = Writer.getDeclVarAbbrev();
-
- Code = serialization::DECL_VAR;
-}
-
-void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
- VisitVarDecl(D);
- Code = serialization::DECL_IMPLICIT_PARAM;
-}
-
-void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
- VisitVarDecl(D);
- Record.push_back(D->isObjCMethodParameter());
- Record.push_back(D->getFunctionScopeDepth());
- Record.push_back(D->getFunctionScopeIndex());
- Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
- Record.push_back(D->isKNRPromoted());
- Record.push_back(D->hasInheritedDefaultArg());
- Record.push_back(D->hasUninstantiatedDefaultArg());
- if (D->hasUninstantiatedDefaultArg())
- Record.AddStmt(D->getUninstantiatedDefaultArg());
- Code = serialization::DECL_PARM_VAR;
-
- assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl
-
- // If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here
- // we dynamically check for the properties that we optimize for, but don't
- // know are true of all PARM_VAR_DECLs.
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- !D->hasAttrs() &&
- !D->hasExtInfo() &&
- !D->isImplicit() &&
- !D->isUsed(false) &&
- !D->isInvalidDecl() &&
- !D->isReferenced() &&
- D->getAccess() == AS_none &&
- !D->isModulePrivate() &&
- D->getStorageClass() == 0 &&
- D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
- D->getFunctionScopeDepth() == 0 &&
- D->getObjCDeclQualifier() == 0 &&
- !D->isKNRPromoted() &&
- !D->hasInheritedDefaultArg() &&
- D->getInit() == nullptr &&
- !D->hasUninstantiatedDefaultArg()) // No default expr.
- AbbrevToUse = Writer.getDeclParmVarAbbrev();
-
- // Check things we know are true of *every* PARM_VAR_DECL, which is more than
- // just us assuming it.
- assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
- assert(!D->isThisDeclarationADemotedDefinition()
- && "PARM_VAR_DECL can't be demoted definition.");
- assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
- assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
- assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
- assert(!D->isStaticDataMember() &&
- "PARM_VAR_DECL can't be static data member");
-}
-
-void ASTDeclWriter::VisitDecompositionDecl(DecompositionDecl *D) {
- // Record the number of bindings first to simplify deserialization.
- Record.push_back(D->bindings().size());
-
- VisitVarDecl(D);
- for (auto *B : D->bindings())
- Record.AddDeclRef(B);
- Code = serialization::DECL_DECOMPOSITION;
-}
-
-void ASTDeclWriter::VisitBindingDecl(BindingDecl *D) {
- VisitValueDecl(D);
- Record.AddStmt(D->getBinding());
- Code = serialization::DECL_BINDING;
-}
-
-void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
- VisitDecl(D);
- Record.AddStmt(D->getAsmString());
- Record.AddSourceLocation(D->getRParenLoc());
- Code = serialization::DECL_FILE_SCOPE_ASM;
-}
-
-void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
- VisitDecl(D);
- Code = serialization::DECL_EMPTY;
-}
-
-void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
- VisitDecl(D);
- Record.AddStmt(D->getBody());
- Record.AddTypeSourceInfo(D->getSignatureAsWritten());
- Record.push_back(D->param_size());
- for (ParmVarDecl *P : D->parameters())
- Record.AddDeclRef(P);
- Record.push_back(D->isVariadic());
- Record.push_back(D->blockMissingReturnType());
- Record.push_back(D->isConversionFromLambda());
- Record.push_back(D->doesNotEscape());
- Record.push_back(D->capturesCXXThis());
- Record.push_back(D->getNumCaptures());
- for (const auto &capture : D->captures()) {
- Record.AddDeclRef(capture.getVariable());
-
- unsigned flags = 0;
- if (capture.isByRef()) flags |= 1;
- if (capture.isNested()) flags |= 2;
- if (capture.hasCopyExpr()) flags |= 4;
- Record.push_back(flags);
-
- if (capture.hasCopyExpr()) Record.AddStmt(capture.getCopyExpr());
- }
-
- Code = serialization::DECL_BLOCK;
-}
-
-void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
- Record.push_back(CD->getNumParams());
- VisitDecl(CD);
- Record.push_back(CD->getContextParamPosition());
- Record.push_back(CD->isNothrow() ? 1 : 0);
- // Body is stored by VisitCapturedStmt.
- for (unsigned I = 0; I < CD->getNumParams(); ++I)
- Record.AddDeclRef(CD->getParam(I));
- Code = serialization::DECL_CAPTURED;
-}
-
-void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
- VisitDecl(D);
- Record.push_back(D->getLanguage());
- Record.AddSourceLocation(D->getExternLoc());
- Record.AddSourceLocation(D->getRBraceLoc());
- Code = serialization::DECL_LINKAGE_SPEC;
-}
-
-void ASTDeclWriter::VisitExportDecl(ExportDecl *D) {
- VisitDecl(D);
- Record.AddSourceLocation(D->getRBraceLoc());
- Code = serialization::DECL_EXPORT;
-}
-
-void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getBeginLoc());
- Code = serialization::DECL_LABEL;
-}
-
-
-void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
- VisitRedeclarable(D);
- VisitNamedDecl(D);
- Record.push_back(D->isInline());
- Record.AddSourceLocation(D->getBeginLoc());
- Record.AddSourceLocation(D->getRBraceLoc());
-
- if (D->isOriginalNamespace())
- Record.AddDeclRef(D->getAnonymousNamespace());
- Code = serialization::DECL_NAMESPACE;
-
- if (Writer.hasChain() && D->isAnonymousNamespace() &&
- D == D->getMostRecentDecl()) {
- // This is a most recent reopening of the anonymous namespace. If its parent
- // is in a previous PCH (or is the TU), mark that parent for update, because
- // the original namespace always points to the latest re-opening of its
- // anonymous namespace.
- Decl *Parent = cast<Decl>(
- D->getParent()->getRedeclContext()->getPrimaryContext());
- if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
- Writer.DeclUpdates[Parent].push_back(
- ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
- }
- }
-}
-
-void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
- VisitRedeclarable(D);
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getNamespaceLoc());
- Record.AddSourceLocation(D->getTargetNameLoc());
- Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
- Record.AddDeclRef(D->getNamespace());
- Code = serialization::DECL_NAMESPACE_ALIAS;
-}
-
-void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getUsingLoc());
- Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
- Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
- Record.AddDeclRef(D->FirstUsingShadow.getPointer());
- Record.push_back(D->hasTypename());
- Record.AddDeclRef(Context.getInstantiatedFromUsingDecl(D));
- Code = serialization::DECL_USING;
-}
-
-void ASTDeclWriter::VisitUsingPackDecl(UsingPackDecl *D) {
- Record.push_back(D->NumExpansions);
- VisitNamedDecl(D);
- Record.AddDeclRef(D->getInstantiatedFromUsingDecl());
- for (auto *E : D->expansions())
- Record.AddDeclRef(E);
- Code = serialization::DECL_USING_PACK;
-}
-
-void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
- VisitRedeclarable(D);
- VisitNamedDecl(D);
- Record.AddDeclRef(D->getTargetDecl());
- Record.push_back(D->getIdentifierNamespace());
- Record.AddDeclRef(D->UsingOrNextShadow);
- Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
- Code = serialization::DECL_USING_SHADOW;
-}
-
-void ASTDeclWriter::VisitConstructorUsingShadowDecl(
- ConstructorUsingShadowDecl *D) {
- VisitUsingShadowDecl(D);
- Record.AddDeclRef(D->NominatedBaseClassShadowDecl);
- Record.AddDeclRef(D->ConstructedBaseClassShadowDecl);
- Record.push_back(D->IsVirtual);
- Code = serialization::DECL_CONSTRUCTOR_USING_SHADOW;
-}
-
-void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
- VisitNamedDecl(D);
- Record.AddSourceLocation(D->getUsingLoc());
- Record.AddSourceLocation(D->getNamespaceKeyLocation());
- Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
- Record.AddDeclRef(D->getNominatedNamespace());
- Record.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()));
- Code = serialization::DECL_USING_DIRECTIVE;
-}
-
-void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
- VisitValueDecl(D);
- Record.AddSourceLocation(D->getUsingLoc());
- Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
- Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
- Record.AddSourceLocation(D->getEllipsisLoc());
- Code = serialization::DECL_UNRESOLVED_USING_VALUE;
-}
-
-void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
- UnresolvedUsingTypenameDecl *D) {
- VisitTypeDecl(D);
- Record.AddSourceLocation(D->getTypenameLoc());
- Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
- Record.AddSourceLocation(D->getEllipsisLoc());
- Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
-}
-
-void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
- VisitRecordDecl(D);
-
- enum {
- CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
- };
- if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
- Record.push_back(CXXRecTemplate);
- Record.AddDeclRef(TemplD);
- } else if (MemberSpecializationInfo *MSInfo
- = D->getMemberSpecializationInfo()) {
- Record.push_back(CXXRecMemberSpecialization);
- Record.AddDeclRef(MSInfo->getInstantiatedFrom());
- Record.push_back(MSInfo->getTemplateSpecializationKind());
- Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
- } else {
- Record.push_back(CXXRecNotTemplate);
- }
-
- Record.push_back(D->isThisDeclarationADefinition());
- if (D->isThisDeclarationADefinition())
- Record.AddCXXDefinitionData(D);
-
- // Store (what we currently believe to be) the key function to avoid
- // deserializing every method so we can compute it.
- if (D->isCompleteDefinition())
- Record.AddDeclRef(Context.getCurrentKeyFunction(D));
-
- Code = serialization::DECL_CXX_RECORD;
-}
-
-void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
- VisitFunctionDecl(D);
- if (D->isCanonicalDecl()) {
- Record.push_back(D->size_overridden_methods());
- for (const CXXMethodDecl *MD : D->overridden_methods())
- Record.AddDeclRef(MD);
- } else {
- // We only need to record overridden methods once for the canonical decl.
- Record.push_back(0);
- }
-
- if (D->getDeclContext() == D->getLexicalDeclContext() &&
- D->getFirstDecl() == D->getMostRecentDecl() &&
- !D->isInvalidDecl() &&
- !D->hasAttrs() &&
- !D->isTopLevelDeclInObjCContainer() &&
- D->getDeclName().getNameKind() == DeclarationName::Identifier &&
- !D->hasExtInfo() &&
- !D->hasInheritedPrototype() &&
- D->hasWrittenPrototype())
- AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
-
- Code = serialization::DECL_CXX_METHOD;
-}
-
-void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- if (auto Inherited = D->getInheritedConstructor()) {
- Record.AddDeclRef(Inherited.getShadowDecl());
- Record.AddDeclRef(Inherited.getConstructor());
- Code = serialization::DECL_CXX_INHERITED_CONSTRUCTOR;
- } else {
- Code = serialization::DECL_CXX_CONSTRUCTOR;
- }
-
- VisitCXXMethodDecl(D);
-
- Code = D->isInheritingConstructor()
- ? serialization::DECL_CXX_INHERITED_CONSTRUCTOR
- : serialization::DECL_CXX_CONSTRUCTOR;
-}
-
-void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
- VisitCXXMethodDecl(D);
-
- Record.AddDeclRef(D->getOperatorDelete());
- if (D->getOperatorDelete())
- Record.AddStmt(D->getOperatorDeleteThisArg());
-
- Code = serialization::DECL_CXX_DESTRUCTOR;
-}
-
-void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
- VisitCXXMethodDecl(D);
- Code = serialization::DECL_CXX_CONVERSION;
-}
-
-void ASTDeclWriter::VisitImportDecl(ImportDecl *D) {
- VisitDecl(D);
- Record.push_back(Writer.getSubmoduleID(D->getImportedModule()));
- ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
- Record.push_back(!IdentifierLocs.empty());
- if (IdentifierLocs.empty()) {
- Record.AddSourceLocation(D->getEndLoc());
- Record.push_back(1);
- } else {
- for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
- Record.AddSourceLocation(IdentifierLocs[I]);
- Record.push_back(IdentifierLocs.size());
- }
- // Note: the number of source locations must always be the last element in
- // the record.
- Code = serialization::DECL_IMPORT;
-}
-
-void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
- VisitDecl(D);
- Record.AddSourceLocation(D->getColonLoc());
- Code = serialization::DECL_ACCESS_SPEC;
-}
-
-void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
- // Record the number of friend type template parameter lists here
- // so as to simplify memory allocation during deserialization.
- Record.push_back(D->NumTPLists);
- VisitDecl(D);
- bool hasFriendDecl = D->Friend.is<NamedDecl*>();
- Record.push_back(hasFriendDecl);
- if (hasFriendDecl)
- Record.AddDeclRef(D->getFriendDecl());
- else
- Record.AddTypeSourceInfo(D->getFriendType());
- for (unsigned i = 0; i < D->NumTPLists; ++i)
- Record.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i));
- Record.AddDeclRef(D->getNextFriend());
- Record.push_back(D->UnsupportedFriend);
- Record.AddSourceLocation(D->FriendLoc);
- Code = serialization::DECL_FRIEND;
-}
-
-void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
- VisitDecl(D);
- Record.push_back(D->getNumTemplateParameters());
- for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
- Record.AddTemplateParameterList(D->getTemplateParameterList(i));
- Record.push_back(D->getFriendDecl() != nullptr);
- if (D->getFriendDecl())
- Record.AddDeclRef(D->getFriendDecl());
- else
- Record.AddTypeSourceInfo(D->getFriendType());
- Record.AddSourceLocation(D->getFriendLoc());
- Code = serialization::DECL_FRIEND_TEMPLATE;
-}
-
-void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
- VisitNamedDecl(D);
-
- Record.AddDeclRef(D->getTemplatedDecl());
- Record.AddTemplateParameterList(D->getTemplateParameters());
-}
-
-void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
- VisitRedeclarable(D);
-
- // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
- // getCommonPtr() can be used while this is still initializing.
- if (D->isFirstDecl()) {
- // This declaration owns the 'common' pointer, so serialize that data now.
- Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
- if (D->getInstantiatedFromMemberTemplate())
- Record.push_back(D->isMemberSpecialization());
- }
-
- VisitTemplateDecl(D);
- Record.push_back(D->getIdentifierNamespace());
-}
-
-void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
-
- if (D->isFirstDecl())
- AddTemplateSpecializations(D);
- Code = serialization::DECL_CLASS_TEMPLATE;
-}
-
-void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
- ClassTemplateSpecializationDecl *D) {
- RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
-
- VisitCXXRecordDecl(D);
-
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *> InstFrom
- = D->getSpecializedTemplateOrPartial();
- if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
- Record.AddDeclRef(InstFromD);
- } else {
- Record.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>());
- Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
- }
-
- Record.AddTemplateArgumentList(&D->getTemplateArgs());
- Record.AddSourceLocation(D->getPointOfInstantiation());
- Record.push_back(D->getSpecializationKind());
- Record.push_back(D->isCanonicalDecl());
-
- if (D->isCanonicalDecl()) {
- // When reading, we'll add it to the folding set of the following template.
- Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
- }
-
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
- Record.AddSourceLocation(D->getTemplateKeywordLoc());
- }
-
- Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
-}
-
-void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
- ClassTemplatePartialSpecializationDecl *D) {
- VisitClassTemplateSpecializationDecl(D);
-
- Record.AddTemplateParameterList(D->getTemplateParameters());
- Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
-
- // These are read/set from/to the first declaration.
- if (D->getPreviousDecl() == nullptr) {
- Record.AddDeclRef(D->getInstantiatedFromMember());
- Record.push_back(D->isMemberSpecialization());
- }
-
- Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
-}
-
-void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
-
- if (D->isFirstDecl())
- AddTemplateSpecializations(D);
- Code = serialization::DECL_VAR_TEMPLATE;
-}
-
-void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
- VarTemplateSpecializationDecl *D) {
- RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
-
- VisitVarDecl(D);
-
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- InstFrom = D->getSpecializedTemplateOrPartial();
- if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
- Record.AddDeclRef(InstFromD);
- } else {
- Record.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>());
- Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
- }
-
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
- Record.AddSourceLocation(D->getTemplateKeywordLoc());
- }
-
- Record.AddTemplateArgumentList(&D->getTemplateArgs());
- Record.AddSourceLocation(D->getPointOfInstantiation());
- Record.push_back(D->getSpecializationKind());
- Record.push_back(D->IsCompleteDefinition);
- Record.push_back(D->isCanonicalDecl());
-
- if (D->isCanonicalDecl()) {
- // When reading, we'll add it to the folding set of the following template.
- Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
- }
-
- Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
-}
-
-void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
- VarTemplatePartialSpecializationDecl *D) {
- VisitVarTemplateSpecializationDecl(D);
-
- Record.AddTemplateParameterList(D->getTemplateParameters());
- Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
-
- // These are read/set from/to the first declaration.
- if (D->getPreviousDecl() == nullptr) {
- Record.AddDeclRef(D->getInstantiatedFromMember());
- Record.push_back(D->isMemberSpecialization());
- }
-
- Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
-}
-
-void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
- ClassScopeFunctionSpecializationDecl *D) {
- VisitDecl(D);
- Record.AddDeclRef(D->getSpecialization());
- Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
-}
-
-
-void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
-
- if (D->isFirstDecl())
- AddTemplateSpecializations(D);
- Code = serialization::DECL_FUNCTION_TEMPLATE;
-}
-
-void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
- VisitTypeDecl(D);
-
- Record.push_back(D->wasDeclaredWithTypename());
-
- bool OwnsDefaultArg = D->hasDefaultArgument() &&
- !D->defaultArgumentWasInherited();
- Record.push_back(OwnsDefaultArg);
- if (OwnsDefaultArg)
- Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
-
- Code = serialization::DECL_TEMPLATE_TYPE_PARM;
-}
-
-void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
- // For an expanded parameter pack, record the number of expansion types here
- // so that it's easier for deserialization to allocate the right amount of
- // memory.
- if (D->isExpandedParameterPack())
- Record.push_back(D->getNumExpansionTypes());
-
- VisitDeclaratorDecl(D);
- // TemplateParmPosition.
- Record.push_back(D->getDepth());
- Record.push_back(D->getPosition());
-
- if (D->isExpandedParameterPack()) {
- for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
- Record.AddTypeRef(D->getExpansionType(I));
- Record.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I));
- }
-
- Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
- } else {
- // Rest of NonTypeTemplateParmDecl.
- Record.push_back(D->isParameterPack());
- bool OwnsDefaultArg = D->hasDefaultArgument() &&
- !D->defaultArgumentWasInherited();
- Record.push_back(OwnsDefaultArg);
- if (OwnsDefaultArg)
- Record.AddStmt(D->getDefaultArgument());
- Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
- }
-}
-
-void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
- // For an expanded parameter pack, record the number of expansion types here
- // so that it's easier for deserialization to allocate the right amount of
- // memory.
- if (D->isExpandedParameterPack())
- Record.push_back(D->getNumExpansionTemplateParameters());
-
- VisitTemplateDecl(D);
- // TemplateParmPosition.
- Record.push_back(D->getDepth());
- Record.push_back(D->getPosition());
-
- if (D->isExpandedParameterPack()) {
- for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
- I != N; ++I)
- Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I));
- Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
- } else {
- // Rest of TemplateTemplateParmDecl.
- Record.push_back(D->isParameterPack());
- bool OwnsDefaultArg = D->hasDefaultArgument() &&
- !D->defaultArgumentWasInherited();
- Record.push_back(OwnsDefaultArg);
- if (OwnsDefaultArg)
- Record.AddTemplateArgumentLoc(D->getDefaultArgument());
- Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
- }
-}
-
-void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
- Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
-}
-
-void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
- VisitDecl(D);
- Record.AddStmt(D->getAssertExpr());
- Record.push_back(D->isFailed());
- Record.AddStmt(D->getMessage());
- Record.AddSourceLocation(D->getRParenLoc());
- Code = serialization::DECL_STATIC_ASSERT;
-}
-
-/// Emit the DeclContext part of a declaration context decl.
-void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
- Record.AddOffset(Writer.WriteDeclContextLexicalBlock(Context, DC));
- Record.AddOffset(Writer.WriteDeclContextVisibleBlock(Context, DC));
-}
-
-const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
- assert(IsLocalDecl(D) && "expected a local declaration");
-
- const Decl *Canon = D->getCanonicalDecl();
- if (IsLocalDecl(Canon))
- return Canon;
-
- const Decl *&CacheEntry = FirstLocalDeclCache[Canon];
- if (CacheEntry)
- return CacheEntry;
-
- for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl())
- if (IsLocalDecl(Redecl))
- D = Redecl;
- return CacheEntry = D;
-}
-
-template <typename T>
-void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
- T *First = D->getFirstDecl();
- T *MostRecent = First->getMostRecentDecl();
- T *DAsT = static_cast<T *>(D);
- if (MostRecent != First) {
- assert(isRedeclarableDeclKind(DAsT->getKind()) &&
- "Not considered redeclarable?");
-
- Record.AddDeclRef(First);
-
- // Write out a list of local redeclarations of this declaration if it's the
- // first local declaration in the chain.
- const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT);
- if (DAsT == FirstLocal) {
- // Emit a list of all imported first declarations so that we can be sure
- // that all redeclarations visible to this module are before D in the
- // redecl chain.
- unsigned I = Record.size();
- Record.push_back(0);
- if (Writer.Chain)
- AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
- // This is the number of imported first declarations + 1.
- Record[I] = Record.size() - I;
-
- // Collect the set of local redeclarations of this declaration, from
- // newest to oldest.
- ASTWriter::RecordData LocalRedecls;
- ASTRecordWriter LocalRedeclWriter(Record, LocalRedecls);
- for (const Decl *Prev = FirstLocal->getMostRecentDecl();
- Prev != FirstLocal; Prev = Prev->getPreviousDecl())
- if (!Prev->isFromASTFile())
- LocalRedeclWriter.AddDeclRef(Prev);
-
- // If we have any redecls, write them now as a separate record preceding
- // the declaration itself.
- if (LocalRedecls.empty())
- Record.push_back(0);
- else
- Record.AddOffset(LocalRedeclWriter.Emit(LOCAL_REDECLARATIONS));
- } else {
- Record.push_back(0);
- Record.AddDeclRef(FirstLocal);
- }
-
- // Make sure that we serialize both the previous and the most-recent
- // declarations, which (transitively) ensures that all declarations in the
- // chain get serialized.
- //
- // FIXME: This is not correct; when we reach an imported declaration we
- // won't emit its previous declaration.
- (void)Writer.GetDeclRef(D->getPreviousDecl());
- (void)Writer.GetDeclRef(MostRecent);
- } else {
- // We use the sentinel value 0 to indicate an only declaration.
- Record.push_back(0);
- }
-}
-
-void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
- Record.push_back(D->varlist_size());
- VisitDecl(D);
- for (auto *I : D->varlists())
- Record.AddStmt(I);
- Code = serialization::DECL_OMP_THREADPRIVATE;
-}
-
-void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
- Record.push_back(D->clauselist_size());
- VisitDecl(D);
- OMPClauseWriter ClauseWriter(Record);
- for (OMPClause *C : D->clauselists())
- ClauseWriter.writeClause(C);
- Code = serialization::DECL_OMP_REQUIRES;
-}
-
-void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
- VisitValueDecl(D);
- Record.AddSourceLocation(D->getBeginLoc());
- Record.AddStmt(D->getCombinerIn());
- Record.AddStmt(D->getCombinerOut());
- Record.AddStmt(D->getCombiner());
- Record.AddStmt(D->getInitOrig());
- Record.AddStmt(D->getInitPriv());
- Record.AddStmt(D->getInitializer());
- Record.push_back(D->getInitializerKind());
- Record.AddDeclRef(D->getPrevDeclInScope());
- Code = serialization::DECL_OMP_DECLARE_REDUCTION;
-}
-
-void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
- VisitVarDecl(D);
- Code = serialization::DECL_OMP_CAPTUREDEXPR;
-}
-
-//===----------------------------------------------------------------------===//
-// ASTWriter Implementation
-//===----------------------------------------------------------------------===//
-
-void ASTWriter::WriteDeclAbbrevs() {
- using namespace llvm;
-
- std::shared_ptr<BitCodeAbbrev> Abv;
-
- // Abbreviation for DECL_FIELD
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // ValueDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DeclaratorDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
- Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
- // FieldDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
- Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
- // Type Source Info
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
- DeclFieldAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_OBJC_IVAR
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // ValueDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DeclaratorDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
- Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
- // FieldDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
- Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
- // ObjC Ivar
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
- // Type Source Info
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
- DeclObjCIvarAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_ENUM
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // TypeDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
- // TagDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
- Abv->Add(BitCodeAbbrevOp(0)); // ExtInfoKind
- // EnumDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddTypeRef
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IntegerType
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getPromotionType
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getNumPositiveBits
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getNumNegativeBits
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScoped
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScopedUsingClassTag
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isFixed
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedMembEnum
- // DC
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
- DeclEnumAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_RECORD
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // TypeDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
- // TagDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
- Abv->Add(BitCodeAbbrevOp(0)); // ExtInfoKind
- // RecordDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember
-
- // isNonTrivialToPrimitiveDefaultInitialize
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // isNonTrivialToPrimitiveCopy
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // isNonTrivialToPrimitiveDestroy
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // isParamDestroyedInCallee
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // getArgPassingRestrictions
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
-
- // DC
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
- DeclRecordAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_PARM_VAR
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // ValueDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DeclaratorDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
- Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
- // VarDecl
- Abv->Add(BitCodeAbbrevOp(0)); // SClass
- Abv->Add(BitCodeAbbrevOp(0)); // TSCSpec
- Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
- Abv->Add(BitCodeAbbrevOp(0)); // ARCPseudoStrong
- Abv->Add(BitCodeAbbrevOp(0)); // Linkage
- Abv->Add(BitCodeAbbrevOp(0)); // HasInit
- Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo
- // ParmVarDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
- Abv->Add(BitCodeAbbrevOp(0)); // ScopeDepth
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
- Abv->Add(BitCodeAbbrevOp(0)); // ObjCDeclQualifier
- Abv->Add(BitCodeAbbrevOp(0)); // KNRPromoted
- Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedDefaultArg
- Abv->Add(BitCodeAbbrevOp(0)); // HasUninstantiatedDefaultArg
- // Type Source Info
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
- DeclParmVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_TYPEDEF
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // TypeDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
- // TypedefDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
- DeclTypedefAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_VAR
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
- // Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
- Abv->Add(BitCodeAbbrevOp(0)); // isUsed
- Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
- Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
- Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
- Abv->Add(BitCodeAbbrevOp(0)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // ValueDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DeclaratorDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
- Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
- // VarDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl
- Abv->Add(BitCodeAbbrevOp(0)); // isInline
- Abv->Add(BitCodeAbbrevOp(0)); // isInlineSpecified
- Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr
- Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture
- Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope
- Abv->Add(BitCodeAbbrevOp(0)); // ImplicitParamKind
- Abv->Add(BitCodeAbbrevOp(0)); // EscapingByref
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // IsInitICE (local)
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // VarKind (local enum)
- // Type Source Info
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
- DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for DECL_CXX_METHOD
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
- // RedeclarableDecl
- Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
- // Decl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
- Abv->Add(BitCodeAbbrevOp(0)); // Invalid
- Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
- Abv->Add(BitCodeAbbrevOp(0)); // InObjCContainer
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModulePrivate
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
- // NamedDecl
- Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier
- Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
- // ValueDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- // DeclaratorDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
- Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
- // FunctionDecl
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitSpecified
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
- Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedProto
- Abv->Add(BitCodeAbbrevOp(1)); // HasWrittenProto
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Deleted
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // TrivialForCall
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // MultiVersion
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
- // This Array slurps the rest of the record. Fortunately we want to encode
- // (nearly) all the remaining (variable number of) fields in the same way.
- //
- // This is the function template information if any, then
- // NumParams and Params[] from FunctionDecl, and
- // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
- //
- // Add an AbbrevOp for 'size then elements' and use it here.
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
- DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for EXPR_DECL_REF
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
- //Stmt
- //Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
- //DeclRefExpr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
- 1)); // RefersToEnclosingVariableOrCapture
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
- DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for EXPR_INTEGER_LITERAL
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
- //Stmt
- //Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
- //Integer Literal
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
- Abv->Add(BitCodeAbbrevOp(32)); // Bit Width
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
- IntegerLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for EXPR_CHARACTER_LITERAL
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
- //Stmt
- //Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
- //Character Literal
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
- CharacterLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- // Abbreviation for EXPR_IMPLICIT_CAST
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
- // Stmt
- // Expr
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
- // CastExpr
- Abv->Add(BitCodeAbbrevOp(0)); // PathSize
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast
- // ImplicitCastExpr
- ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- DeclContextLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
-
- Abv = std::make_shared<BitCodeAbbrev>();
- Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
-}
-
-/// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
-/// consumers of the AST.
-///
-/// Such decls will always be deserialized from the AST file, so we would like
-/// this to be as restrictive as possible. Currently the predicate is driven by
-/// code generation requirements, if other clients have a different notion of
-/// what is "required" then we may have to consider an alternate scheme where
-/// clients can iterate over the top-level decls and get information on them,
-/// without necessary deserializing them. We could explicitly require such
-/// clients to use a separate API call to "realize" the decl. This should be
-/// relatively painless since they would presumably only do it for top-level
-/// decls.
-static bool isRequiredDecl(const Decl *D, ASTContext &Context,
- bool WritingModule) {
- // An ObjCMethodDecl is never considered as "required" because its
- // implementation container always is.
-
- // File scoped assembly or obj-c or OMP declare target implementation must be
- // seen.
- if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
- return true;
-
- if (WritingModule && (isa<VarDecl>(D) || isa<ImportDecl>(D))) {
- // These declarations are part of the module initializer, and are emitted
- // if and when the module is imported, rather than being emitted eagerly.
- return false;
- }
-
- return Context.DeclMustBeEmitted(D);
-}
-
-void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
- PrettyDeclStackTraceEntry CrashInfo(Context, D, SourceLocation(),
- "serializing");
-
- // Determine the ID for this declaration.
- serialization::DeclID ID;
- assert(!D->isFromASTFile() && "should not be emitting imported decl");
- serialization::DeclID &IDR = DeclIDs[D];
- if (IDR == 0)
- IDR = NextDeclID++;
-
- ID = IDR;
-
- assert(ID >= FirstDeclID && "invalid decl ID");
-
- RecordData Record;
- ASTDeclWriter W(*this, Context, Record);
-
- // Build a record for this declaration
- W.Visit(D);
-
- // Emit this declaration to the bitstream.
- uint64_t Offset = W.Emit(D);
-
- // Record the offset for this declaration
- SourceLocation Loc = D->getLocation();
- unsigned Index = ID - FirstDeclID;
- if (DeclOffsets.size() == Index)
- DeclOffsets.push_back(DeclOffset(Loc, Offset));
- else if (DeclOffsets.size() < Index) {
- // FIXME: Can/should this happen?
- DeclOffsets.resize(Index+1);
- DeclOffsets[Index].setLocation(Loc);
- DeclOffsets[Index].BitOffset = Offset;
- } else {
- llvm_unreachable("declarations should be emitted in ID order");
- }
-
- SourceManager &SM = Context.getSourceManager();
- if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
- associateDeclWithFile(D, ID);
-
- // Note declarations that should be deserialized eagerly so that we can add
- // them to a record in the AST file later.
- if (isRequiredDecl(D, Context, WritingModule))
- EagerlyDeserializedDecls.push_back(ID);
-}
-
-void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
- // Switch case IDs are per function body.
- Writer->ClearSwitchCaseIDs();
-
- assert(FD->doesThisDeclarationHaveABody());
- bool ModulesCodegen = false;
- if (Writer->WritingModule && !FD->isDependentContext()) {
- Optional<GVALinkage> Linkage;
- if (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) {
- // When building a C++ Modules TS module interface unit, a strong
- // definition in the module interface is provided by the compilation of
- // that module interface unit, not by its users. (Inline functions are
- // still emitted in module users.)
- Linkage = Writer->Context->GetGVALinkageForFunction(FD);
- ModulesCodegen = *Linkage == GVA_StrongExternal;
- }
- if (Writer->Context->getLangOpts().ModulesCodegen) {
- // Under -fmodules-codegen, codegen is performed for all non-internal,
- // non-always_inline functions.
- if (!FD->hasAttr<AlwaysInlineAttr>()) {
- if (!Linkage)
- Linkage = Writer->Context->GetGVALinkageForFunction(FD);
- ModulesCodegen = *Linkage != GVA_Internal;
- }
- }
- }
- Record->push_back(ModulesCodegen);
- if (ModulesCodegen)
- Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD));
- if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
- Record->push_back(CD->getNumCtorInitializers());
- if (CD->getNumCtorInitializers())
- AddCXXCtorInitializers(
- llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
- }
- AddStmt(FD->getBody());
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp b/gnu/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp
deleted file mode 100644
index 6f8b86edcdf..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp
+++ /dev/null
@@ -1,2368 +0,0 @@
-//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Implements serialization for Statements and Expressions.
-///
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/ASTWriter.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/Lex/Token.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Statement/expression serialization
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-
- class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
- ASTWriter &Writer;
- ASTRecordWriter Record;
-
- serialization::StmtCode Code;
- unsigned AbbrevToUse;
-
- public:
- ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
- : Writer(Writer), Record(Writer, Record),
- Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
-
- ASTStmtWriter(const ASTStmtWriter&) = delete;
-
- uint64_t Emit() {
- assert(Code != serialization::STMT_NULL_PTR &&
- "unhandled sub-statement writing AST file");
- return Record.EmitStmt(Code, AbbrevToUse);
- }
-
- void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
- const TemplateArgumentLoc *Args);
-
- void VisitStmt(Stmt *S);
-#define STMT(Type, Base) \
- void Visit##Type(Type *);
-#include "clang/AST/StmtNodes.inc"
- };
-}
-
-void ASTStmtWriter::AddTemplateKWAndArgsInfo(
- const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
- Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
- Record.AddSourceLocation(ArgInfo.LAngleLoc);
- Record.AddSourceLocation(ArgInfo.RAngleLoc);
- for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
- Record.AddTemplateArgumentLoc(Args[i]);
-}
-
-void ASTStmtWriter::VisitStmt(Stmt *S) {
-}
-
-void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getSemiLoc());
- Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
- Code = serialization::STMT_NULL;
-}
-
-void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
- VisitStmt(S);
- Record.push_back(S->size());
- for (auto *CS : S->body())
- Record.AddStmt(CS);
- Record.AddSourceLocation(S->getLBracLoc());
- Record.AddSourceLocation(S->getRBracLoc());
- Code = serialization::STMT_COMPOUND;
-}
-
-void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
- VisitStmt(S);
- Record.push_back(Writer.getSwitchCaseID(S));
- Record.AddSourceLocation(S->getKeywordLoc());
- Record.AddSourceLocation(S->getColonLoc());
-}
-
-void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
- VisitSwitchCase(S);
- Record.push_back(S->caseStmtIsGNURange());
- Record.AddStmt(S->getLHS());
- Record.AddStmt(S->getSubStmt());
- if (S->caseStmtIsGNURange()) {
- Record.AddStmt(S->getRHS());
- Record.AddSourceLocation(S->getEllipsisLoc());
- }
- Code = serialization::STMT_CASE;
-}
-
-void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
- VisitSwitchCase(S);
- Record.AddStmt(S->getSubStmt());
- Code = serialization::STMT_DEFAULT;
-}
-
-void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
- VisitStmt(S);
- Record.AddDeclRef(S->getDecl());
- Record.AddStmt(S->getSubStmt());
- Record.AddSourceLocation(S->getIdentLoc());
- Code = serialization::STMT_LABEL;
-}
-
-void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
- VisitStmt(S);
- Record.push_back(S->getAttrs().size());
- Record.AddAttributes(S->getAttrs());
- Record.AddStmt(S->getSubStmt());
- Record.AddSourceLocation(S->getAttrLoc());
- Code = serialization::STMT_ATTRIBUTED;
-}
-
-void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
- VisitStmt(S);
-
- bool HasElse = S->getElse() != nullptr;
- bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
- bool HasInit = S->getInit() != nullptr;
-
- Record.push_back(S->isConstexpr());
- Record.push_back(HasElse);
- Record.push_back(HasVar);
- Record.push_back(HasInit);
-
- Record.AddStmt(S->getCond());
- Record.AddStmt(S->getThen());
- if (HasElse)
- Record.AddStmt(S->getElse());
- if (HasVar)
- Record.AddDeclRef(S->getConditionVariable());
- if (HasInit)
- Record.AddStmt(S->getInit());
-
- Record.AddSourceLocation(S->getIfLoc());
- if (HasElse)
- Record.AddSourceLocation(S->getElseLoc());
-
- Code = serialization::STMT_IF;
-}
-
-void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
- VisitStmt(S);
-
- bool HasInit = S->getInit() != nullptr;
- bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
- Record.push_back(HasInit);
- Record.push_back(HasVar);
- Record.push_back(S->isAllEnumCasesCovered());
-
- Record.AddStmt(S->getCond());
- Record.AddStmt(S->getBody());
- if (HasInit)
- Record.AddStmt(S->getInit());
- if (HasVar)
- Record.AddDeclRef(S->getConditionVariable());
-
- Record.AddSourceLocation(S->getSwitchLoc());
-
- for (SwitchCase *SC = S->getSwitchCaseList(); SC;
- SC = SC->getNextSwitchCase())
- Record.push_back(Writer.RecordSwitchCaseID(SC));
- Code = serialization::STMT_SWITCH;
-}
-
-void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
- VisitStmt(S);
-
- bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
- Record.push_back(HasVar);
-
- Record.AddStmt(S->getCond());
- Record.AddStmt(S->getBody());
- if (HasVar)
- Record.AddDeclRef(S->getConditionVariable());
-
- Record.AddSourceLocation(S->getWhileLoc());
- Code = serialization::STMT_WHILE;
-}
-
-void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
- VisitStmt(S);
- Record.AddStmt(S->getCond());
- Record.AddStmt(S->getBody());
- Record.AddSourceLocation(S->getDoLoc());
- Record.AddSourceLocation(S->getWhileLoc());
- Record.AddSourceLocation(S->getRParenLoc());
- Code = serialization::STMT_DO;
-}
-
-void ASTStmtWriter::VisitForStmt(ForStmt *S) {
- VisitStmt(S);
- Record.AddStmt(S->getInit());
- Record.AddStmt(S->getCond());
- Record.AddDeclRef(S->getConditionVariable());
- Record.AddStmt(S->getInc());
- Record.AddStmt(S->getBody());
- Record.AddSourceLocation(S->getForLoc());
- Record.AddSourceLocation(S->getLParenLoc());
- Record.AddSourceLocation(S->getRParenLoc());
- Code = serialization::STMT_FOR;
-}
-
-void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
- VisitStmt(S);
- Record.AddDeclRef(S->getLabel());
- Record.AddSourceLocation(S->getGotoLoc());
- Record.AddSourceLocation(S->getLabelLoc());
- Code = serialization::STMT_GOTO;
-}
-
-void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getGotoLoc());
- Record.AddSourceLocation(S->getStarLoc());
- Record.AddStmt(S->getTarget());
- Code = serialization::STMT_INDIRECT_GOTO;
-}
-
-void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getContinueLoc());
- Code = serialization::STMT_CONTINUE;
-}
-
-void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getBreakLoc());
- Code = serialization::STMT_BREAK;
-}
-
-void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
- VisitStmt(S);
-
- bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
- Record.push_back(HasNRVOCandidate);
-
- Record.AddStmt(S->getRetValue());
- if (HasNRVOCandidate)
- Record.AddDeclRef(S->getNRVOCandidate());
-
- Record.AddSourceLocation(S->getReturnLoc());
- Code = serialization::STMT_RETURN;
-}
-
-void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getBeginLoc());
- Record.AddSourceLocation(S->getEndLoc());
- DeclGroupRef DG = S->getDeclGroup();
- for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
- Record.AddDeclRef(*D);
- Code = serialization::STMT_DECL;
-}
-
-void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
- VisitStmt(S);
- Record.push_back(S->getNumOutputs());
- Record.push_back(S->getNumInputs());
- Record.push_back(S->getNumClobbers());
- Record.AddSourceLocation(S->getAsmLoc());
- Record.push_back(S->isVolatile());
- Record.push_back(S->isSimple());
-}
-
-void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
- VisitAsmStmt(S);
- Record.AddSourceLocation(S->getRParenLoc());
- Record.AddStmt(S->getAsmString());
-
- // Outputs
- for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
- Record.AddIdentifierRef(S->getOutputIdentifier(I));
- Record.AddStmt(S->getOutputConstraintLiteral(I));
- Record.AddStmt(S->getOutputExpr(I));
- }
-
- // Inputs
- for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
- Record.AddIdentifierRef(S->getInputIdentifier(I));
- Record.AddStmt(S->getInputConstraintLiteral(I));
- Record.AddStmt(S->getInputExpr(I));
- }
-
- // Clobbers
- for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
- Record.AddStmt(S->getClobberStringLiteral(I));
-
- Code = serialization::STMT_GCCASM;
-}
-
-void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
- VisitAsmStmt(S);
- Record.AddSourceLocation(S->getLBraceLoc());
- Record.AddSourceLocation(S->getEndLoc());
- Record.push_back(S->getNumAsmToks());
- Record.AddString(S->getAsmString());
-
- // Tokens
- for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
- // FIXME: Move this to ASTRecordWriter?
- Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
- }
-
- // Clobbers
- for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
- Record.AddString(S->getClobber(I));
- }
-
- // Outputs
- for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
- Record.AddStmt(S->getOutputExpr(I));
- Record.AddString(S->getOutputConstraint(I));
- }
-
- // Inputs
- for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
- Record.AddStmt(S->getInputExpr(I));
- Record.AddString(S->getInputConstraint(I));
- }
-
- Code = serialization::STMT_MSASM;
-}
-
-void ASTStmtWriter::VisitCoroutineBodyStmt(CoroutineBodyStmt *CoroStmt) {
- VisitStmt(CoroStmt);
- Record.push_back(CoroStmt->getParamMoves().size());
- for (Stmt *S : CoroStmt->children())
- Record.AddStmt(S);
- Code = serialization::STMT_COROUTINE_BODY;
-}
-
-void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getKeywordLoc());
- Record.AddStmt(S->getOperand());
- Record.AddStmt(S->getPromiseCall());
- Record.push_back(S->isImplicit());
- Code = serialization::STMT_CORETURN;
-}
-
-void ASTStmtWriter::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getKeywordLoc());
- for (Stmt *S : E->children())
- Record.AddStmt(S);
- Record.AddStmt(E->getOpaqueValue());
-}
-
-void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
- VisitCoroutineSuspendExpr(E);
- Record.push_back(E->isImplicit());
- Code = serialization::EXPR_COAWAIT;
-}
-
-void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
- VisitCoroutineSuspendExpr(E);
- Code = serialization::EXPR_COYIELD;
-}
-
-void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getKeywordLoc());
- for (Stmt *S : E->children())
- Record.AddStmt(S);
- Code = serialization::EXPR_DEPENDENT_COAWAIT;
-}
-
-void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
- VisitStmt(S);
- // NumCaptures
- Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
-
- // CapturedDecl and captured region kind
- Record.AddDeclRef(S->getCapturedDecl());
- Record.push_back(S->getCapturedRegionKind());
-
- Record.AddDeclRef(S->getCapturedRecordDecl());
-
- // Capture inits
- for (auto *I : S->capture_inits())
- Record.AddStmt(I);
-
- // Body
- Record.AddStmt(S->getCapturedStmt());
-
- // Captures
- for (const auto &I : S->captures()) {
- if (I.capturesThis() || I.capturesVariableArrayType())
- Record.AddDeclRef(nullptr);
- else
- Record.AddDeclRef(I.getCapturedVar());
- Record.push_back(I.getCaptureKind());
- Record.AddSourceLocation(I.getLocation());
- }
-
- Code = serialization::STMT_CAPTURED;
-}
-
-void ASTStmtWriter::VisitExpr(Expr *E) {
- VisitStmt(E);
- Record.AddTypeRef(E->getType());
- Record.push_back(E->isTypeDependent());
- Record.push_back(E->isValueDependent());
- Record.push_back(E->isInstantiationDependent());
- Record.push_back(E->containsUnexpandedParameterPack());
- Record.push_back(E->getValueKind());
- Record.push_back(E->getObjectKind());
-}
-
-void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Code = serialization::EXPR_CONSTANT;
-}
-
-void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
- VisitExpr(E);
-
- bool HasFunctionName = E->getFunctionName() != nullptr;
- Record.push_back(HasFunctionName);
- Record.push_back(E->getIdentKind()); // FIXME: stable encoding
- Record.AddSourceLocation(E->getLocation());
- if (HasFunctionName)
- Record.AddStmt(E->getFunctionName());
- Code = serialization::EXPR_PREDEFINED;
-}
-
-void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
- VisitExpr(E);
-
- Record.push_back(E->hasQualifier());
- Record.push_back(E->getDecl() != E->getFoundDecl());
- Record.push_back(E->hasTemplateKWAndArgsInfo());
- Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->refersToEnclosingVariableOrCapture());
-
- if (E->hasTemplateKWAndArgsInfo()) {
- unsigned NumTemplateArgs = E->getNumTemplateArgs();
- Record.push_back(NumTemplateArgs);
- }
-
- DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
-
- if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
- (E->getDecl() == E->getFoundDecl()) &&
- nk == DeclarationName::Identifier) {
- AbbrevToUse = Writer.getDeclRefExprAbbrev();
- }
-
- if (E->hasQualifier())
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
-
- if (E->getDecl() != E->getFoundDecl())
- Record.AddDeclRef(E->getFoundDecl());
-
- if (E->hasTemplateKWAndArgsInfo())
- AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
- E->getTrailingObjects<TemplateArgumentLoc>());
-
- Record.AddDeclRef(E->getDecl());
- Record.AddSourceLocation(E->getLocation());
- Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
- Code = serialization::EXPR_DECL_REF;
-}
-
-void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getLocation());
- Record.AddAPInt(E->getValue());
-
- if (E->getValue().getBitWidth() == 32) {
- AbbrevToUse = Writer.getIntegerLiteralAbbrev();
- }
-
- Code = serialization::EXPR_INTEGER_LITERAL;
-}
-
-void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getLocation());
- Record.AddAPInt(E->getValue());
- Code = serialization::EXPR_INTEGER_LITERAL;
-}
-
-void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
- VisitExpr(E);
- Record.push_back(E->getRawSemantics());
- Record.push_back(E->isExact());
- Record.AddAPFloat(E->getValue());
- Record.AddSourceLocation(E->getLocation());
- Code = serialization::EXPR_FLOATING_LITERAL;
-}
-
-void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Code = serialization::EXPR_IMAGINARY_LITERAL;
-}
-
-void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
- VisitExpr(E);
-
- // Store the various bits of data of StringLiteral.
- Record.push_back(E->getNumConcatenated());
- Record.push_back(E->getLength());
- Record.push_back(E->getCharByteWidth());
- Record.push_back(E->getKind());
- Record.push_back(E->isPascal());
-
- // Store the trailing array of SourceLocation.
- for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
- Record.AddSourceLocation(E->getStrTokenLoc(I));
-
- // Store the trailing array of char holding the string data.
- StringRef StrData = E->getBytes();
- for (unsigned I = 0, N = E->getByteLength(); I != N; ++I)
- Record.push_back(StrData[I]);
-
- Code = serialization::EXPR_STRING_LITERAL;
-}
-
-void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
- VisitExpr(E);
- Record.push_back(E->getValue());
- Record.AddSourceLocation(E->getLocation());
- Record.push_back(E->getKind());
-
- AbbrevToUse = Writer.getCharacterLiteralAbbrev();
-
- Code = serialization::EXPR_CHARACTER_LITERAL;
-}
-
-void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getLParen());
- Record.AddSourceLocation(E->getRParen());
- Record.AddStmt(E->getSubExpr());
- Code = serialization::EXPR_PAREN;
-}
-
-void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumExprs());
- for (auto *SubStmt : E->exprs())
- Record.AddStmt(SubStmt);
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_PAREN_LIST;
-}
-
-void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.push_back(E->canOverflow());
- Code = serialization::EXPR_UNARY_OPERATOR;
-}
-
-void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumComponents());
- Record.push_back(E->getNumExpressions());
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Record.AddTypeSourceInfo(E->getTypeSourceInfo());
- for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
- const OffsetOfNode &ON = E->getComponent(I);
- Record.push_back(ON.getKind()); // FIXME: Stable encoding
- Record.AddSourceLocation(ON.getSourceRange().getBegin());
- Record.AddSourceLocation(ON.getSourceRange().getEnd());
- switch (ON.getKind()) {
- case OffsetOfNode::Array:
- Record.push_back(ON.getArrayExprIndex());
- break;
-
- case OffsetOfNode::Field:
- Record.AddDeclRef(ON.getField());
- break;
-
- case OffsetOfNode::Identifier:
- Record.AddIdentifierRef(ON.getFieldName());
- break;
-
- case OffsetOfNode::Base:
- Record.AddCXXBaseSpecifier(*ON.getBase());
- break;
- }
- }
- for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
- Record.AddStmt(E->getIndexExpr(I));
- Code = serialization::EXPR_OFFSETOF;
-}
-
-void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getKind());
- if (E->isArgumentType())
- Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
- else {
- Record.push_back(0);
- Record.AddStmt(E->getArgumentExpr());
- }
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_SIZEOF_ALIGN_OF;
-}
-
-void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getLHS());
- Record.AddStmt(E->getRHS());
- Record.AddSourceLocation(E->getRBracketLoc());
- Code = serialization::EXPR_ARRAY_SUBSCRIPT;
-}
-
-void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getBase());
- Record.AddStmt(E->getLowerBound());
- Record.AddStmt(E->getLength());
- Record.AddSourceLocation(E->getColonLoc());
- Record.AddSourceLocation(E->getRBracketLoc());
- Code = serialization::EXPR_OMP_ARRAY_SECTION;
-}
-
-void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumArgs());
- Record.AddSourceLocation(E->getRParenLoc());
- Record.AddStmt(E->getCallee());
- for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
- Arg != ArgEnd; ++Arg)
- Record.AddStmt(*Arg);
- Record.push_back(static_cast<unsigned>(E->getADLCallKind()));
- Code = serialization::EXPR_CALL;
-}
-
-void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
- // Don't call VisitExpr, we'll write everything here.
-
- Record.push_back(E->hasQualifier());
- if (E->hasQualifier())
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
-
- Record.push_back(E->hasTemplateKWAndArgsInfo());
- if (E->hasTemplateKWAndArgsInfo()) {
- Record.AddSourceLocation(E->getTemplateKeywordLoc());
- unsigned NumTemplateArgs = E->getNumTemplateArgs();
- Record.push_back(NumTemplateArgs);
- Record.AddSourceLocation(E->getLAngleLoc());
- Record.AddSourceLocation(E->getRAngleLoc());
- for (unsigned i=0; i != NumTemplateArgs; ++i)
- Record.AddTemplateArgumentLoc(E->getTemplateArgs()[i]);
- }
-
- Record.push_back(E->hadMultipleCandidates());
-
- DeclAccessPair FoundDecl = E->getFoundDecl();
- Record.AddDeclRef(FoundDecl.getDecl());
- Record.push_back(FoundDecl.getAccess());
-
- Record.AddTypeRef(E->getType());
- Record.push_back(E->getValueKind());
- Record.push_back(E->getObjectKind());
- Record.AddStmt(E->getBase());
- Record.AddDeclRef(E->getMemberDecl());
- Record.AddSourceLocation(E->getMemberLoc());
- Record.push_back(E->isArrow());
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.AddDeclarationNameLoc(E->MemberDNLoc,
- E->getMemberDecl()->getDeclName());
- Code = serialization::EXPR_MEMBER;
-}
-
-void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getBase());
- Record.AddSourceLocation(E->getIsaMemberLoc());
- Record.AddSourceLocation(E->getOpLoc());
- Record.push_back(E->isArrow());
- Code = serialization::EXPR_OBJC_ISA;
-}
-
-void ASTStmtWriter::
-VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Record.push_back(E->shouldCopy());
- Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
-}
-
-void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
- VisitExplicitCastExpr(E);
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddSourceLocation(E->getBridgeKeywordLoc());
- Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
- Code = serialization::EXPR_OBJC_BRIDGED_CAST;
-}
-
-void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
- VisitExpr(E);
- Record.push_back(E->path_size());
- Record.AddStmt(E->getSubExpr());
- Record.push_back(E->getCastKind()); // FIXME: stable encoding
-
- for (CastExpr::path_iterator
- PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
- Record.AddCXXBaseSpecifier(**PI);
-}
-
-void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
- VisitExpr(E);
- Record.AddStmt(E->getLHS());
- Record.AddStmt(E->getRHS());
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.push_back(E->getFPFeatures().getInt());
- Code = serialization::EXPR_BINARY_OPERATOR;
-}
-
-void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- VisitBinaryOperator(E);
- Record.AddTypeRef(E->getComputationLHSType());
- Record.AddTypeRef(E->getComputationResultType());
- Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
-}
-
-void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
- VisitExpr(E);
- Record.AddStmt(E->getCond());
- Record.AddStmt(E->getLHS());
- Record.AddStmt(E->getRHS());
- Record.AddSourceLocation(E->getQuestionLoc());
- Record.AddSourceLocation(E->getColonLoc());
- Code = serialization::EXPR_CONDITIONAL_OPERATOR;
-}
-
-void
-ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
- VisitExpr(E);
- Record.AddStmt(E->getOpaqueValue());
- Record.AddStmt(E->getCommon());
- Record.AddStmt(E->getCond());
- Record.AddStmt(E->getTrueExpr());
- Record.AddStmt(E->getFalseExpr());
- Record.AddSourceLocation(E->getQuestionLoc());
- Record.AddSourceLocation(E->getColonLoc());
- Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
-}
-
-void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
- VisitCastExpr(E);
- Record.push_back(E->isPartOfExplicitCast());
-
- if (E->path_size() == 0)
- AbbrevToUse = Writer.getExprImplicitCastAbbrev();
-
- Code = serialization::EXPR_IMPLICIT_CAST;
-}
-
-void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
- VisitCastExpr(E);
- Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
-}
-
-void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
- VisitExplicitCastExpr(E);
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_CSTYLE_CAST;
-}
-
-void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddTypeSourceInfo(E->getTypeSourceInfo());
- Record.AddStmt(E->getInitializer());
- Record.push_back(E->isFileScope());
- Code = serialization::EXPR_COMPOUND_LITERAL;
-}
-
-void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getBase());
- Record.AddIdentifierRef(&E->getAccessor());
- Record.AddSourceLocation(E->getAccessorLoc());
- Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
-}
-
-void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
- VisitExpr(E);
- // NOTE: only add the (possibly null) syntactic form.
- // No need to serialize the isSemanticForm flag and the semantic form.
- Record.AddStmt(E->getSyntacticForm());
- Record.AddSourceLocation(E->getLBraceLoc());
- Record.AddSourceLocation(E->getRBraceLoc());
- bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
- Record.push_back(isArrayFiller);
- if (isArrayFiller)
- Record.AddStmt(E->getArrayFiller());
- else
- Record.AddDeclRef(E->getInitializedFieldInUnion());
- Record.push_back(E->hadArrayRangeDesignator());
- Record.push_back(E->getNumInits());
- if (isArrayFiller) {
- // ArrayFiller may have filled "holes" due to designated initializer.
- // Replace them by 0 to indicate that the filler goes in that place.
- Expr *filler = E->getArrayFiller();
- for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
- Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
- } else {
- for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
- Record.AddStmt(E->getInit(I));
- }
- Code = serialization::EXPR_INIT_LIST;
-}
-
-void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumSubExprs());
- for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
- Record.AddStmt(E->getSubExpr(I));
- Record.AddSourceLocation(E->getEqualOrColonLoc());
- Record.push_back(E->usesGNUSyntax());
- for (const DesignatedInitExpr::Designator &D : E->designators()) {
- if (D.isFieldDesignator()) {
- if (FieldDecl *Field = D.getField()) {
- Record.push_back(serialization::DESIG_FIELD_DECL);
- Record.AddDeclRef(Field);
- } else {
- Record.push_back(serialization::DESIG_FIELD_NAME);
- Record.AddIdentifierRef(D.getFieldName());
- }
- Record.AddSourceLocation(D.getDotLoc());
- Record.AddSourceLocation(D.getFieldLoc());
- } else if (D.isArrayDesignator()) {
- Record.push_back(serialization::DESIG_ARRAY);
- Record.push_back(D.getFirstExprIndex());
- Record.AddSourceLocation(D.getLBracketLoc());
- Record.AddSourceLocation(D.getRBracketLoc());
- } else {
- assert(D.isArrayRangeDesignator() && "Unknown designator");
- Record.push_back(serialization::DESIG_ARRAY_RANGE);
- Record.push_back(D.getFirstExprIndex());
- Record.AddSourceLocation(D.getLBracketLoc());
- Record.AddSourceLocation(D.getEllipsisLoc());
- Record.AddSourceLocation(D.getRBracketLoc());
- }
- }
- Code = serialization::EXPR_DESIGNATED_INIT;
-}
-
-void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getBase());
- Record.AddStmt(E->getUpdater());
- Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
-}
-
-void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
- VisitExpr(E);
- Code = serialization::EXPR_NO_INIT;
-}
-
-void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->SubExprs[0]);
- Record.AddStmt(E->SubExprs[1]);
- Code = serialization::EXPR_ARRAY_INIT_LOOP;
-}
-
-void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
- VisitExpr(E);
- Code = serialization::EXPR_ARRAY_INIT_INDEX;
-}
-
-void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
- VisitExpr(E);
- Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
-}
-
-void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
- Record.AddSourceLocation(E->getBuiltinLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Record.push_back(E->isMicrosoftABI());
- Code = serialization::EXPR_VA_ARG;
-}
-
-void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getAmpAmpLoc());
- Record.AddSourceLocation(E->getLabelLoc());
- Record.AddDeclRef(E->getLabel());
- Code = serialization::EXPR_ADDR_LABEL;
-}
-
-void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubStmt());
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_STMT;
-}
-
-void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getCond());
- Record.AddStmt(E->getLHS());
- Record.AddStmt(E->getRHS());
- Record.AddSourceLocation(E->getBuiltinLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
- Code = serialization::EXPR_CHOOSE;
-}
-
-void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getTokenLocation());
- Code = serialization::EXPR_GNU_NULL;
-}
-
-void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumSubExprs());
- for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
- Record.AddStmt(E->getExpr(I));
- Record.AddSourceLocation(E->getBuiltinLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_SHUFFLE_VECTOR;
-}
-
-void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getBuiltinLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Record.AddTypeSourceInfo(E->getTypeSourceInfo());
- Record.AddStmt(E->getSrcExpr());
- Code = serialization::EXPR_CONVERT_VECTOR;
-}
-
-void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getBlockDecl());
- Code = serialization::EXPR_BLOCK;
-}
-
-void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumAssocs());
-
- Record.AddStmt(E->getControllingExpr());
- for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
- Record.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I));
- Record.AddStmt(E->getAssocExpr(I));
- }
- Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
-
- Record.AddSourceLocation(E->getGenericLoc());
- Record.AddSourceLocation(E->getDefaultLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_GENERIC_SELECTION;
-}
-
-void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumSemanticExprs());
-
- // Push the result index. Currently, this needs to exactly match
- // the encoding used internally for ResultIndex.
- unsigned result = E->getResultExprIndex();
- result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
- Record.push_back(result);
-
- Record.AddStmt(E->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator
- i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
- Record.AddStmt(*i);
- }
- Code = serialization::EXPR_PSEUDO_OBJECT;
-}
-
-void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getOp());
- for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
- Record.AddStmt(E->getSubExprs()[I]);
- Record.AddSourceLocation(E->getBuiltinLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_ATOMIC;
-}
-
-//===----------------------------------------------------------------------===//
-// Objective-C Expressions and Statements.
-//===----------------------------------------------------------------------===//
-
-void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
- VisitExpr(E);
- Record.AddStmt(E->getString());
- Record.AddSourceLocation(E->getAtLoc());
- Code = serialization::EXPR_OBJC_STRING_LITERAL;
-}
-
-void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Record.AddDeclRef(E->getBoxingMethod());
- Record.AddSourceRange(E->getSourceRange());
- Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
-}
-
-void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
- VisitExpr(E);
- Record.push_back(E->getNumElements());
- for (unsigned i = 0; i < E->getNumElements(); i++)
- Record.AddStmt(E->getElement(i));
- Record.AddDeclRef(E->getArrayWithObjectsMethod());
- Record.AddSourceRange(E->getSourceRange());
- Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
-}
-
-void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
- VisitExpr(E);
- Record.push_back(E->getNumElements());
- Record.push_back(E->HasPackExpansions);
- for (unsigned i = 0; i < E->getNumElements(); i++) {
- ObjCDictionaryElement Element = E->getKeyValueElement(i);
- Record.AddStmt(Element.Key);
- Record.AddStmt(Element.Value);
- if (E->HasPackExpansions) {
- Record.AddSourceLocation(Element.EllipsisLoc);
- unsigned NumExpansions = 0;
- if (Element.NumExpansions)
- NumExpansions = *Element.NumExpansions + 1;
- Record.push_back(NumExpansions);
- }
- }
-
- Record.AddDeclRef(E->getDictWithObjectsMethod());
- Record.AddSourceRange(E->getSourceRange());
- Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
-}
-
-void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
- VisitExpr(E);
- Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
- Record.AddSourceLocation(E->getAtLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_OBJC_ENCODE;
-}
-
-void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
- VisitExpr(E);
- Record.AddSelectorRef(E->getSelector());
- Record.AddSourceLocation(E->getAtLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
-}
-
-void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getProtocol());
- Record.AddSourceLocation(E->getAtLoc());
- Record.AddSourceLocation(E->ProtoLoc);
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
-}
-
-void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getDecl());
- Record.AddSourceLocation(E->getLocation());
- Record.AddSourceLocation(E->getOpLoc());
- Record.AddStmt(E->getBase());
- Record.push_back(E->isArrow());
- Record.push_back(E->isFreeIvar());
- Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
-}
-
-void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
- VisitExpr(E);
- Record.push_back(E->SetterAndMethodRefFlags.getInt());
- Record.push_back(E->isImplicitProperty());
- if (E->isImplicitProperty()) {
- Record.AddDeclRef(E->getImplicitPropertyGetter());
- Record.AddDeclRef(E->getImplicitPropertySetter());
- } else {
- Record.AddDeclRef(E->getExplicitProperty());
- }
- Record.AddSourceLocation(E->getLocation());
- Record.AddSourceLocation(E->getReceiverLocation());
- if (E->isObjectReceiver()) {
- Record.push_back(0);
- Record.AddStmt(E->getBase());
- } else if (E->isSuperReceiver()) {
- Record.push_back(1);
- Record.AddTypeRef(E->getSuperReceiverType());
- } else {
- Record.push_back(2);
- Record.AddDeclRef(E->getClassReceiver());
- }
-
- Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
-}
-
-void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getRBracket());
- Record.AddStmt(E->getBaseExpr());
- Record.AddStmt(E->getKeyExpr());
- Record.AddDeclRef(E->getAtIndexMethodDecl());
- Record.AddDeclRef(E->setAtIndexMethodDecl());
-
- Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
-}
-
-void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumArgs());
- Record.push_back(E->getNumStoredSelLocs());
- Record.push_back(E->SelLocsKind);
- Record.push_back(E->isDelegateInitCall());
- Record.push_back(E->IsImplicit);
- Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
- switch (E->getReceiverKind()) {
- case ObjCMessageExpr::Instance:
- Record.AddStmt(E->getInstanceReceiver());
- break;
-
- case ObjCMessageExpr::Class:
- Record.AddTypeSourceInfo(E->getClassReceiverTypeInfo());
- break;
-
- case ObjCMessageExpr::SuperClass:
- case ObjCMessageExpr::SuperInstance:
- Record.AddTypeRef(E->getSuperType());
- Record.AddSourceLocation(E->getSuperLoc());
- break;
- }
-
- if (E->getMethodDecl()) {
- Record.push_back(1);
- Record.AddDeclRef(E->getMethodDecl());
- } else {
- Record.push_back(0);
- Record.AddSelectorRef(E->getSelector());
- }
-
- Record.AddSourceLocation(E->getLeftLoc());
- Record.AddSourceLocation(E->getRightLoc());
-
- for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
- Arg != ArgEnd; ++Arg)
- Record.AddStmt(*Arg);
-
- SourceLocation *Locs = E->getStoredSelLocs();
- for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
- Record.AddSourceLocation(Locs[i]);
-
- Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
-}
-
-void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
- VisitStmt(S);
- Record.AddStmt(S->getElement());
- Record.AddStmt(S->getCollection());
- Record.AddStmt(S->getBody());
- Record.AddSourceLocation(S->getForLoc());
- Record.AddSourceLocation(S->getRParenLoc());
- Code = serialization::STMT_OBJC_FOR_COLLECTION;
-}
-
-void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
- Record.AddStmt(S->getCatchBody());
- Record.AddDeclRef(S->getCatchParamDecl());
- Record.AddSourceLocation(S->getAtCatchLoc());
- Record.AddSourceLocation(S->getRParenLoc());
- Code = serialization::STMT_OBJC_CATCH;
-}
-
-void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
- Record.AddStmt(S->getFinallyBody());
- Record.AddSourceLocation(S->getAtFinallyLoc());
- Code = serialization::STMT_OBJC_FINALLY;
-}
-
-void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
- Record.AddStmt(S->getSubStmt());
- Record.AddSourceLocation(S->getAtLoc());
- Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
-}
-
-void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
- Record.push_back(S->getNumCatchStmts());
- Record.push_back(S->getFinallyStmt() != nullptr);
- Record.AddStmt(S->getTryBody());
- for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
- Record.AddStmt(S->getCatchStmt(I));
- if (S->getFinallyStmt())
- Record.AddStmt(S->getFinallyStmt());
- Record.AddSourceLocation(S->getAtTryLoc());
- Code = serialization::STMT_OBJC_AT_TRY;
-}
-
-void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
- Record.AddStmt(S->getSynchExpr());
- Record.AddStmt(S->getSynchBody());
- Record.AddSourceLocation(S->getAtSynchronizedLoc());
- Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
-}
-
-void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
- Record.AddStmt(S->getThrowExpr());
- Record.AddSourceLocation(S->getThrowLoc());
- Code = serialization::STMT_OBJC_AT_THROW;
-}
-
-void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getValue());
- Record.AddSourceLocation(E->getLocation());
- Code = serialization::EXPR_OBJC_BOOL_LITERAL;
-}
-
-void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
- VisitExpr(E);
- Record.AddSourceRange(E->getSourceRange());
- Record.AddVersionTuple(E->getVersion());
- Code = serialization::EXPR_OBJC_AVAILABILITY_CHECK;
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Expressions and Statements.
-//===----------------------------------------------------------------------===//
-
-void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getCatchLoc());
- Record.AddDeclRef(S->getExceptionDecl());
- Record.AddStmt(S->getHandlerBlock());
- Code = serialization::STMT_CXX_CATCH;
-}
-
-void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
- VisitStmt(S);
- Record.push_back(S->getNumHandlers());
- Record.AddSourceLocation(S->getTryLoc());
- Record.AddStmt(S->getTryBlock());
- for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
- Record.AddStmt(S->getHandler(i));
- Code = serialization::STMT_CXX_TRY;
-}
-
-void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getForLoc());
- Record.AddSourceLocation(S->getCoawaitLoc());
- Record.AddSourceLocation(S->getColonLoc());
- Record.AddSourceLocation(S->getRParenLoc());
- Record.AddStmt(S->getInit());
- Record.AddStmt(S->getRangeStmt());
- Record.AddStmt(S->getBeginStmt());
- Record.AddStmt(S->getEndStmt());
- Record.AddStmt(S->getCond());
- Record.AddStmt(S->getInc());
- Record.AddStmt(S->getLoopVarStmt());
- Record.AddStmt(S->getBody());
- Code = serialization::STMT_CXX_FOR_RANGE;
-}
-
-void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getKeywordLoc());
- Record.push_back(S->isIfExists());
- Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
- Record.AddDeclarationNameInfo(S->getNameInfo());
- Record.AddStmt(S->getSubStmt());
- Code = serialization::STMT_MS_DEPENDENT_EXISTS;
-}
-
-void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
- VisitCallExpr(E);
- Record.push_back(E->getOperator());
- Record.push_back(E->getFPFeatures().getInt());
- Record.AddSourceRange(E->Range);
- Code = serialization::EXPR_CXX_OPERATOR_CALL;
-}
-
-void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
- VisitCallExpr(E);
- Code = serialization::EXPR_CXX_MEMBER_CALL;
-}
-
-void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
- VisitExpr(E);
-
- Record.push_back(E->getNumArgs());
- Record.push_back(E->isElidable());
- Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->isListInitialization());
- Record.push_back(E->isStdInitListInitialization());
- Record.push_back(E->requiresZeroInitialization());
- Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
- Record.AddSourceLocation(E->getLocation());
- Record.AddDeclRef(E->getConstructor());
- Record.AddSourceRange(E->getParenOrBraceRange());
-
- for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
- Record.AddStmt(E->getArg(I));
-
- Code = serialization::EXPR_CXX_CONSTRUCT;
-}
-
-void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getConstructor());
- Record.AddSourceLocation(E->getLocation());
- Record.push_back(E->constructsVBase());
- Record.push_back(E->inheritedFromVBase());
- Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
-}
-
-void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
- VisitCXXConstructExpr(E);
- Record.AddTypeSourceInfo(E->getTypeSourceInfo());
- Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
-}
-
-void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
- VisitExpr(E);
- Record.push_back(E->NumCaptures);
- Record.AddSourceRange(E->IntroducerRange);
- Record.push_back(E->CaptureDefault); // FIXME: stable encoding
- Record.AddSourceLocation(E->CaptureDefaultLoc);
- Record.push_back(E->ExplicitParams);
- Record.push_back(E->ExplicitResultType);
- Record.AddSourceLocation(E->ClosingBrace);
-
- // Add capture initializers.
- for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
- CEnd = E->capture_init_end();
- C != CEnd; ++C) {
- Record.AddStmt(*C);
- }
-
- Code = serialization::EXPR_LAMBDA;
-}
-
-void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSubExpr());
- Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
-}
-
-void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
- VisitExplicitCastExpr(E);
- Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
- Record.AddSourceRange(E->getAngleBrackets());
-}
-
-void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
- VisitCXXNamedCastExpr(E);
- Code = serialization::EXPR_CXX_STATIC_CAST;
-}
-
-void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
- VisitCXXNamedCastExpr(E);
- Code = serialization::EXPR_CXX_DYNAMIC_CAST;
-}
-
-void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
- VisitCXXNamedCastExpr(E);
- Code = serialization::EXPR_CXX_REINTERPRET_CAST;
-}
-
-void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
- VisitCXXNamedCastExpr(E);
- Code = serialization::EXPR_CXX_CONST_CAST;
-}
-
-void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
- VisitExplicitCastExpr(E);
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
-}
-
-void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
- VisitCallExpr(E);
- Record.AddSourceLocation(E->UDSuffixLoc);
- Code = serialization::EXPR_USER_DEFINED_LITERAL;
-}
-
-void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getValue());
- Record.AddSourceLocation(E->getLocation());
- Code = serialization::EXPR_CXX_BOOL_LITERAL;
-}
-
-void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getLocation());
- Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
-}
-
-void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
- VisitExpr(E);
- Record.AddSourceRange(E->getSourceRange());
- if (E->isTypeOperand()) {
- Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
- Code = serialization::EXPR_CXX_TYPEID_TYPE;
- } else {
- Record.AddStmt(E->getExprOperand());
- Code = serialization::EXPR_CXX_TYPEID_EXPR;
- }
-}
-
-void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getLocation());
- Record.push_back(E->isImplicit());
- Code = serialization::EXPR_CXX_THIS;
-}
-
-void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getThrowLoc());
- Record.AddStmt(E->getSubExpr());
- Record.push_back(E->isThrownVariableInScope());
- Code = serialization::EXPR_CXX_THROW;
-}
-
-void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getParam());
- Record.AddSourceLocation(E->getUsedLocation());
- Code = serialization::EXPR_CXX_DEFAULT_ARG;
-}
-
-void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getField());
- Record.AddSourceLocation(E->getExprLoc());
- Code = serialization::EXPR_CXX_DEFAULT_INIT;
-}
-
-void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- VisitExpr(E);
- Record.AddCXXTemporary(E->getTemporary());
- Record.AddStmt(E->getSubExpr());
- Code = serialization::EXPR_CXX_BIND_TEMPORARY;
-}
-
-void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
- VisitExpr(E);
- Record.AddTypeSourceInfo(E->getTypeSourceInfo());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
-}
-
-void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
- VisitExpr(E);
-
- Record.push_back(E->isArray());
- Record.push_back(E->hasInitializer());
- Record.push_back(E->getNumPlacementArgs());
- Record.push_back(E->isParenTypeId());
-
- Record.push_back(E->isGlobalNew());
- Record.push_back(E->passAlignment());
- Record.push_back(E->doesUsualArrayDeleteWantSize());
- Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
-
- Record.AddDeclRef(E->getOperatorNew());
- Record.AddDeclRef(E->getOperatorDelete());
- Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
- if (E->isParenTypeId())
- Record.AddSourceRange(E->getTypeIdParens());
- Record.AddSourceRange(E->getSourceRange());
- Record.AddSourceRange(E->getDirectInitRange());
-
- for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
- I != N; ++I)
- Record.AddStmt(*I);
-
- Code = serialization::EXPR_CXX_NEW;
-}
-
-void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
- VisitExpr(E);
- Record.push_back(E->isGlobalDelete());
- Record.push_back(E->isArrayForm());
- Record.push_back(E->isArrayFormAsWritten());
- Record.push_back(E->doesUsualArrayDeleteWantSize());
- Record.AddDeclRef(E->getOperatorDelete());
- Record.AddStmt(E->getArgument());
- Record.AddSourceLocation(E->getBeginLoc());
-
- Code = serialization::EXPR_CXX_DELETE;
-}
-
-void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
- VisitExpr(E);
-
- Record.AddStmt(E->getBase());
- Record.push_back(E->isArrow());
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
- Record.AddTypeSourceInfo(E->getScopeTypeInfo());
- Record.AddSourceLocation(E->getColonColonLoc());
- Record.AddSourceLocation(E->getTildeLoc());
-
- // PseudoDestructorTypeStorage.
- Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
- if (E->getDestroyedTypeIdentifier())
- Record.AddSourceLocation(E->getDestroyedTypeLoc());
- else
- Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());
-
- Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
-}
-
-void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
- VisitExpr(E);
- Record.push_back(E->getNumObjects());
- for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
- Record.AddDeclRef(E->getObject(i));
-
- Record.push_back(E->cleanupsHaveSideEffects());
- Record.AddStmt(E->getSubExpr());
- Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
-}
-
-void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
- CXXDependentScopeMemberExpr *E) {
- VisitExpr(E);
-
- // Don't emit anything here (or if you do you will have to update
- // the corresponding deserialization function).
-
- Record.push_back(E->hasTemplateKWAndArgsInfo());
- Record.push_back(E->getNumTemplateArgs());
- Record.push_back(E->hasFirstQualifierFoundInScope());
-
- if (E->hasTemplateKWAndArgsInfo()) {
- const ASTTemplateKWAndArgsInfo &ArgInfo =
- *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- AddTemplateKWAndArgsInfo(ArgInfo,
- E->getTrailingObjects<TemplateArgumentLoc>());
- }
-
- Record.push_back(E->isArrow());
- Record.AddSourceLocation(E->getOperatorLoc());
- Record.AddTypeRef(E->getBaseType());
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
- if (!E->isImplicitAccess())
- Record.AddStmt(E->getBase());
- else
- Record.AddStmt(nullptr);
-
- if (E->hasFirstQualifierFoundInScope())
- Record.AddDeclRef(E->getFirstQualifierFoundInScope());
-
- Record.AddDeclarationNameInfo(E->MemberNameInfo);
- Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
-}
-
-void
-ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
- VisitExpr(E);
-
- // Don't emit anything here, HasTemplateKWAndArgsInfo must be
- // emitted first.
-
- Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
- if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
- const ASTTemplateKWAndArgsInfo &ArgInfo =
- *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- Record.push_back(ArgInfo.NumTemplateArgs);
- AddTemplateKWAndArgsInfo(ArgInfo,
- E->getTrailingObjects<TemplateArgumentLoc>());
- }
-
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
- Record.AddDeclarationNameInfo(E->NameInfo);
- Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
-}
-
-void
-ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
- VisitExpr(E);
- Record.push_back(E->arg_size());
- for (CXXUnresolvedConstructExpr::arg_iterator
- ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
- Record.AddStmt(*ArgI);
- Record.AddTypeSourceInfo(E->getTypeSourceInfo());
- Record.AddSourceLocation(E->getLParenLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
-}
-
-void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
- VisitExpr(E);
-
- Record.push_back(E->getNumDecls());
- Record.push_back(E->hasTemplateKWAndArgsInfo());
- if (E->hasTemplateKWAndArgsInfo()) {
- const ASTTemplateKWAndArgsInfo &ArgInfo =
- *E->getTrailingASTTemplateKWAndArgsInfo();
- Record.push_back(ArgInfo.NumTemplateArgs);
- AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
- }
-
- for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
- OvE = E->decls_end();
- OvI != OvE; ++OvI) {
- Record.AddDeclRef(OvI.getDecl());
- Record.push_back(OvI.getAccess());
- }
-
- Record.AddDeclarationNameInfo(E->getNameInfo());
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
-}
-
-void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
- VisitOverloadExpr(E);
- Record.push_back(E->isArrow());
- Record.push_back(E->hasUnresolvedUsing());
- Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
- Record.AddTypeRef(E->getBaseType());
- Record.AddSourceLocation(E->getOperatorLoc());
- Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
-}
-
-void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
- VisitOverloadExpr(E);
- Record.push_back(E->requiresADL());
- Record.push_back(E->isOverloaded());
- Record.AddDeclRef(E->getNamingClass());
- Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
-}
-
-void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
- VisitExpr(E);
- Record.push_back(E->TypeTraitExprBits.NumArgs);
- Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
- Record.push_back(E->TypeTraitExprBits.Value);
- Record.AddSourceRange(E->getSourceRange());
- for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
- Record.AddTypeSourceInfo(E->getArg(I));
- Code = serialization::EXPR_TYPE_TRAIT;
-}
-
-void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getTrait());
- Record.push_back(E->getValue());
- Record.AddSourceRange(E->getSourceRange());
- Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
- Record.AddStmt(E->getDimensionExpression());
- Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
-}
-
-void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getTrait());
- Record.push_back(E->getValue());
- Record.AddSourceRange(E->getSourceRange());
- Record.AddStmt(E->getQueriedExpression());
- Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
-}
-
-void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getValue());
- Record.AddSourceRange(E->getSourceRange());
- Record.AddStmt(E->getOperand());
- Code = serialization::EXPR_CXX_NOEXCEPT;
-}
-
-void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getEllipsisLoc());
- Record.push_back(E->NumExpansions);
- Record.AddStmt(E->getPattern());
- Code = serialization::EXPR_PACK_EXPANSION;
-}
-
-void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
- VisitExpr(E);
- Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
- : 0);
- Record.AddSourceLocation(E->OperatorLoc);
- Record.AddSourceLocation(E->PackLoc);
- Record.AddSourceLocation(E->RParenLoc);
- Record.AddDeclRef(E->Pack);
- if (E->isPartiallySubstituted()) {
- for (const auto &TA : E->getPartialArguments())
- Record.AddTemplateArgument(TA);
- } else if (!E->isValueDependent()) {
- Record.push_back(E->getPackLength());
- }
- Code = serialization::EXPR_SIZEOF_PACK;
-}
-
-void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
- SubstNonTypeTemplateParmExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getParameter());
- Record.AddSourceLocation(E->getNameLoc());
- Record.AddStmt(E->getReplacement());
- Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
-}
-
-void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
- SubstNonTypeTemplateParmPackExpr *E) {
- VisitExpr(E);
- Record.AddDeclRef(E->getParameterPack());
- Record.AddTemplateArgument(E->getArgumentPack());
- Record.AddSourceLocation(E->getParameterPackLocation());
- Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
-}
-
-void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
- VisitExpr(E);
- Record.push_back(E->getNumExpansions());
- Record.AddDeclRef(E->getParameterPack());
- Record.AddSourceLocation(E->getParameterPackLocation());
- for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
- I != End; ++I)
- Record.AddDeclRef(*I);
- Code = serialization::EXPR_FUNCTION_PARM_PACK;
-}
-
-void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getTemporary());
- Record.AddDeclRef(E->getExtendingDecl());
- Record.push_back(E->getManglingNumber());
- Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
-}
-
-void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->LParenLoc);
- Record.AddSourceLocation(E->EllipsisLoc);
- Record.AddSourceLocation(E->RParenLoc);
- Record.AddStmt(E->SubExprs[0]);
- Record.AddStmt(E->SubExprs[1]);
- Record.push_back(E->Opcode);
- Code = serialization::EXPR_CXX_FOLD;
-}
-
-void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getSourceExpr());
- Record.AddSourceLocation(E->getLocation());
- Record.push_back(E->isUnique());
- Code = serialization::EXPR_OPAQUE_VALUE;
-}
-
-void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
- VisitExpr(E);
- // TODO: Figure out sane writer behavior for a TypoExpr, if necessary
- llvm_unreachable("Cannot write TypoExpr nodes");
-}
-
-//===----------------------------------------------------------------------===//
-// CUDA Expressions and Statements.
-//===----------------------------------------------------------------------===//
-
-void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
- VisitCallExpr(E);
- Record.AddStmt(E->getConfig());
- Code = serialization::EXPR_CUDA_KERNEL_CALL;
-}
-
-//===----------------------------------------------------------------------===//
-// OpenCL Expressions and Statements.
-//===----------------------------------------------------------------------===//
-void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
- VisitExpr(E);
- Record.AddSourceLocation(E->getBuiltinLoc());
- Record.AddSourceLocation(E->getRParenLoc());
- Record.AddStmt(E->getSrcExpr());
- Code = serialization::EXPR_ASTYPE;
-}
-
-//===----------------------------------------------------------------------===//
-// Microsoft Expressions and Statements.
-//===----------------------------------------------------------------------===//
-void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
- VisitExpr(E);
- Record.push_back(E->isArrow());
- Record.AddStmt(E->getBaseExpr());
- Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
- Record.AddSourceLocation(E->getMemberLoc());
- Record.AddDeclRef(E->getPropertyDecl());
- Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
-}
-
-void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
- VisitExpr(E);
- Record.AddStmt(E->getBase());
- Record.AddStmt(E->getIdx());
- Record.AddSourceLocation(E->getRBracketLoc());
- Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
-}
-
-void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
- VisitExpr(E);
- Record.AddSourceRange(E->getSourceRange());
- Record.AddString(E->getUuidStr());
- if (E->isTypeOperand()) {
- Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
- Code = serialization::EXPR_CXX_UUIDOF_TYPE;
- } else {
- Record.AddStmt(E->getExprOperand());
- Code = serialization::EXPR_CXX_UUIDOF_EXPR;
- }
-}
-
-void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getExceptLoc());
- Record.AddStmt(S->getFilterExpr());
- Record.AddStmt(S->getBlock());
- Code = serialization::STMT_SEH_EXCEPT;
-}
-
-void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getFinallyLoc());
- Record.AddStmt(S->getBlock());
- Code = serialization::STMT_SEH_FINALLY;
-}
-
-void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
- VisitStmt(S);
- Record.push_back(S->getIsCXXTry());
- Record.AddSourceLocation(S->getTryLoc());
- Record.AddStmt(S->getTryBlock());
- Record.AddStmt(S->getHandler());
- Code = serialization::STMT_SEH_TRY;
-}
-
-void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
- VisitStmt(S);
- Record.AddSourceLocation(S->getLeaveLoc());
- Code = serialization::STMT_SEH_LEAVE;
-}
-
-//===----------------------------------------------------------------------===//
-// OpenMP Directives.
-//===----------------------------------------------------------------------===//
-void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
- Record.AddSourceLocation(E->getBeginLoc());
- Record.AddSourceLocation(E->getEndLoc());
- OMPClauseWriter ClauseWriter(Record);
- for (unsigned i = 0; i < E->getNumClauses(); ++i) {
- ClauseWriter.writeClause(E->getClause(i));
- }
- if (E->hasAssociatedStmt())
- Record.AddStmt(E->getAssociatedStmt());
-}
-
-void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- Record.push_back(D->getCollapsedNumber());
- VisitOMPExecutableDirective(D);
- Record.AddStmt(D->getIterationVariable());
- Record.AddStmt(D->getLastIteration());
- Record.AddStmt(D->getCalcLastIteration());
- Record.AddStmt(D->getPreCond());
- Record.AddStmt(D->getCond());
- Record.AddStmt(D->getInit());
- Record.AddStmt(D->getInc());
- Record.AddStmt(D->getPreInits());
- if (isOpenMPWorksharingDirective(D->getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(D->getDirectiveKind()) ||
- isOpenMPDistributeDirective(D->getDirectiveKind())) {
- Record.AddStmt(D->getIsLastIterVariable());
- Record.AddStmt(D->getLowerBoundVariable());
- Record.AddStmt(D->getUpperBoundVariable());
- Record.AddStmt(D->getStrideVariable());
- Record.AddStmt(D->getEnsureUpperBound());
- Record.AddStmt(D->getNextLowerBound());
- Record.AddStmt(D->getNextUpperBound());
- Record.AddStmt(D->getNumIterations());
- }
- if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) {
- Record.AddStmt(D->getPrevLowerBoundVariable());
- Record.AddStmt(D->getPrevUpperBoundVariable());
- Record.AddStmt(D->getDistInc());
- Record.AddStmt(D->getPrevEnsureUpperBound());
- Record.AddStmt(D->getCombinedLowerBoundVariable());
- Record.AddStmt(D->getCombinedUpperBoundVariable());
- Record.AddStmt(D->getCombinedEnsureUpperBound());
- Record.AddStmt(D->getCombinedInit());
- Record.AddStmt(D->getCombinedCond());
- Record.AddStmt(D->getCombinedNextLowerBound());
- Record.AddStmt(D->getCombinedNextUpperBound());
- Record.AddStmt(D->getCombinedDistCond());
- Record.AddStmt(D->getCombinedParForInDistCond());
- }
- for (auto I : D->counters()) {
- Record.AddStmt(I);
- }
- for (auto I : D->private_counters()) {
- Record.AddStmt(I);
- }
- for (auto I : D->inits()) {
- Record.AddStmt(I);
- }
- for (auto I : D->updates()) {
- Record.AddStmt(I);
- }
- for (auto I : D->finals()) {
- Record.AddStmt(I);
- }
-}
-
-void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
- VisitOMPLoopDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_FOR_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.AddDeclarationNameInfo(D->getDirectiveName());
- Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPParallelForSimdDirective(
- OMPParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPParallelSectionsDirective(
- OMPParallelSectionsDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_TASK_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.AddStmt(D->getX());
- Record.AddStmt(D->getV());
- Record.AddStmt(D->getExpr());
- Record.AddStmt(D->getUpdateExpr());
- Record.push_back(D->isXLHSInRHSPart() ? 1 : 0);
- Record.push_back(D->isPostfixUpdate() ? 1 : 0);
- Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
- OMPTargetEnterDataDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetExitDataDirective(
- OMPTargetExitDataDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetParallelDirective(
- OMPTargetParallelDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetParallelForDirective(
- OMPTargetParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.AddStmt(D->getReductionRef());
- Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPCancellationPointDirective(
- OMPCancellationPointDirective *D) {
- VisitStmt(D);
- VisitOMPExecutableDirective(D);
- Record.push_back(D->getCancelRegion());
- Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Record.push_back(D->getCancelRegion());
- Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
- OMPDistributeParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
- OMPDistributeParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPDistributeSimdDirective(
- OMPDistributeSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
- OMPTargetParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
- OMPTeamsDistributeDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
- OMPTeamsDistributeSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
- OMPTeamsDistributeParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
- OMPTeamsDistributeParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
- VisitStmt(D);
- Record.push_back(D->getNumClauses());
- VisitOMPExecutableDirective(D);
- Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
- OMPTargetTeamsDistributeDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
- OMPTargetTeamsDistributeParallelForDirective *D) {
- VisitOMPLoopDirective(D);
- Record.push_back(D->hasCancel() ? 1 : 0);
- Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
- OMPTargetTeamsDistributeParallelForSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::
- STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
-}
-
-void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
- OMPTargetTeamsDistributeSimdDirective *D) {
- VisitOMPLoopDirective(D);
- Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
-}
-
-//===----------------------------------------------------------------------===//
-// ASTWriter Implementation
-//===----------------------------------------------------------------------===//
-
-unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
- assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
- "SwitchCase recorded twice");
- unsigned NextID = SwitchCaseIDs.size();
- SwitchCaseIDs[S] = NextID;
- return NextID;
-}
-
-unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
- assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
- "SwitchCase hasn't been seen yet");
- return SwitchCaseIDs[S];
-}
-
-void ASTWriter::ClearSwitchCaseIDs() {
- SwitchCaseIDs.clear();
-}
-
-/// Write the given substatement or subexpression to the
-/// bitstream.
-void ASTWriter::WriteSubStmt(Stmt *S) {
- RecordData Record;
- ASTStmtWriter Writer(*this, Record);
- ++NumStatements;
-
- if (!S) {
- Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
- return;
- }
-
- llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
- if (I != SubStmtEntries.end()) {
- Record.push_back(I->second);
- Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
- return;
- }
-
-#ifndef NDEBUG
- assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
-
- struct ParentStmtInserterRAII {
- Stmt *S;
- llvm::DenseSet<Stmt *> &ParentStmts;
-
- ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
- : S(S), ParentStmts(ParentStmts) {
- ParentStmts.insert(S);
- }
- ~ParentStmtInserterRAII() {
- ParentStmts.erase(S);
- }
- };
-
- ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
-#endif
-
- Writer.Visit(S);
-
- uint64_t Offset = Writer.Emit();
- SubStmtEntries[S] = Offset;
-}
-
-/// Flush all of the statements that have been added to the
-/// queue via AddStmt().
-void ASTRecordWriter::FlushStmts() {
- // We expect to be the only consumer of the two temporary statement maps,
- // assert that they are empty.
- assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
- assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
-
- for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
- Writer->WriteSubStmt(StmtsToEmit[I]);
-
- assert(N == StmtsToEmit.size() && "record modified while being written!");
-
- // Note that we are at the end of a full expression. Any
- // expression records that follow this one are part of a different
- // expression.
- Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());
-
- Writer->SubStmtEntries.clear();
- Writer->ParentStmts.clear();
- }
-
- StmtsToEmit.clear();
-}
-
-void ASTRecordWriter::FlushSubStmts() {
- // For a nested statement, write out the substatements in reverse order (so
- // that a simple stack machine can be used when loading), and don't emit a
- // STMT_STOP after each one.
- for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
- Writer->WriteSubStmt(StmtsToEmit[N - I - 1]);
- assert(N == StmtsToEmit.size() && "record modified while being written!");
- }
-
- StmtsToEmit.clear();
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/CMakeLists.txt b/gnu/llvm/tools/clang/lib/Serialization/CMakeLists.txt
deleted file mode 100644
index a312cb91eb0..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- BitReader
- Support
- )
-
-
-add_clang_library(clangSerialization
- ASTCommon.cpp
- ASTReader.cpp
- ASTReaderDecl.cpp
- ASTReaderStmt.cpp
- ASTWriter.cpp
- ASTWriterDecl.cpp
- ASTWriterStmt.cpp
- GeneratePCH.cpp
- GlobalModuleIndex.cpp
- Module.cpp
- ModuleFileExtension.cpp
- ModuleManager.cpp
- PCHContainerOperations.cpp
-
- ADDITIONAL_HEADERS
- ASTCommon.h
- ASTReaderInternals.h
-
- LINK_LIBS
- clangAST
- clangBasic
- clangLex
- clangSema
- )
diff --git a/gnu/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp b/gnu/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp
deleted file mode 100644
index 2e0076521f9..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===--- GeneratePCH.cpp - Sema Consumer for PCH Generation -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the PCHGenerator, which as a SemaConsumer that generates
-// a PCH file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/ASTContext.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "clang/Serialization/ASTWriter.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-
-using namespace clang;
-
-PCHGenerator::PCHGenerator(
- const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
- std::shared_ptr<PCHBuffer> Buffer,
- ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool AllowASTWithErrors, bool IncludeTimestamps)
- : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
- SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
- Writer(Stream, this->Buffer->Data, PP.getPCMCache(), Extensions,
- IncludeTimestamps),
- AllowASTWithErrors(AllowASTWithErrors) {
- this->Buffer->IsComplete = false;
-}
-
-PCHGenerator::~PCHGenerator() {
-}
-
-void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
- // Don't create a PCH if there were fatal failures during module loading.
- if (PP.getModuleLoader().HadFatalFailure)
- return;
-
- bool hasErrors = PP.getDiagnostics().hasErrorOccurred();
- if (hasErrors && !AllowASTWithErrors)
- return;
-
- Module *Module = nullptr;
- if (PP.getLangOpts().isCompilingModule()) {
- Module = PP.getHeaderSearchInfo().lookupModule(
- PP.getLangOpts().CurrentModule, /*AllowSearch*/ false);
- if (!Module) {
- assert(hasErrors && "emitting module but current module doesn't exist");
- return;
- }
- }
-
- // Emit the PCH file to the Buffer.
- assert(SemaPtr && "No Sema?");
- Buffer->Signature =
- Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot,
- // For serialization we are lenient if the errors were
- // only warn-as-error kind.
- PP.getDiagnostics().hasUncompilableErrorOccurred());
-
- Buffer->IsComplete = true;
-}
-
-ASTMutationListener *PCHGenerator::GetASTMutationListener() {
- return &Writer;
-}
-
-ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
- return &Writer;
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp b/gnu/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp
deleted file mode 100644
index e7642a38924..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp
+++ /dev/null
@@ -1,943 +0,0 @@
-//===--- GlobalModuleIndex.cpp - Global Module Index ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the GlobalModuleIndex class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ASTReaderInternals.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Serialization/ASTBitCodes.h"
-#include "clang/Serialization/GlobalModuleIndex.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/PCHContainerOperations.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
-#include "llvm/Support/DJB.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/LockFileManager.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/OnDiskHashTable.h"
-#include "llvm/Support/Path.h"
-#include <cstdio>
-using namespace clang;
-using namespace serialization;
-
-//----------------------------------------------------------------------------//
-// Shared constants
-//----------------------------------------------------------------------------//
-namespace {
- enum {
- /// The block containing the index.
- GLOBAL_INDEX_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID
- };
-
- /// Describes the record types in the index.
- enum IndexRecordTypes {
- /// Contains version information and potentially other metadata,
- /// used to determine if we can read this global index file.
- INDEX_METADATA,
- /// Describes a module, including its file name and dependencies.
- MODULE,
- /// The index for identifiers.
- IDENTIFIER_INDEX
- };
-}
-
-/// The name of the global index file.
-static const char * const IndexFileName = "modules.idx";
-
-/// The global index file version.
-static const unsigned CurrentVersion = 1;
-
-//----------------------------------------------------------------------------//
-// Global module index reader.
-//----------------------------------------------------------------------------//
-
-namespace {
-
-/// Trait used to read the identifier index from the on-disk hash
-/// table.
-class IdentifierIndexReaderTrait {
-public:
- typedef StringRef external_key_type;
- typedef StringRef internal_key_type;
- typedef SmallVector<unsigned, 2> data_type;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
-
- static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
- return a == b;
- }
-
- static hash_value_type ComputeHash(const internal_key_type& a) {
- return llvm::djbHash(a);
- }
-
- static std::pair<unsigned, unsigned>
- ReadKeyDataLength(const unsigned char*& d) {
- using namespace llvm::support;
- unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
- unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
- return std::make_pair(KeyLen, DataLen);
- }
-
- static const internal_key_type&
- GetInternalKey(const external_key_type& x) { return x; }
-
- static const external_key_type&
- GetExternalKey(const internal_key_type& x) { return x; }
-
- static internal_key_type ReadKey(const unsigned char* d, unsigned n) {
- return StringRef((const char *)d, n);
- }
-
- static data_type ReadData(const internal_key_type& k,
- const unsigned char* d,
- unsigned DataLen) {
- using namespace llvm::support;
-
- data_type Result;
- while (DataLen > 0) {
- unsigned ID = endian::readNext<uint32_t, little, unaligned>(d);
- Result.push_back(ID);
- DataLen -= 4;
- }
-
- return Result;
- }
-};
-
-typedef llvm::OnDiskIterableChainedHashTable<IdentifierIndexReaderTrait>
- IdentifierIndexTable;
-
-}
-
-GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
- llvm::BitstreamCursor Cursor)
- : Buffer(std::move(Buffer)), IdentifierIndex(), NumIdentifierLookups(),
- NumIdentifierLookupHits() {
- // Read the global index.
- bool InGlobalIndexBlock = false;
- bool Done = false;
- while (!Done) {
- llvm::BitstreamEntry Entry = Cursor.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- return;
-
- case llvm::BitstreamEntry::EndBlock:
- if (InGlobalIndexBlock) {
- InGlobalIndexBlock = false;
- Done = true;
- continue;
- }
- return;
-
-
- case llvm::BitstreamEntry::Record:
- // Entries in the global index block are handled below.
- if (InGlobalIndexBlock)
- break;
-
- return;
-
- case llvm::BitstreamEntry::SubBlock:
- if (!InGlobalIndexBlock && Entry.ID == GLOBAL_INDEX_BLOCK_ID) {
- if (Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID))
- return;
-
- InGlobalIndexBlock = true;
- } else if (Cursor.SkipBlock()) {
- return;
- }
- continue;
- }
-
- SmallVector<uint64_t, 64> Record;
- StringRef Blob;
- switch ((IndexRecordTypes)Cursor.readRecord(Entry.ID, Record, &Blob)) {
- case INDEX_METADATA:
- // Make sure that the version matches.
- if (Record.size() < 1 || Record[0] != CurrentVersion)
- return;
- break;
-
- case MODULE: {
- unsigned Idx = 0;
- unsigned ID = Record[Idx++];
-
- // Make room for this module's information.
- if (ID == Modules.size())
- Modules.push_back(ModuleInfo());
- else
- Modules.resize(ID + 1);
-
- // Size/modification time for this module file at the time the
- // global index was built.
- Modules[ID].Size = Record[Idx++];
- Modules[ID].ModTime = Record[Idx++];
-
- // File name.
- unsigned NameLen = Record[Idx++];
- Modules[ID].FileName.assign(Record.begin() + Idx,
- Record.begin() + Idx + NameLen);
- Idx += NameLen;
-
- // Dependencies
- unsigned NumDeps = Record[Idx++];
- Modules[ID].Dependencies.insert(Modules[ID].Dependencies.end(),
- Record.begin() + Idx,
- Record.begin() + Idx + NumDeps);
- Idx += NumDeps;
-
- // Make sure we're at the end of the record.
- assert(Idx == Record.size() && "More module info?");
-
- // Record this module as an unresolved module.
- // FIXME: this doesn't work correctly for module names containing path
- // separators.
- StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName);
- // Remove the -<hash of ModuleMapPath>
- ModuleName = ModuleName.rsplit('-').first;
- UnresolvedModules[ModuleName] = ID;
- break;
- }
-
- case IDENTIFIER_INDEX:
- // Wire up the identifier index.
- if (Record[0]) {
- IdentifierIndex = IdentifierIndexTable::Create(
- (const unsigned char *)Blob.data() + Record[0],
- (const unsigned char *)Blob.data() + sizeof(uint32_t),
- (const unsigned char *)Blob.data(), IdentifierIndexReaderTrait());
- }
- break;
- }
- }
-}
-
-GlobalModuleIndex::~GlobalModuleIndex() {
- delete static_cast<IdentifierIndexTable *>(IdentifierIndex);
-}
-
-std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode>
-GlobalModuleIndex::readIndex(StringRef Path) {
- // Load the index file, if it's there.
- llvm::SmallString<128> IndexPath;
- IndexPath += Path;
- llvm::sys::path::append(IndexPath, IndexFileName);
-
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrErr =
- llvm::MemoryBuffer::getFile(IndexPath.c_str());
- if (!BufferOrErr)
- return std::make_pair(nullptr, EC_NotFound);
- std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrErr.get());
-
- /// The main bitstream cursor for the main block.
- llvm::BitstreamCursor Cursor(*Buffer);
-
- // Sniff for the signature.
- if (Cursor.Read(8) != 'B' ||
- Cursor.Read(8) != 'C' ||
- Cursor.Read(8) != 'G' ||
- Cursor.Read(8) != 'I') {
- return std::make_pair(nullptr, EC_IOError);
- }
-
- return std::make_pair(new GlobalModuleIndex(std::move(Buffer), Cursor),
- EC_None);
-}
-
-void
-GlobalModuleIndex::getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles) {
- ModuleFiles.clear();
- for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
- if (ModuleFile *MF = Modules[I].File)
- ModuleFiles.push_back(MF);
- }
-}
-
-void GlobalModuleIndex::getModuleDependencies(
- ModuleFile *File,
- SmallVectorImpl<ModuleFile *> &Dependencies) {
- // Look for information about this module file.
- llvm::DenseMap<ModuleFile *, unsigned>::iterator Known
- = ModulesByFile.find(File);
- if (Known == ModulesByFile.end())
- return;
-
- // Record dependencies.
- Dependencies.clear();
- ArrayRef<unsigned> StoredDependencies = Modules[Known->second].Dependencies;
- for (unsigned I = 0, N = StoredDependencies.size(); I != N; ++I) {
- if (ModuleFile *MF = Modules[I].File)
- Dependencies.push_back(MF);
- }
-}
-
-bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) {
- Hits.clear();
-
- // If there's no identifier index, there is nothing we can do.
- if (!IdentifierIndex)
- return false;
-
- // Look into the identifier index.
- ++NumIdentifierLookups;
- IdentifierIndexTable &Table
- = *static_cast<IdentifierIndexTable *>(IdentifierIndex);
- IdentifierIndexTable::iterator Known = Table.find(Name);
- if (Known == Table.end()) {
- return true;
- }
-
- SmallVector<unsigned, 2> ModuleIDs = *Known;
- for (unsigned I = 0, N = ModuleIDs.size(); I != N; ++I) {
- if (ModuleFile *MF = Modules[ModuleIDs[I]].File)
- Hits.insert(MF);
- }
-
- ++NumIdentifierLookupHits;
- return true;
-}
-
-bool GlobalModuleIndex::loadedModuleFile(ModuleFile *File) {
- // Look for the module in the global module index based on the module name.
- StringRef Name = File->ModuleName;
- llvm::StringMap<unsigned>::iterator Known = UnresolvedModules.find(Name);
- if (Known == UnresolvedModules.end()) {
- return true;
- }
-
- // Rectify this module with the global module index.
- ModuleInfo &Info = Modules[Known->second];
-
- // If the size and modification time match what we expected, record this
- // module file.
- bool Failed = true;
- if (File->File->getSize() == Info.Size &&
- File->File->getModificationTime() == Info.ModTime) {
- Info.File = File;
- ModulesByFile[File] = Known->second;
-
- Failed = false;
- }
-
- // One way or another, we have resolved this module file.
- UnresolvedModules.erase(Known);
- return Failed;
-}
-
-void GlobalModuleIndex::printStats() {
- std::fprintf(stderr, "*** Global Module Index Statistics:\n");
- if (NumIdentifierLookups) {
- fprintf(stderr, " %u / %u identifier lookups succeeded (%f%%)\n",
- NumIdentifierLookupHits, NumIdentifierLookups,
- (double)NumIdentifierLookupHits*100.0/NumIdentifierLookups);
- }
- std::fprintf(stderr, "\n");
-}
-
-LLVM_DUMP_METHOD void GlobalModuleIndex::dump() {
- llvm::errs() << "*** Global Module Index Dump:\n";
- llvm::errs() << "Module files:\n";
- for (auto &MI : Modules) {
- llvm::errs() << "** " << MI.FileName << "\n";
- if (MI.File)
- MI.File->dump();
- else
- llvm::errs() << "\n";
- }
- llvm::errs() << "\n";
-}
-
-//----------------------------------------------------------------------------//
-// Global module index writer.
-//----------------------------------------------------------------------------//
-
-namespace {
- /// Provides information about a specific module file.
- struct ModuleFileInfo {
- /// The numberic ID for this module file.
- unsigned ID;
-
- /// The set of modules on which this module depends. Each entry is
- /// a module ID.
- SmallVector<unsigned, 4> Dependencies;
- ASTFileSignature Signature;
- };
-
- struct ImportedModuleFileInfo {
- off_t StoredSize;
- time_t StoredModTime;
- ASTFileSignature StoredSignature;
- ImportedModuleFileInfo(off_t Size, time_t ModTime, ASTFileSignature Sig)
- : StoredSize(Size), StoredModTime(ModTime), StoredSignature(Sig) {}
- };
-
- /// Builder that generates the global module index file.
- class GlobalModuleIndexBuilder {
- FileManager &FileMgr;
- const PCHContainerReader &PCHContainerRdr;
-
- /// Mapping from files to module file information.
- typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
-
- /// Information about each of the known module files.
- ModuleFilesMap ModuleFiles;
-
- /// Mapping from the imported module file to the imported
- /// information.
- typedef std::multimap<const FileEntry *, ImportedModuleFileInfo>
- ImportedModuleFilesMap;
-
- /// Information about each importing of a module file.
- ImportedModuleFilesMap ImportedModuleFiles;
-
- /// Mapping from identifiers to the list of module file IDs that
- /// consider this identifier to be interesting.
- typedef llvm::StringMap<SmallVector<unsigned, 2> > InterestingIdentifierMap;
-
- /// A mapping from all interesting identifiers to the set of module
- /// files in which those identifiers are considered interesting.
- InterestingIdentifierMap InterestingIdentifiers;
-
- /// Write the block-info block for the global module index file.
- void emitBlockInfoBlock(llvm::BitstreamWriter &Stream);
-
- /// Retrieve the module file information for the given file.
- ModuleFileInfo &getModuleFileInfo(const FileEntry *File) {
- llvm::MapVector<const FileEntry *, ModuleFileInfo>::iterator Known
- = ModuleFiles.find(File);
- if (Known != ModuleFiles.end())
- return Known->second;
-
- unsigned NewID = ModuleFiles.size();
- ModuleFileInfo &Info = ModuleFiles[File];
- Info.ID = NewID;
- return Info;
- }
-
- public:
- explicit GlobalModuleIndexBuilder(
- FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr)
- : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr) {}
-
- /// Load the contents of the given module file into the builder.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool loadModuleFile(const FileEntry *File);
-
- /// Write the index to the given bitstream.
- /// \returns true if an error occurred, false otherwise.
- bool writeIndex(llvm::BitstreamWriter &Stream);
- };
-}
-
-static void emitBlockID(unsigned ID, const char *Name,
- llvm::BitstreamWriter &Stream,
- SmallVectorImpl<uint64_t> &Record) {
- Record.clear();
- Record.push_back(ID);
- Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
-
- // Emit the block name if present.
- if (!Name || Name[0] == 0) return;
- Record.clear();
- while (*Name)
- Record.push_back(*Name++);
- Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
-}
-
-static void emitRecordID(unsigned ID, const char *Name,
- llvm::BitstreamWriter &Stream,
- SmallVectorImpl<uint64_t> &Record) {
- Record.clear();
- Record.push_back(ID);
- while (*Name)
- Record.push_back(*Name++);
- Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
-}
-
-void
-GlobalModuleIndexBuilder::emitBlockInfoBlock(llvm::BitstreamWriter &Stream) {
- SmallVector<uint64_t, 64> Record;
- Stream.EnterBlockInfoBlock();
-
-#define BLOCK(X) emitBlockID(X ## _ID, #X, Stream, Record)
-#define RECORD(X) emitRecordID(X, #X, Stream, Record)
- BLOCK(GLOBAL_INDEX_BLOCK);
- RECORD(INDEX_METADATA);
- RECORD(MODULE);
- RECORD(IDENTIFIER_INDEX);
-#undef RECORD
-#undef BLOCK
-
- Stream.ExitBlock();
-}
-
-namespace {
- class InterestingASTIdentifierLookupTrait
- : public serialization::reader::ASTIdentifierLookupTraitBase {
-
- public:
- /// The identifier and whether it is "interesting".
- typedef std::pair<StringRef, bool> data_type;
-
- data_type ReadData(const internal_key_type& k,
- const unsigned char* d,
- unsigned DataLen) {
- // The first bit indicates whether this identifier is interesting.
- // That's all we care about.
- using namespace llvm::support;
- unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
- bool IsInteresting = RawID & 0x01;
- return std::make_pair(k, IsInteresting);
- }
- };
-}
-
-bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
- // Open the module file.
-
- auto Buffer = FileMgr.getBufferForFile(File, /*isVolatile=*/true);
- if (!Buffer) {
- return true;
- }
-
- // Initialize the input stream
- llvm::BitstreamCursor InStream(PCHContainerRdr.ExtractPCH(**Buffer));
-
- // Sniff for the signature.
- if (InStream.Read(8) != 'C' ||
- InStream.Read(8) != 'P' ||
- InStream.Read(8) != 'C' ||
- InStream.Read(8) != 'H') {
- return true;
- }
-
- // Record this module file and assign it a unique ID (if it doesn't have
- // one already).
- unsigned ID = getModuleFileInfo(File).ID;
-
- // Search for the blocks and records we care about.
- enum { Other, ControlBlock, ASTBlock, DiagnosticOptionsBlock } State = Other;
- bool Done = false;
- while (!Done) {
- llvm::BitstreamEntry Entry = InStream.advance();
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::Error:
- Done = true;
- continue;
-
- case llvm::BitstreamEntry::Record:
- // In the 'other' state, just skip the record. We don't care.
- if (State == Other) {
- InStream.skipRecord(Entry.ID);
- continue;
- }
-
- // Handle potentially-interesting records below.
- break;
-
- case llvm::BitstreamEntry::SubBlock:
- if (Entry.ID == CONTROL_BLOCK_ID) {
- if (InStream.EnterSubBlock(CONTROL_BLOCK_ID))
- return true;
-
- // Found the control block.
- State = ControlBlock;
- continue;
- }
-
- if (Entry.ID == AST_BLOCK_ID) {
- if (InStream.EnterSubBlock(AST_BLOCK_ID))
- return true;
-
- // Found the AST block.
- State = ASTBlock;
- continue;
- }
-
- if (Entry.ID == UNHASHED_CONTROL_BLOCK_ID) {
- if (InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID))
- return true;
-
- // Found the Diagnostic Options block.
- State = DiagnosticOptionsBlock;
- continue;
- }
-
- if (InStream.SkipBlock())
- return true;
-
- continue;
-
- case llvm::BitstreamEntry::EndBlock:
- State = Other;
- continue;
- }
-
- // Read the given record.
- SmallVector<uint64_t, 64> Record;
- StringRef Blob;
- unsigned Code = InStream.readRecord(Entry.ID, Record, &Blob);
-
- // Handle module dependencies.
- if (State == ControlBlock && Code == IMPORTS) {
- // Load each of the imported PCH files.
- unsigned Idx = 0, N = Record.size();
- while (Idx < N) {
- // Read information about the AST file.
-
- // Skip the imported kind
- ++Idx;
-
- // Skip the import location
- ++Idx;
-
- // Load stored size/modification time.
- off_t StoredSize = (off_t)Record[Idx++];
- time_t StoredModTime = (time_t)Record[Idx++];
-
- // Skip the stored signature.
- // FIXME: we could read the signature out of the import and validate it.
- ASTFileSignature StoredSignature = {
- {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
- (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
- (uint32_t)Record[Idx++]}}};
-
- // Skip the module name (currently this is only used for prebuilt
- // modules while here we are only dealing with cached).
- Idx += Record[Idx] + 1;
-
- // Retrieve the imported file name.
- unsigned Length = Record[Idx++];
- SmallString<128> ImportedFile(Record.begin() + Idx,
- Record.begin() + Idx + Length);
- Idx += Length;
-
- // Find the imported module file.
- const FileEntry *DependsOnFile
- = FileMgr.getFile(ImportedFile, /*openFile=*/false,
- /*cacheFailure=*/false);
-
- if (!DependsOnFile)
- return true;
-
- // Save the information in ImportedModuleFileInfo so we can verify after
- // loading all pcms.
- ImportedModuleFiles.insert(std::make_pair(
- DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime,
- StoredSignature)));
-
- // Record the dependency.
- unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID;
- getModuleFileInfo(File).Dependencies.push_back(DependsOnID);
- }
-
- continue;
- }
-
- // Handle the identifier table
- if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) {
- typedef llvm::OnDiskIterableChainedHashTable<
- InterestingASTIdentifierLookupTrait> InterestingIdentifierTable;
- std::unique_ptr<InterestingIdentifierTable> Table(
- InterestingIdentifierTable::Create(
- (const unsigned char *)Blob.data() + Record[0],
- (const unsigned char *)Blob.data() + sizeof(uint32_t),
- (const unsigned char *)Blob.data()));
- for (InterestingIdentifierTable::data_iterator D = Table->data_begin(),
- DEnd = Table->data_end();
- D != DEnd; ++D) {
- std::pair<StringRef, bool> Ident = *D;
- if (Ident.second)
- InterestingIdentifiers[Ident.first].push_back(ID);
- else
- (void)InterestingIdentifiers[Ident.first];
- }
- }
-
- // Get Signature.
- if (State == DiagnosticOptionsBlock && Code == SIGNATURE)
- getModuleFileInfo(File).Signature = {
- {{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
- (uint32_t)Record[3], (uint32_t)Record[4]}}};
-
- // We don't care about this record.
- }
-
- return false;
-}
-
-namespace {
-
-/// Trait used to generate the identifier index as an on-disk hash
-/// table.
-class IdentifierIndexWriterTrait {
-public:
- typedef StringRef key_type;
- typedef StringRef key_type_ref;
- typedef SmallVector<unsigned, 2> data_type;
- typedef const SmallVector<unsigned, 2> &data_type_ref;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
-
- static hash_value_type ComputeHash(key_type_ref Key) {
- return llvm::djbHash(Key);
- }
-
- std::pair<unsigned,unsigned>
- EmitKeyDataLength(raw_ostream& Out, key_type_ref Key, data_type_ref Data) {
- using namespace llvm::support;
- endian::Writer LE(Out, little);
- unsigned KeyLen = Key.size();
- unsigned DataLen = Data.size() * 4;
- LE.write<uint16_t>(KeyLen);
- LE.write<uint16_t>(DataLen);
- return std::make_pair(KeyLen, DataLen);
- }
-
- void EmitKey(raw_ostream& Out, key_type_ref Key, unsigned KeyLen) {
- Out.write(Key.data(), KeyLen);
- }
-
- void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data,
- unsigned DataLen) {
- using namespace llvm::support;
- for (unsigned I = 0, N = Data.size(); I != N; ++I)
- endian::write<uint32_t>(Out, Data[I], little);
- }
-};
-
-}
-
-bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
- for (auto MapEntry : ImportedModuleFiles) {
- auto *File = MapEntry.first;
- ImportedModuleFileInfo &Info = MapEntry.second;
- if (getModuleFileInfo(File).Signature) {
- if (getModuleFileInfo(File).Signature != Info.StoredSignature)
- // Verify Signature.
- return true;
- } else if (Info.StoredSize != File->getSize() ||
- Info.StoredModTime != File->getModificationTime())
- // Verify Size and ModTime.
- return true;
- }
-
- using namespace llvm;
-
- // Emit the file header.
- Stream.Emit((unsigned)'B', 8);
- Stream.Emit((unsigned)'C', 8);
- Stream.Emit((unsigned)'G', 8);
- Stream.Emit((unsigned)'I', 8);
-
- // Write the block-info block, which describes the records in this bitcode
- // file.
- emitBlockInfoBlock(Stream);
-
- Stream.EnterSubblock(GLOBAL_INDEX_BLOCK_ID, 3);
-
- // Write the metadata.
- SmallVector<uint64_t, 2> Record;
- Record.push_back(CurrentVersion);
- Stream.EmitRecord(INDEX_METADATA, Record);
-
- // Write the set of known module files.
- for (ModuleFilesMap::iterator M = ModuleFiles.begin(),
- MEnd = ModuleFiles.end();
- M != MEnd; ++M) {
- Record.clear();
- Record.push_back(M->second.ID);
- Record.push_back(M->first->getSize());
- Record.push_back(M->first->getModificationTime());
-
- // File name
- StringRef Name(M->first->getName());
- Record.push_back(Name.size());
- Record.append(Name.begin(), Name.end());
-
- // Dependencies
- Record.push_back(M->second.Dependencies.size());
- Record.append(M->second.Dependencies.begin(), M->second.Dependencies.end());
- Stream.EmitRecord(MODULE, Record);
- }
-
- // Write the identifier -> module file mapping.
- {
- llvm::OnDiskChainedHashTableGenerator<IdentifierIndexWriterTrait> Generator;
- IdentifierIndexWriterTrait Trait;
-
- // Populate the hash table.
- for (InterestingIdentifierMap::iterator I = InterestingIdentifiers.begin(),
- IEnd = InterestingIdentifiers.end();
- I != IEnd; ++I) {
- Generator.insert(I->first(), I->second, Trait);
- }
-
- // Create the on-disk hash table in a buffer.
- SmallString<4096> IdentifierTable;
- uint32_t BucketOffset;
- {
- using namespace llvm::support;
- llvm::raw_svector_ostream Out(IdentifierTable);
- // Make sure that no bucket is at offset 0
- endian::write<uint32_t>(Out, 0, little);
- BucketOffset = Generator.Emit(Out, Trait);
- }
-
- // Create a blob abbreviation
- auto Abbrev = std::make_shared<BitCodeAbbrev>();
- Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_INDEX));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
- unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
-
- // Write the identifier table
- uint64_t Record[] = {IDENTIFIER_INDEX, BucketOffset};
- Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable);
- }
-
- Stream.ExitBlock();
- return false;
-}
-
-GlobalModuleIndex::ErrorCode
-GlobalModuleIndex::writeIndex(FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- StringRef Path) {
- llvm::SmallString<128> IndexPath;
- IndexPath += Path;
- llvm::sys::path::append(IndexPath, IndexFileName);
-
- // Coordinate building the global index file with other processes that might
- // try to do the same.
- llvm::LockFileManager Locked(IndexPath);
- switch (Locked) {
- case llvm::LockFileManager::LFS_Error:
- return EC_IOError;
-
- case llvm::LockFileManager::LFS_Owned:
- // We're responsible for building the index ourselves. Do so below.
- break;
-
- case llvm::LockFileManager::LFS_Shared:
- // Someone else is responsible for building the index. We don't care
- // when they finish, so we're done.
- return EC_Building;
- }
-
- // The module index builder.
- GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerRdr);
-
- // Load each of the module files.
- std::error_code EC;
- for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
- D != DEnd && !EC;
- D.increment(EC)) {
- // If this isn't a module file, we don't care.
- if (llvm::sys::path::extension(D->path()) != ".pcm") {
- // ... unless it's a .pcm.lock file, which indicates that someone is
- // in the process of rebuilding a module. They'll rebuild the index
- // at the end of that translation unit, so we don't have to.
- if (llvm::sys::path::extension(D->path()) == ".pcm.lock")
- return EC_Building;
-
- continue;
- }
-
- // If we can't find the module file, skip it.
- const FileEntry *ModuleFile = FileMgr.getFile(D->path());
- if (!ModuleFile)
- continue;
-
- // Load this module file.
- if (Builder.loadModuleFile(ModuleFile))
- return EC_IOError;
- }
-
- // The output buffer, into which the global index will be written.
- SmallVector<char, 16> OutputBuffer;
- {
- llvm::BitstreamWriter OutputStream(OutputBuffer);
- if (Builder.writeIndex(OutputStream))
- return EC_IOError;
- }
-
- // Write the global index file to a temporary file.
- llvm::SmallString<128> IndexTmpPath;
- int TmpFD;
- if (llvm::sys::fs::createUniqueFile(IndexPath + "-%%%%%%%%", TmpFD,
- IndexTmpPath))
- return EC_IOError;
-
- // Open the temporary global index file for output.
- llvm::raw_fd_ostream Out(TmpFD, true);
- if (Out.has_error())
- return EC_IOError;
-
- // Write the index.
- Out.write(OutputBuffer.data(), OutputBuffer.size());
- Out.close();
- if (Out.has_error())
- return EC_IOError;
-
- // Remove the old index file. It isn't relevant any more.
- llvm::sys::fs::remove(IndexPath);
-
- // Rename the newly-written index file to the proper name.
- if (llvm::sys::fs::rename(IndexTmpPath, IndexPath)) {
- // Rename failed; just remove the
- llvm::sys::fs::remove(IndexTmpPath);
- return EC_IOError;
- }
-
- // We're done.
- return EC_None;
-}
-
-namespace {
- class GlobalIndexIdentifierIterator : public IdentifierIterator {
- /// The current position within the identifier lookup table.
- IdentifierIndexTable::key_iterator Current;
-
- /// The end position within the identifier lookup table.
- IdentifierIndexTable::key_iterator End;
-
- public:
- explicit GlobalIndexIdentifierIterator(IdentifierIndexTable &Idx) {
- Current = Idx.key_begin();
- End = Idx.key_end();
- }
-
- StringRef Next() override {
- if (Current == End)
- return StringRef();
-
- StringRef Result = *Current;
- ++Current;
- return Result;
- }
- };
-}
-
-IdentifierIterator *GlobalModuleIndex::createIdentifierIterator() const {
- IdentifierIndexTable &Table =
- *static_cast<IdentifierIndexTable *>(IdentifierIndex);
- return new GlobalIndexIdentifierIterator(Table);
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/Module.cpp b/gnu/llvm/tools/clang/lib/Serialization/Module.cpp
deleted file mode 100644
index 580e46e4f24..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/Module.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-//===- Module.cpp - Module description ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Module class, which describes a module that has
-// been loaded from an AST file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/Module.h"
-#include "ASTReaderInternals.h"
-#include "clang/Serialization/ContinuousRangeMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace serialization;
-using namespace reader;
-
-ModuleFile::~ModuleFile() {
- delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
- delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
- delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
-}
-
-template<typename Key, typename Offset, unsigned InitialCapacity>
-static void
-dumpLocalRemap(StringRef Name,
- const ContinuousRangeMap<Key, Offset, InitialCapacity> &Map) {
- if (Map.begin() == Map.end())
- return;
-
- using MapType = ContinuousRangeMap<Key, Offset, InitialCapacity>;
-
- llvm::errs() << " " << Name << ":\n";
- for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end();
- I != IEnd; ++I) {
- llvm::errs() << " " << I->first << " -> " << I->second << "\n";
- }
-}
-
-LLVM_DUMP_METHOD void ModuleFile::dump() {
- llvm::errs() << "\nModule: " << FileName << "\n";
- if (!Imports.empty()) {
- llvm::errs() << " Imports: ";
- for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
- if (I)
- llvm::errs() << ", ";
- llvm::errs() << Imports[I]->FileName;
- }
- llvm::errs() << "\n";
- }
-
- // Remapping tables.
- llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset
- << '\n';
- dumpLocalRemap("Source location offset local -> global map", SLocRemap);
-
- llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n'
- << " Number of identifiers: " << LocalNumIdentifiers << '\n';
- dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap);
-
- llvm::errs() << " Base macro ID: " << BaseMacroID << '\n'
- << " Number of macros: " << LocalNumMacros << '\n';
- dumpLocalRemap("Macro ID local -> global map", MacroRemap);
-
- llvm::errs() << " Base submodule ID: " << BaseSubmoduleID << '\n'
- << " Number of submodules: " << LocalNumSubmodules << '\n';
- dumpLocalRemap("Submodule ID local -> global map", SubmoduleRemap);
-
- llvm::errs() << " Base selector ID: " << BaseSelectorID << '\n'
- << " Number of selectors: " << LocalNumSelectors << '\n';
- dumpLocalRemap("Selector ID local -> global map", SelectorRemap);
-
- llvm::errs() << " Base preprocessed entity ID: " << BasePreprocessedEntityID
- << '\n'
- << " Number of preprocessed entities: "
- << NumPreprocessedEntities << '\n';
- dumpLocalRemap("Preprocessed entity ID local -> global map",
- PreprocessedEntityRemap);
-
- llvm::errs() << " Base type index: " << BaseTypeIndex << '\n'
- << " Number of types: " << LocalNumTypes << '\n';
- dumpLocalRemap("Type index local -> global map", TypeRemap);
-
- llvm::errs() << " Base decl ID: " << BaseDeclID << '\n'
- << " Number of decls: " << LocalNumDecls << '\n';
- dumpLocalRemap("Decl ID local -> global map", DeclRemap);
-}
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ModuleFileExtension.cpp b/gnu/llvm/tools/clang/lib/Serialization/ModuleFileExtension.cpp
deleted file mode 100644
index 5bd0a1ce660..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ModuleFileExtension.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//===-- ModuleFileExtension.cpp - Module File Extensions ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "clang/Serialization/ModuleFileExtension.h"
-#include "llvm/ADT/Hashing.h"
-using namespace clang;
-
-ModuleFileExtension::~ModuleFileExtension() { }
-
-llvm::hash_code ModuleFileExtension::hashExtension(llvm::hash_code Code) const {
- return Code;
-}
-
-ModuleFileExtensionWriter::~ModuleFileExtensionWriter() { }
-
-ModuleFileExtensionReader::~ModuleFileExtensionReader() { }
diff --git a/gnu/llvm/tools/clang/lib/Serialization/ModuleManager.cpp b/gnu/llvm/tools/clang/lib/Serialization/ModuleManager.cpp
deleted file mode 100644
index 54e0c08c5bc..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/ModuleManager.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-//===- ModuleManager.cpp - Module Manager ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ModuleManager class, which manages a set of loaded
-// modules for the ASTReader.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/ModuleManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/MemoryBufferCache.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/ModuleMap.h"
-#include "clang/Serialization/GlobalModuleIndex.h"
-#include "clang/Serialization/Module.h"
-#include "clang/Serialization/PCHContainerOperations.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Support/Chrono.h"
-#include "llvm/Support/DOTGraphTraits.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/GraphWriter.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/VirtualFileSystem.h"
-#include <algorithm>
-#include <cassert>
-#include <memory>
-#include <string>
-#include <system_error>
-
-using namespace clang;
-using namespace serialization;
-
-ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const {
- const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
- /*cacheFailure=*/false);
- if (Entry)
- return lookup(Entry);
-
- return nullptr;
-}
-
-ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const {
- if (const Module *Mod = HeaderSearchInfo.getModuleMap().findModule(Name))
- if (const FileEntry *File = Mod->getASTFile())
- return lookup(File);
-
- return nullptr;
-}
-
-ModuleFile *ModuleManager::lookup(const FileEntry *File) const {
- auto Known = Modules.find(File);
- if (Known == Modules.end())
- return nullptr;
-
- return Known->second;
-}
-
-std::unique_ptr<llvm::MemoryBuffer>
-ModuleManager::lookupBuffer(StringRef Name) {
- const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
- /*cacheFailure=*/false);
- return std::move(InMemoryBuffers[Entry]);
-}
-
-static bool checkSignature(ASTFileSignature Signature,
- ASTFileSignature ExpectedSignature,
- std::string &ErrorStr) {
- if (!ExpectedSignature || Signature == ExpectedSignature)
- return false;
-
- ErrorStr =
- Signature ? "signature mismatch" : "could not read module signature";
- return true;
-}
-
-static void updateModuleImports(ModuleFile &MF, ModuleFile *ImportedBy,
- SourceLocation ImportLoc) {
- if (ImportedBy) {
- MF.ImportedBy.insert(ImportedBy);
- ImportedBy->Imports.insert(&MF);
- } else {
- if (!MF.DirectlyImported)
- MF.ImportLoc = ImportLoc;
-
- MF.DirectlyImported = true;
- }
-}
-
-ModuleManager::AddModuleResult
-ModuleManager::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) {
- Module = nullptr;
-
- // Look for the file entry. This only fails if the expected size or
- // modification time differ.
- const FileEntry *Entry;
- if (Type == MK_ExplicitModule || Type == MK_PrebuiltModule) {
- // If we're not expecting to pull this file out of the module cache, it
- // might have a different mtime due to being moved across filesystems in
- // a distributed build. The size must still match, though. (As must the
- // contents, but we can't check that.)
- ExpectedModTime = 0;
- }
- if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) {
- ErrorStr = "module file out of date";
- return OutOfDate;
- }
-
- if (!Entry && FileName != "-") {
- ErrorStr = "module file not found";
- return Missing;
- }
-
- // Check whether we already loaded this module, before
- if (ModuleFile *ModuleEntry = Modules.lookup(Entry)) {
- // Check the stored signature.
- if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
- return OutOfDate;
-
- Module = ModuleEntry;
- updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc);
- return AlreadyLoaded;
- }
-
- // Allocate a new module.
- auto NewModule = llvm::make_unique<ModuleFile>(Type, Generation);
- NewModule->Index = Chain.size();
- NewModule->FileName = FileName.str();
- NewModule->File = Entry;
- NewModule->ImportLoc = ImportLoc;
- NewModule->InputFilesValidationTimestamp = 0;
-
- if (NewModule->Kind == MK_ImplicitModule) {
- std::string TimestampFilename = NewModule->getTimestampFilename();
- llvm::vfs::Status Status;
- // A cached stat value would be fine as well.
- if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
- NewModule->InputFilesValidationTimestamp =
- llvm::sys::toTimeT(Status.getLastModificationTime());
- }
-
- // Load the contents of the module
- if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
- // The buffer was already provided for us.
- NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer));
- // Since the cached buffer is reused, it is safe to close the file
- // descriptor that was opened while stat()ing the PCM in
- // lookupModuleFile() above, it won't be needed any longer.
- Entry->closeFile();
- } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) {
- NewModule->Buffer = Buffer;
- // As above, the file descriptor is no longer needed.
- Entry->closeFile();
- } else {
- // Open the AST file.
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
- if (FileName == "-") {
- Buf = llvm::MemoryBuffer::getSTDIN();
- } else {
- // Get a buffer of the file and close the file descriptor when done.
- Buf = FileMgr.getBufferForFile(NewModule->File,
- /*IsVolatile=*/false,
- /*ShouldClose=*/true);
- }
-
- if (!Buf) {
- ErrorStr = Buf.getError().message();
- return Missing;
- }
-
- NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf));
- }
-
- // Initialize the stream.
- NewModule->Data = PCHContainerRdr.ExtractPCH(*NewModule->Buffer);
-
- // Read the signature eagerly now so that we can check it. Avoid calling
- // ReadSignature unless there's something to check though.
- if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
- ExpectedSignature, ErrorStr)) {
- // Try to remove the buffer. If it can't be removed, then it was already
- // validated by this process.
- if (!PCMCache->tryToRemoveBuffer(NewModule->FileName))
- FileMgr.invalidateCache(NewModule->File);
- return OutOfDate;
- }
-
- // We're keeping this module. Store it everywhere.
- Module = Modules[Entry] = NewModule.get();
-
- updateModuleImports(*NewModule, ImportedBy, ImportLoc);
-
- if (!NewModule->isModule())
- PCHChain.push_back(NewModule.get());
- if (!ImportedBy)
- Roots.push_back(NewModule.get());
-
- Chain.push_back(std::move(NewModule));
- return NewlyLoaded;
-}
-
-void ModuleManager::removeModules(
- ModuleIterator First,
- llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
- ModuleMap *modMap) {
- auto Last = end();
- if (First == Last)
- return;
-
- // Explicitly clear VisitOrder since we might not notice it is stale.
- VisitOrder.clear();
-
- // Collect the set of module file pointers that we'll be removing.
- llvm::SmallPtrSet<ModuleFile *, 4> victimSet(
- (llvm::pointer_iterator<ModuleIterator>(First)),
- (llvm::pointer_iterator<ModuleIterator>(Last)));
-
- auto IsVictim = [&](ModuleFile *MF) {
- return victimSet.count(MF);
- };
- // Remove any references to the now-destroyed modules.
- for (auto I = begin(); I != First; ++I) {
- I->Imports.remove_if(IsVictim);
- I->ImportedBy.remove_if(IsVictim);
- }
- Roots.erase(std::remove_if(Roots.begin(), Roots.end(), IsVictim),
- Roots.end());
-
- // Remove the modules from the PCH chain.
- for (auto I = First; I != Last; ++I) {
- if (!I->isModule()) {
- PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), &*I),
- PCHChain.end());
- break;
- }
- }
-
- // Delete the modules and erase them from the various structures.
- for (ModuleIterator victim = First; victim != Last; ++victim) {
- Modules.erase(victim->File);
-
- if (modMap) {
- StringRef ModuleName = victim->ModuleName;
- if (Module *mod = modMap->findModule(ModuleName)) {
- mod->setASTFile(nullptr);
- }
- }
-
- // Files that didn't make it through ReadASTCore successfully will be
- // rebuilt (or there was an error). Invalidate them so that we can load the
- // new files that will be renamed over the old ones.
- //
- // The PCMCache tracks whether the module was successfully loaded in another
- // thread/context; in that case, it won't need to be rebuilt (and we can't
- // safely invalidate it anyway).
- if (LoadedSuccessfully.count(&*victim) == 0 &&
- !PCMCache->tryToRemoveBuffer(victim->FileName))
- FileMgr.invalidateCache(victim->File);
- }
-
- // Delete the modules.
- Chain.erase(Chain.begin() + (First - begin()), Chain.end());
-}
-
-void
-ModuleManager::addInMemoryBuffer(StringRef FileName,
- std::unique_ptr<llvm::MemoryBuffer> Buffer) {
- const FileEntry *Entry =
- FileMgr.getVirtualFile(FileName, Buffer->getBufferSize(), 0);
- InMemoryBuffers[Entry] = std::move(Buffer);
-}
-
-ModuleManager::VisitState *ModuleManager::allocateVisitState() {
- // Fast path: if we have a cached state, use it.
- if (FirstVisitState) {
- VisitState *Result = FirstVisitState;
- FirstVisitState = FirstVisitState->NextState;
- Result->NextState = nullptr;
- return Result;
- }
-
- // Allocate and return a new state.
- return new VisitState(size());
-}
-
-void ModuleManager::returnVisitState(VisitState *State) {
- assert(State->NextState == nullptr && "Visited state is in list?");
- State->NextState = FirstVisitState;
- FirstVisitState = State;
-}
-
-void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) {
- GlobalIndex = Index;
- if (!GlobalIndex) {
- ModulesInCommonWithGlobalIndex.clear();
- return;
- }
-
- // Notify the global module index about all of the modules we've already
- // loaded.
- for (ModuleFile &M : *this)
- if (!GlobalIndex->loadedModuleFile(&M))
- ModulesInCommonWithGlobalIndex.push_back(&M);
-}
-
-void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
- if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF))
- return;
-
- ModulesInCommonWithGlobalIndex.push_back(MF);
-}
-
-ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
- const PCHContainerReader &PCHContainerRdr,
- const HeaderSearch& HeaderSearchInfo)
- : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr),
- HeaderSearchInfo(HeaderSearchInfo) {}
-
-ModuleManager::~ModuleManager() { delete FirstVisitState; }
-
-void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
- llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
- // If the visitation order vector is the wrong size, recompute the order.
- if (VisitOrder.size() != Chain.size()) {
- unsigned N = size();
- VisitOrder.clear();
- VisitOrder.reserve(N);
-
- // Record the number of incoming edges for each module. When we
- // encounter a module with no incoming edges, push it into the queue
- // to seed the queue.
- SmallVector<ModuleFile *, 4> Queue;
- Queue.reserve(N);
- llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
- UnusedIncomingEdges.resize(size());
- for (ModuleFile &M : llvm::reverse(*this)) {
- unsigned Size = M.ImportedBy.size();
- UnusedIncomingEdges[M.Index] = Size;
- if (!Size)
- Queue.push_back(&M);
- }
-
- // Traverse the graph, making sure to visit a module before visiting any
- // of its dependencies.
- while (!Queue.empty()) {
- ModuleFile *CurrentModule = Queue.pop_back_val();
- VisitOrder.push_back(CurrentModule);
-
- // For any module that this module depends on, push it on the
- // stack (if it hasn't already been marked as visited).
- for (auto M = CurrentModule->Imports.rbegin(),
- MEnd = CurrentModule->Imports.rend();
- M != MEnd; ++M) {
- // Remove our current module as an impediment to visiting the
- // module we depend on. If we were the last unvisited module
- // that depends on this particular module, push it into the
- // queue to be visited.
- unsigned &NumUnusedEdges = UnusedIncomingEdges[(*M)->Index];
- if (NumUnusedEdges && (--NumUnusedEdges == 0))
- Queue.push_back(*M);
- }
- }
-
- assert(VisitOrder.size() == N && "Visitation order is wrong?");
-
- delete FirstVisitState;
- FirstVisitState = nullptr;
- }
-
- VisitState *State = allocateVisitState();
- unsigned VisitNumber = State->NextVisitNumber++;
-
- // If the caller has provided us with a hit-set that came from the global
- // module index, mark every module file in common with the global module
- // index that is *not* in that set as 'visited'.
- if (ModuleFilesHit && !ModulesInCommonWithGlobalIndex.empty()) {
- for (unsigned I = 0, N = ModulesInCommonWithGlobalIndex.size(); I != N; ++I)
- {
- ModuleFile *M = ModulesInCommonWithGlobalIndex[I];
- if (!ModuleFilesHit->count(M))
- State->VisitNumber[M->Index] = VisitNumber;
- }
- }
-
- for (unsigned I = 0, N = VisitOrder.size(); I != N; ++I) {
- ModuleFile *CurrentModule = VisitOrder[I];
- // Should we skip this module file?
- if (State->VisitNumber[CurrentModule->Index] == VisitNumber)
- continue;
-
- // Visit the module.
- assert(State->VisitNumber[CurrentModule->Index] == VisitNumber - 1);
- State->VisitNumber[CurrentModule->Index] = VisitNumber;
- if (!Visitor(*CurrentModule))
- continue;
-
- // The visitor has requested that cut off visitation of any
- // module that the current module depends on. To indicate this
- // behavior, we mark all of the reachable modules as having been visited.
- ModuleFile *NextModule = CurrentModule;
- do {
- // For any module that this module depends on, push it on the
- // stack (if it hasn't already been marked as visited).
- for (llvm::SetVector<ModuleFile *>::iterator
- M = NextModule->Imports.begin(),
- MEnd = NextModule->Imports.end();
- M != MEnd; ++M) {
- if (State->VisitNumber[(*M)->Index] != VisitNumber) {
- State->Stack.push_back(*M);
- State->VisitNumber[(*M)->Index] = VisitNumber;
- }
- }
-
- if (State->Stack.empty())
- break;
-
- // Pop the next module off the stack.
- NextModule = State->Stack.pop_back_val();
- } while (true);
- }
-
- returnVisitState(State);
-}
-
-bool ModuleManager::lookupModuleFile(StringRef FileName,
- off_t ExpectedSize,
- time_t ExpectedModTime,
- const FileEntry *&File) {
- if (FileName == "-") {
- File = nullptr;
- return false;
- }
-
- // Open the file immediately to ensure there is no race between stat'ing and
- // opening the file.
- File = FileMgr.getFile(FileName, /*openFile=*/true, /*cacheFailure=*/false);
- if (!File)
- return false;
-
- if ((ExpectedSize && ExpectedSize != File->getSize()) ||
- (ExpectedModTime && ExpectedModTime != File->getModificationTime()))
- // Do not destroy File, as it may be referenced. If we need to rebuild it,
- // it will be destroyed by removeModules.
- return true;
-
- return false;
-}
-
-#ifndef NDEBUG
-namespace llvm {
-
- template<>
- struct GraphTraits<ModuleManager> {
- using NodeRef = ModuleFile *;
- using ChildIteratorType = llvm::SetVector<ModuleFile *>::const_iterator;
- using nodes_iterator = pointer_iterator<ModuleManager::ModuleConstIterator>;
-
- static ChildIteratorType child_begin(NodeRef Node) {
- return Node->Imports.begin();
- }
-
- static ChildIteratorType child_end(NodeRef Node) {
- return Node->Imports.end();
- }
-
- static nodes_iterator nodes_begin(const ModuleManager &Manager) {
- return nodes_iterator(Manager.begin());
- }
-
- static nodes_iterator nodes_end(const ModuleManager &Manager) {
- return nodes_iterator(Manager.end());
- }
- };
-
- template<>
- struct DOTGraphTraits<ModuleManager> : public DefaultDOTGraphTraits {
- explicit DOTGraphTraits(bool IsSimple = false)
- : DefaultDOTGraphTraits(IsSimple) {}
-
- static bool renderGraphFromBottomUp() { return true; }
-
- std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
- return M->ModuleName;
- }
- };
-
-} // namespace llvm
-
-void ModuleManager::viewGraph() {
- llvm::ViewGraph(*this, "Modules");
-}
-#endif
diff --git a/gnu/llvm/tools/clang/lib/Serialization/MultiOnDiskHashTable.h b/gnu/llvm/tools/clang/lib/Serialization/MultiOnDiskHashTable.h
deleted file mode 100644
index ded7cd14644..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/MultiOnDiskHashTable.h
+++ /dev/null
@@ -1,347 +0,0 @@
-//===- MultiOnDiskHashTable.h - Merged set of hash tables -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a hash table data structure suitable for incremental and
-// distributed storage across a set of files.
-//
-// Multiple hash tables from different files are implicitly merged to improve
-// performance, and on reload the merged table will override those from other
-// files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
-#define LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/EndianStream.h"
-#include "llvm/Support/OnDiskHashTable.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cstdint>
-#include <vector>
-
-namespace clang {
-namespace serialization {
-
-/// A collection of on-disk hash tables, merged when relevant for performance.
-template<typename Info> class MultiOnDiskHashTable {
-public:
- /// A handle to a file, used when overriding tables.
- using file_type = typename Info::file_type;
-
- /// A pointer to an on-disk representation of the hash table.
- using storage_type = const unsigned char *;
-
- using external_key_type = typename Info::external_key_type;
- using internal_key_type = typename Info::internal_key_type;
- using data_type = typename Info::data_type;
- using data_type_builder = typename Info::data_type_builder;
- using hash_value_type = unsigned;
-
-private:
- /// The generator is permitted to read our merged table.
- template<typename ReaderInfo, typename WriterInfo>
- friend class MultiOnDiskHashTableGenerator;
-
- /// A hash table stored on disk.
- struct OnDiskTable {
- using HashTable = llvm::OnDiskIterableChainedHashTable<Info>;
-
- file_type File;
- HashTable Table;
-
- OnDiskTable(file_type File, unsigned NumBuckets, unsigned NumEntries,
- storage_type Buckets, storage_type Payload, storage_type Base,
- const Info &InfoObj)
- : File(File),
- Table(NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj) {}
- };
-
- struct MergedTable {
- std::vector<file_type> Files;
- llvm::DenseMap<internal_key_type, data_type> Data;
- };
-
- using Table = llvm::PointerUnion<OnDiskTable *, MergedTable *>;
- using TableVector = llvm::TinyPtrVector<void *>;
-
- /// The current set of on-disk and merged tables.
- /// We manually store the opaque value of the Table because TinyPtrVector
- /// can't cope with holding a PointerUnion directly.
- /// There can be at most one MergedTable in this vector, and if present,
- /// it is the first table.
- TableVector Tables;
-
- /// Files corresponding to overridden tables that we've not yet
- /// discarded.
- llvm::TinyPtrVector<file_type> PendingOverrides;
-
- struct AsOnDiskTable {
- using result_type = OnDiskTable *;
-
- result_type operator()(void *P) const {
- return Table::getFromOpaqueValue(P).template get<OnDiskTable *>();
- }
- };
-
- using table_iterator =
- llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable>;
- using table_range = llvm::iterator_range<table_iterator>;
-
- /// The current set of on-disk tables.
- table_range tables() {
- auto Begin = Tables.begin(), End = Tables.end();
- if (getMergedTable())
- ++Begin;
- return llvm::make_range(llvm::map_iterator(Begin, AsOnDiskTable()),
- llvm::map_iterator(End, AsOnDiskTable()));
- }
-
- MergedTable *getMergedTable() const {
- // If we already have a merged table, it's the first one.
- return Tables.empty() ? nullptr : Table::getFromOpaqueValue(*Tables.begin())
- .template dyn_cast<MergedTable*>();
- }
-
- /// Delete all our current on-disk tables.
- void clear() {
- for (auto *T : tables())
- delete T;
- if (auto *M = getMergedTable())
- delete M;
- Tables.clear();
- }
-
- void removeOverriddenTables() {
- llvm::DenseSet<file_type> Files;
- Files.insert(PendingOverrides.begin(), PendingOverrides.end());
- // Explicitly capture Files to work around an MSVC 2015 rejects-valid bug.
- auto ShouldRemove = [&Files](void *T) -> bool {
- auto *ODT = Table::getFromOpaqueValue(T).template get<OnDiskTable *>();
- bool Remove = Files.count(ODT->File);
- if (Remove)
- delete ODT;
- return Remove;
- };
- Tables.erase(std::remove_if(tables().begin().getCurrent(), Tables.end(),
- ShouldRemove),
- Tables.end());
- PendingOverrides.clear();
- }
-
- void condense() {
- MergedTable *Merged = getMergedTable();
- if (!Merged)
- Merged = new MergedTable;
-
- // Read in all the tables and merge them together.
- // FIXME: Be smarter about which tables we merge.
- for (auto *ODT : tables()) {
- auto &HT = ODT->Table;
- Info &InfoObj = HT.getInfoObj();
-
- for (auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
- auto *LocalPtr = I.getItem();
-
- // FIXME: Don't rely on the OnDiskHashTable format here.
- auto L = InfoObj.ReadKeyDataLength(LocalPtr);
- const internal_key_type &Key = InfoObj.ReadKey(LocalPtr, L.first);
- data_type_builder ValueBuilder(Merged->Data[Key]);
- InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second,
- ValueBuilder);
- }
-
- Merged->Files.push_back(ODT->File);
- delete ODT;
- }
-
- Tables.clear();
- Tables.push_back(Table(Merged).getOpaqueValue());
- }
-
-public:
- MultiOnDiskHashTable() = default;
-
- MultiOnDiskHashTable(MultiOnDiskHashTable &&O)
- : Tables(std::move(O.Tables)),
- PendingOverrides(std::move(O.PendingOverrides)) {
- O.Tables.clear();
- }
-
- MultiOnDiskHashTable &operator=(MultiOnDiskHashTable &&O) {
- if (&O == this)
- return *this;
- clear();
- Tables = std::move(O.Tables);
- O.Tables.clear();
- PendingOverrides = std::move(O.PendingOverrides);
- return *this;
- }
-
- ~MultiOnDiskHashTable() { clear(); }
-
- /// Add the table \p Data loaded from file \p File.
- void add(file_type File, storage_type Data, Info InfoObj = Info()) {
- using namespace llvm::support;
-
- storage_type Ptr = Data;
-
- uint32_t BucketOffset = endian::readNext<uint32_t, little, unaligned>(Ptr);
-
- // Read the list of overridden files.
- uint32_t NumFiles = endian::readNext<uint32_t, little, unaligned>(Ptr);
- // FIXME: Add a reserve() to TinyPtrVector so that we don't need to make
- // an additional copy.
- llvm::SmallVector<file_type, 16> OverriddenFiles;
- OverriddenFiles.reserve(NumFiles);
- for (/**/; NumFiles != 0; --NumFiles)
- OverriddenFiles.push_back(InfoObj.ReadFileRef(Ptr));
- PendingOverrides.insert(PendingOverrides.end(), OverriddenFiles.begin(),
- OverriddenFiles.end());
-
- // Read the OnDiskChainedHashTable header.
- storage_type Buckets = Data + BucketOffset;
- auto NumBucketsAndEntries =
- OnDiskTable::HashTable::readNumBucketsAndEntries(Buckets);
-
- // Register the table.
- Table NewTable = new OnDiskTable(File, NumBucketsAndEntries.first,
- NumBucketsAndEntries.second,
- Buckets, Ptr, Data, std::move(InfoObj));
- Tables.push_back(NewTable.getOpaqueValue());
- }
-
- /// Find and read the lookup results for \p EKey.
- data_type find(const external_key_type &EKey) {
- data_type Result;
-
- if (!PendingOverrides.empty())
- removeOverriddenTables();
-
- if (Tables.size() > static_cast<unsigned>(Info::MaxTables))
- condense();
-
- internal_key_type Key = Info::GetInternalKey(EKey);
- auto KeyHash = Info::ComputeHash(Key);
-
- if (MergedTable *M = getMergedTable()) {
- auto It = M->Data.find(Key);
- if (It != M->Data.end())
- Result = It->second;
- }
-
- data_type_builder ResultBuilder(Result);
-
- for (auto *ODT : tables()) {
- auto &HT = ODT->Table;
- auto It = HT.find_hashed(Key, KeyHash);
- if (It != HT.end())
- HT.getInfoObj().ReadDataInto(Key, It.getDataPtr(), It.getDataLen(),
- ResultBuilder);
- }
-
- return Result;
- }
-
- /// Read all the lookup results into a single value. This only makes
- /// sense if merging values across keys is meaningful.
- data_type findAll() {
- data_type Result;
- data_type_builder ResultBuilder(Result);
-
- if (!PendingOverrides.empty())
- removeOverriddenTables();
-
- if (MergedTable *M = getMergedTable()) {
- for (auto &KV : M->Data)
- Info::MergeDataInto(KV.second, ResultBuilder);
- }
-
- for (auto *ODT : tables()) {
- auto &HT = ODT->Table;
- Info &InfoObj = HT.getInfoObj();
- for (auto I = HT.data_begin(), E = HT.data_end(); I != E; ++I) {
- auto *LocalPtr = I.getItem();
-
- // FIXME: Don't rely on the OnDiskHashTable format here.
- auto L = InfoObj.ReadKeyDataLength(LocalPtr);
- const internal_key_type &Key = InfoObj.ReadKey(LocalPtr, L.first);
- InfoObj.ReadDataInto(Key, LocalPtr + L.first, L.second, ResultBuilder);
- }
- }
-
- return Result;
- }
-};
-
-/// Writer for the on-disk hash table.
-template<typename ReaderInfo, typename WriterInfo>
-class MultiOnDiskHashTableGenerator {
- using BaseTable = MultiOnDiskHashTable<ReaderInfo>;
- using Generator = llvm::OnDiskChainedHashTableGenerator<WriterInfo>;
-
- Generator Gen;
-
-public:
- MultiOnDiskHashTableGenerator() : Gen() {}
-
- void insert(typename WriterInfo::key_type_ref Key,
- typename WriterInfo::data_type_ref Data, WriterInfo &Info) {
- Gen.insert(Key, Data, Info);
- }
-
- void emit(llvm::SmallVectorImpl<char> &Out, WriterInfo &Info,
- const BaseTable *Base) {
- using namespace llvm::support;
-
- llvm::raw_svector_ostream OutStream(Out);
-
- // Write our header information.
- {
- endian::Writer Writer(OutStream, little);
-
- // Reserve four bytes for the bucket offset.
- Writer.write<uint32_t>(0);
-
- if (auto *Merged = Base ? Base->getMergedTable() : nullptr) {
- // Write list of overridden files.
- Writer.write<uint32_t>(Merged->Files.size());
- for (const auto &F : Merged->Files)
- Info.EmitFileRef(OutStream, F);
-
- // Add all merged entries from Base to the generator.
- for (auto &KV : Merged->Data) {
- if (!Gen.contains(KV.first, Info))
- Gen.insert(KV.first, Info.ImportData(KV.second), Info);
- }
- } else {
- Writer.write<uint32_t>(0);
- }
- }
-
- // Write the table itself.
- uint32_t BucketOffset = Gen.Emit(OutStream, Info);
-
- // Replace the first four bytes with the bucket offset.
- endian::write32le(Out.data(), BucketOffset);
- }
-};
-
-} // namespace serialization
-} // namespace clang
-
-#endif // LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H
diff --git a/gnu/llvm/tools/clang/lib/Serialization/PCHContainerOperations.cpp b/gnu/llvm/tools/clang/lib/Serialization/PCHContainerOperations.cpp
deleted file mode 100644
index fbc613efeb6..00000000000
--- a/gnu/llvm/tools/clang/lib/Serialization/PCHContainerOperations.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-//=== Serialization/PCHContainerOperations.cpp - PCH Containers -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines PCHContainerOperations and RawPCHContainerOperation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Serialization/PCHContainerOperations.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Lex/ModuleLoader.h"
-#include "llvm/Bitcode/BitstreamReader.h"
-#include "llvm/Support/raw_ostream.h"
-#include <utility>
-
-using namespace clang;
-
-PCHContainerWriter::~PCHContainerWriter() {}
-PCHContainerReader::~PCHContainerReader() {}
-
-namespace {
-
-/// A PCHContainerGenerator that writes out the PCH to a flat file.
-class RawPCHContainerGenerator : public ASTConsumer {
- std::shared_ptr<PCHBuffer> Buffer;
- std::unique_ptr<raw_pwrite_stream> OS;
-
-public:
- RawPCHContainerGenerator(std::unique_ptr<llvm::raw_pwrite_stream> OS,
- std::shared_ptr<PCHBuffer> Buffer)
- : Buffer(std::move(Buffer)), OS(std::move(OS)) {}
-
- ~RawPCHContainerGenerator() override = default;
-
- void HandleTranslationUnit(ASTContext &Ctx) override {
- if (Buffer->IsComplete) {
- // Make sure it hits disk now.
- *OS << Buffer->Data;
- OS->flush();
- }
- // Free the space of the temporary buffer.
- llvm::SmallVector<char, 0> Empty;
- Buffer->Data = std::move(Empty);
- }
-};
-
-} // anonymous namespace
-
-std::unique_ptr<ASTConsumer> RawPCHContainerWriter::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 {
- return llvm::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer);
-}
-
-StringRef
-RawPCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const {
- return Buffer.getBuffer();
-}
-
-PCHContainerOperations::PCHContainerOperations() {
- registerWriter(llvm::make_unique<RawPCHContainerWriter>());
- registerReader(llvm::make_unique<RawPCHContainerReader>());
-}