llvm/clang/lib/Serialization/ASTReaderDecl.cpp

//===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the ASTReader::readDeclRecord method, which is the
// entrypoint for loading a decl.
//
//===----------------------------------------------------------------------===//

#include "ASTCommon.h"
#include "ASTReaderInternals.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTStructuralEquivalence.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/DiagnosticSema.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/Basic/Stack.h"
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTRecordReader.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/ModuleFile.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/Bitstream/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>

usingnamespaceclang;
usingnamespaceserialization;

//===----------------------------------------------------------------------===//
// Declaration Merging
//===----------------------------------------------------------------------===//

namespace {
/// Results from loading a RedeclarableDecl.
class RedeclarableResult {};
} // namespace

namespace clang {
class ASTDeclMerger {};
} // namespace clang

//===----------------------------------------------------------------------===//
// Declaration deserialization
//===----------------------------------------------------------------------===//

namespace clang {
class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {};

  } // 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 {};

} // namespace

template <typename DeclT>
static llvm::iterator_range<MergedRedeclIterator<DeclT>>
merged_redecls(DeclT *D) {}

uint64_t ASTDeclReader::GetCurrentCursorOffset() {}

void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {}

void ASTDeclReader::Visit(Decl *D) {}

void ASTDeclReader::VisitDecl(Decl *D) {}

void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) {}

void ASTDeclReader::VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D) {}

void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {}

void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {}

void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {}

RedeclarableResult ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {}

void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {}

void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {}

RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {}

void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {}

RedeclarableResult ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {}

void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {}

void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {}

void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {}

void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {}

void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {}

void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {}

void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {}

void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {}

ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() {}

void ASTDeclReader::ReadObjCDefinitionData(
         struct ObjCInterfaceDecl::DefinitionData &Data) {}

void ASTDeclMerger::MergeDefinitionData(
    ObjCInterfaceDecl *D, struct ObjCInterfaceDecl::DefinitionData &&NewDD) {}

void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {}

void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {}

void ASTDeclReader::ReadObjCDefinitionData(
         struct ObjCProtocolDecl::DefinitionData &Data) {}

void ASTDeclMerger::MergeDefinitionData(
    ObjCProtocolDecl *D, struct ObjCProtocolDecl::DefinitionData &&NewDD) {}

void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {}

void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {}

void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {}

void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {}

void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {}

void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {}

void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {}

void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {}

void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {}

void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {}

void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) {}

void ASTDeclReader::VisitMSGuidDecl(MSGuidDecl *D) {}

void ASTDeclReader::VisitUnnamedGlobalConstantDecl(
    UnnamedGlobalConstantDecl *D) {}

void ASTDeclReader::VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D) {}

void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {}

RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {}

void ASTDeclReader::ReadVarDeclInit(VarDecl *VD) {}

void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {}

void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {}

void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) {}

void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) {}

void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {}

void ASTDeclReader::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {}

void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {}

void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {}

void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {}

void ASTDeclReader::VisitExportDecl(ExportDecl *D) {}

void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {}

void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {}

void ASTDeclReader::VisitHLSLBufferDecl(HLSLBufferDecl *D) {}

void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {}

void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {}

void ASTDeclReader::VisitUsingEnumDecl(UsingEnumDecl *D) {}

void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) {}

void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {}

void ASTDeclReader::VisitConstructorUsingShadowDecl(
    ConstructorUsingShadowDecl *D) {}

void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {}

void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {}

void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
                                               UnresolvedUsingTypenameDecl *D) {}

void ASTDeclReader::VisitUnresolvedUsingIfExistsDecl(
    UnresolvedUsingIfExistsDecl *D) {}

void ASTDeclReader::ReadCXXDefinitionData(
    struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D,
    Decl *LambdaContext, unsigned IndexInLambdaContext) {}

void ASTDeclMerger::MergeDefinitionData(
    CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &&MergeDD) {}

void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update,
                                            Decl *LambdaContext,
                                            unsigned IndexInLambdaContext) {}

RedeclarableResult ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {}

void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {}

void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {}

void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {}

void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {}

void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {}

void ASTDeclReader::VisitImportDecl(ImportDecl *D) {}

void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {}

void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {}

void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {}

void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {}

void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) {}

void ASTDeclReader::VisitImplicitConceptSpecializationDecl(
    ImplicitConceptSpecializationDecl *D) {}

void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {}

RedeclarableResult
ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {}

void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {}

void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {}

/// TODO: Unify with ClassTemplateDecl version?
///       May require unifying ClassTemplateDecl and
///        VarTemplateDecl beyond TemplateDecl...
void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {}

RedeclarableResult ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
    ClassTemplateSpecializationDecl *D) {}

void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
                                    ClassTemplatePartialSpecializationDecl *D) {}

void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {}

/// 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.
RedeclarableResult ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
    VarTemplateSpecializationDecl *D) {}

/// 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) {}

void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {}

void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {}

void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {}

void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {}

void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {}

void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {}

void ASTDeclReader::VisitLifetimeExtendedTemporaryDecl(
    LifetimeExtendedTemporaryDecl *D) {}

std::pair<uint64_t, uint64_t>
ASTDeclReader::VisitDeclContext(DeclContext *DC) {}

template <typename T>
RedeclarableResult ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {}

/// 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) {}

/// Attempt to merge D with a previous declaration of the same lambda, which is
/// found by its index within its context declaration, if it has one.
///
/// We can't look up lambdas in their enclosing lexical or semantic context in
/// general, because for lambdas in variables, both of those might be a
/// namespace or the translation unit.
void ASTDeclMerger::mergeLambda(CXXRecordDecl *D, RedeclarableResult &Redecl,
                                Decl &Context, unsigned IndexInContext) {}

void ASTDeclReader::mergeRedeclarableTemplate(RedeclarableTemplateDecl *D,
                                              RedeclarableResult &Redecl) {}

/// "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) {}
template<typename T> static T assert_cast(...) {}

/// Merge together the pattern declarations from two template
/// declarations.
void ASTDeclMerger::mergeTemplatePattern(RedeclarableTemplateDecl *D,
                                         RedeclarableTemplateDecl *Existing,
                                         bool IsKeyDecl) {}

/// Attempts to merge the given declaration (D) with another declaration
/// of the same entity.
template <typename T>
void ASTDeclMerger::mergeRedeclarableImpl(Redeclarable<T> *DBase, T *Existing,
                                          GlobalDeclID KeyDeclID) {}

/// 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) {}

/// Attempts to merge LifetimeExtendedTemporaryDecl with
/// identical class definitions from two different modules.
void ASTDeclReader::mergeMergeable(LifetimeExtendedTemporaryDecl *D) {}

/// 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) {}

void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {}

void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) {}

void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {}

void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {}

void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {}

void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {}

//===----------------------------------------------------------------------===//
// Attribute Reading
//===----------------------------------------------------------------------===//

namespace {
class AttrReader {};
}

Attr *ASTRecordReader::readAttr() {}

/// Reads attributes from the current stream position.
void ASTRecordReader::readAttributes(AttrVec &Attrs) {}

//===----------------------------------------------------------------------===//
// 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) {}

/// 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.
bool ASTReader::isConsumerInterestedIn(Decl *D) {}

/// Get the correct cursor and offset for loading a declaration.
ASTReader::RecordLocation ASTReader::DeclCursorForID(GlobalDeclID ID,
                                                     SourceLocation &Loc) {}

ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) {}

uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset) {}

CXXRecordDecl *
ASTDeclReader::getOrFakePrimaryClassDefinition(ASTReader &Reader,
                                               CXXRecordDecl *RD) {}

/// Find the context in which we should search for previous declarations when
/// looking for declarations to merge.
DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader,
                                                        DeclContext *DC) {}

ASTDeclReader::FindExistingResult::~FindExistingResult() {}

/// 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) {}

/// 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) {}

NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,
                                                     DeclContext *DC,
                                                     unsigned Index) {}

void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader,
                                               DeclContext *DC, unsigned Index,
                                               NamedDecl *D) {}

ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {}

template<typename DeclT>
Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) {}

Decl *ASTDeclReader::getMostRecentDeclImpl(...) {}

Decl *ASTDeclReader::getMostRecentDecl(Decl *D) {}

Decl *ASTReader::getMostRecentExistingDecl(Decl *D) {}

namespace {
void mergeInheritableAttributes(ASTReader &Reader, Decl *D, Decl *Previous) {}
} // namespace

template<typename DeclT>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
                                           Redeclarable<DeclT> *D,
                                           Decl *Previous, Decl *Canon) {}

namespace clang {

template<>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
                                           Redeclarable<VarDecl> *D,
                                           Decl *Previous, Decl *Canon) {}

static bool isUndeducedReturnType(QualType T) {}

template<>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
                                           Redeclarable<FunctionDecl> *D,
                                           Decl *Previous, Decl *Canon) {}

} // namespace clang

void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {}

/// 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) {}

static void inheritDefaultTemplateArguments(ASTContext &Context,
                                            TemplateDecl *From,
                                            TemplateDecl *To) {}

// [basic.link]/p10:
//    If two declarations of an entity are attached to different modules,
//    the program is ill-formed;
void ASTDeclReader::checkMultipleDefinitionInNamedModules(ASTReader &Reader,
                                                          Decl *D,
                                                          Decl *Previous) {}

void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
                                       Decl *Previous, Decl *Canon) {}

template<typename DeclT>
void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) {}

void ASTDeclReader::attachLatestDeclImpl(...) {}

void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {}

template<typename DeclT>
void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) {}

void ASTDeclReader::markIncompleteDeclChainImpl(...) {}

void ASTReader::markIncompleteDeclChain(Decl *D) {}

/// Read the declaration at the given offset from the AST file.
Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {}

void ASTReader::PassInterestingDeclsToConsumer() {}

void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {}

void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {}

namespace {

  /// Given an ObjC interface, goes through the modules and links to the
  /// interface all the categories for it.
  class ObjCCategoriesVisitor {};

} // namespace

void ASTReader::loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D,
                                   unsigned PreviousGeneration) {}

template<typename DeclT, typename Fn>
static void forAllLaterRedecls(DeclT *D, Fn F) {}

void ASTDeclReader::UpdateDecl(
    Decl *D,
    llvm::SmallVectorImpl<GlobalDeclID> &PendingLazySpecializationIDs) {}