DECB6D650F9AE26600F5FBC7 /* JumpDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB6D640F9AE26600F5FBC7 /* JumpDiagnostics.cpp */; };
DECB6F070F9D93A800F5FBC7 /* InitPreprocessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */; };
DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */; };
+ DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */; };
DED626C90AE0C065001E80A4 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED626C80AE0C065001E80A4 /* TargetInfo.cpp */; };
DED62ABB0AE2EDF1001E80A4 /* Decl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */; };
DED676D10B6C786700AAD4A3 /* Builtins.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676D00B6C786700AAD4A3 /* Builtins.def */; };
DECB734E0FA3ED8400F5FBC7 /* StmtObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtObjC.h; path = clang/AST/StmtObjC.h; sourceTree = "<group>"; };
DECB73550FA3EE5A00F5FBC7 /* StmtCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtCXX.h; path = clang/AST/StmtCXX.h; sourceTree = "<group>"; };
DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderStmt.cpp; path = lib/Frontend/PCHReaderStmt.cpp; sourceTree = "<group>"; };
+ DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderDecl.cpp; path = lib/Frontend/PCHReaderDecl.cpp; sourceTree = "<group>"; };
DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Decl.cpp; path = lib/AST/Decl.cpp; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
DED676D00B6C786700AAD4A3 /* Builtins.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; name = Builtins.def; path = clang/AST/Builtins.def; sourceTree = "<group>"; tabWidth = 2; };
DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */,
352246E30F5C6BE000D0D279 /* ManagerRegistry.cpp */,
DEF165740F8FB3510098507F /* PCHReader.cpp */,
+ DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */,
DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */,
DEF165700F8FB34D0098507F /* PCHWriter.cpp */,
352246E40F5C6BE000D0D279 /* PlistDiagnostics.cpp */,
DECB6D650F9AE26600F5FBC7 /* JumpDiagnostics.cpp in Sources */,
DECB6F070F9D93A800F5FBC7 /* InitPreprocessor.cpp in Sources */,
DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */,
+ DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
// This file defines the PCHReader class, which reads a precompiled header.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_FRONTEND_PCH_READER_H
#define LLVM_CLANG_FRONTEND_PCH_READER_H
TextDiagnosticBuffer.cpp
TextDiagnosticPrinter.cpp
PCHReader.cpp
+ PCHReaderDecl.cpp
PCHReaderStmt.cpp
PCHWriter.cpp
PlistDiagnostics.cpp
#include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Lex/MacroInfo.h"
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cstdio>
-
using namespace clang;
namespace {
};
}
-//===----------------------------------------------------------------------===//
-// Declaration deserialization
-//===----------------------------------------------------------------------===//
-namespace {
- class VISIBILITY_HIDDEN PCHDeclReader
- : public DeclVisitor<PCHDeclReader, void> {
- PCHReader &Reader;
- const PCHReader::RecordData &Record;
- unsigned &Idx;
-
- public:
- PCHDeclReader(PCHReader &Reader, const PCHReader::RecordData &Record,
- unsigned &Idx)
- : Reader(Reader), Record(Record), Idx(Idx) { }
-
- void VisitDecl(Decl *D);
- void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
- void VisitNamedDecl(NamedDecl *ND);
- void VisitTypeDecl(TypeDecl *TD);
- void VisitTypedefDecl(TypedefDecl *TD);
- void VisitTagDecl(TagDecl *TD);
- void VisitEnumDecl(EnumDecl *ED);
- void VisitRecordDecl(RecordDecl *RD);
- void VisitValueDecl(ValueDecl *VD);
- void VisitEnumConstantDecl(EnumConstantDecl *ECD);
- void VisitFunctionDecl(FunctionDecl *FD);
- void VisitFieldDecl(FieldDecl *FD);
- void VisitVarDecl(VarDecl *VD);
- void VisitImplicitParamDecl(ImplicitParamDecl *PD);
- void VisitParmVarDecl(ParmVarDecl *PD);
- void VisitOriginalParmVarDecl(OriginalParmVarDecl *PD);
- void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
- void VisitBlockDecl(BlockDecl *BD);
- std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
- void VisitObjCMethodDecl(ObjCMethodDecl *D);
- void VisitObjCContainerDecl(ObjCContainerDecl *D);
- void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
- void VisitObjCIvarDecl(ObjCIvarDecl *D);
- void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
- void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
- void VisitObjCClassDecl(ObjCClassDecl *D);
- void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *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 PCHDeclReader::VisitDecl(Decl *D) {
- D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
- D->setLexicalDeclContext(
- cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
- D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
- D->setInvalidDecl(Record[Idx++]);
- if (Record[Idx++])
- D->addAttr(Reader.ReadAttributes());
- D->setImplicit(Record[Idx++]);
- D->setAccess((AccessSpecifier)Record[Idx++]);
-}
-
-void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
- VisitDecl(TU);
-}
-
-void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
- VisitDecl(ND);
- ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
-}
-
-void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
- VisitNamedDecl(TD);
- TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
-}
-
-void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
- // Note that we cannot use VisitTypeDecl here, because we need to
- // set the underlying type of the typedef *before* we try to read
- // the type associated with the TypedefDecl.
- VisitNamedDecl(TD);
- TD->setUnderlyingType(Reader.GetType(Record[Idx + 1]));
- TD->setTypeForDecl(Reader.GetType(Record[Idx]).getTypePtr());
- Idx += 2;
-}
-
-void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
- VisitTypeDecl(TD);
- TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
- TD->setDefinition(Record[Idx++]);
- TD->setTypedefForAnonDecl(
- cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
-}
-
-void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
- VisitTagDecl(ED);
- ED->setIntegerType(Reader.GetType(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
- VisitTagDecl(RD);
- RD->setHasFlexibleArrayMember(Record[Idx++]);
- RD->setAnonymousStructOrUnion(Record[Idx++]);
-}
-
-void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
- VisitNamedDecl(VD);
- VD->setType(Reader.GetType(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
- VisitValueDecl(ECD);
- if (Record[Idx++])
- ECD->setInitExpr(Reader.ReadExpr());
- ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
-}
-
-void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
- VisitValueDecl(FD);
- if (Record[Idx++])
- FD->setLazyBody(Reader.getStream().GetCurrentBitNo());
- FD->setPreviousDeclaration(
- cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
- FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
- FD->setInline(Record[Idx++]);
- FD->setC99InlineDefinition(Record[Idx++]);
- FD->setVirtual(Record[Idx++]);
- FD->setPure(Record[Idx++]);
- FD->setInheritedPrototype(Record[Idx++]);
- FD->setHasPrototype(Record[Idx++]);
- FD->setDeleted(Record[Idx++]);
- FD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- unsigned NumParams = Record[Idx++];
- llvm::SmallVector<ParmVarDecl *, 16> Params;
- Params.reserve(NumParams);
- for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- FD->setParams(Reader.getContext(), &Params[0], NumParams);
-}
-
-void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
- VisitNamedDecl(MD);
- if (Record[Idx++]) {
- // In practice, this won't be executed (since method definitions
- // don't occur in header files).
- MD->setBody(cast<CompoundStmt>(Reader.ReadStmt()));
- MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
- MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
- }
- MD->setInstanceMethod(Record[Idx++]);
- MD->setVariadic(Record[Idx++]);
- MD->setSynthesized(Record[Idx++]);
- MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
- MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
- MD->setResultType(Reader.GetType(Record[Idx++]));
- MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- unsigned NumParams = Record[Idx++];
- llvm::SmallVector<ParmVarDecl *, 16> Params;
- Params.reserve(NumParams);
- for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- MD->setMethodParams(Reader.getContext(), &Params[0], NumParams);
-}
-
-void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
- VisitNamedDecl(CD);
- CD->setAtEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
- VisitObjCContainerDecl(ID);
- ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
- ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
- (Reader.GetDecl(Record[Idx++])));
- unsigned NumProtocols = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> Protocols;
- Protocols.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setProtocolList(&Protocols[0], NumProtocols, Reader.getContext());
- unsigned NumIvars = Record[Idx++];
- llvm::SmallVector<ObjCIvarDecl *, 16> IVars;
- IVars.reserve(NumIvars);
- for (unsigned I = 0; I != NumIvars; ++I)
- IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setIVarList(&IVars[0], NumIvars, Reader.getContext());
- ID->setCategoryList(
- cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setForwardDecl(Record[Idx++]);
- ID->setImplicitInterfaceDecl(Record[Idx++]);
- ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- ID->setAtEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
- VisitFieldDecl(IVD);
- IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
-}
-
-void PCHDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
- VisitObjCContainerDecl(PD);
- PD->setForwardDecl(Record[Idx++]);
- PD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
- unsigned NumProtoRefs = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
- ProtoRefs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- PD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
-}
-
-void PCHDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
- VisitFieldDecl(FD);
-}
-
-void PCHDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
- VisitDecl(CD);
- unsigned NumClassRefs = Record[Idx++];
- llvm::SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
- ClassRefs.reserve(NumClassRefs);
- for (unsigned I = 0; I != NumClassRefs; ++I)
- ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
- CD->setClassList(Reader.getContext(), &ClassRefs[0], NumClassRefs);
-}
-
-void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
- VisitDecl(FPD);
- unsigned NumProtoRefs = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
- ProtoRefs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- FPD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
-}
-
-void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
- VisitObjCContainerDecl(CD);
- CD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
- unsigned NumProtoRefs = Record[Idx++];
- llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
- ProtoRefs.reserve(NumProtoRefs);
- for (unsigned I = 0; I != NumProtoRefs; ++I)
- ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
- CD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
- CD->setNextClassCategory(cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
- CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
- VisitNamedDecl(CAD);
- CAD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
-}
-
-void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
- VisitNamedDecl(D);
- D->setType(Reader.GetType(Record[Idx++]));
- // FIXME: stable encoding
- D->setPropertyAttributes(
- (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
- // FIXME: stable encoding
- D->setPropertyImplementation(
- (ObjCPropertyDecl::PropertyControl)Record[Idx++]);
- D->setGetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
- D->setSetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
- D->setGetterMethodDecl(
- cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
- D->setSetterMethodDecl(
- cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
- D->setPropertyIvarDecl(
- cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
-}
-
-void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
- VisitNamedDecl(D);
- D->setClassInterface(
- cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
- D->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
- VisitObjCImplDecl(D);
- D->setIdentifier(Reader.GetIdentifierInfo(Record, Idx));
-}
-
-void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
- VisitObjCImplDecl(D);
- D->setSuperClass(
- cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
-}
-
-
-void PCHDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
- VisitDecl(D);
- D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- D->setPropertyDecl(
- cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
- D->setPropertyIvarDecl(
- cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
-}
-
-void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
- VisitValueDecl(FD);
- FD->setMutable(Record[Idx++]);
- if (Record[Idx++])
- FD->setBitWidth(Reader.ReadExpr());
-}
-
-void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
- VisitValueDecl(VD);
- VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
- VD->setThreadSpecified(Record[Idx++]);
- VD->setCXXDirectInitializer(Record[Idx++]);
- VD->setDeclaredInCondition(Record[Idx++]);
- VD->setPreviousDeclaration(
- cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
- VD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- if (Record[Idx++])
- VD->setInit(Reader.ReadExpr());
-}
-
-void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
- VisitVarDecl(PD);
-}
-
-void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
- VisitVarDecl(PD);
- PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
- // FIXME: default argument (C++ only)
-}
-
-void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) {
- VisitParmVarDecl(PD);
- PD->setOriginalType(Reader.GetType(Record[Idx++]));
-}
-
-void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
- VisitDecl(AD);
- AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr()));
-}
-
-void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
- VisitDecl(BD);
- BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt()));
- unsigned NumParams = Record[Idx++];
- llvm::SmallVector<ParmVarDecl *, 16> Params;
- Params.reserve(NumParams);
- for (unsigned I = 0; I != NumParams; ++I)
- Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- BD->setParams(Reader.getContext(), &Params[0], NumParams);
-}
-
-std::pair<uint64_t, uint64_t>
-PCHDeclReader::VisitDeclContext(DeclContext *DC) {
- uint64_t LexicalOffset = Record[Idx++];
- uint64_t VisibleOffset = Record[Idx++];
- return std::make_pair(LexicalOffset, VisibleOffset);
-}
-
-
//===----------------------------------------------------------------------===//
// PCH reader implementation
//===----------------------------------------------------------------------===//
return QualType();
}
-/// \brief 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 PCHReader::LoadedDecl(unsigned Index, Decl *D) {
- assert(!DeclsLoaded[Index] && "Decl loaded twice?");
- DeclsLoaded[Index] = D;
-}
-
-/// \brief 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(Decl *D) {
- if (VarDecl *Var = dyn_cast<VarDecl>(D))
- return Var->isFileVarDecl() && Var->getInit();
- if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
- return Func->isThisDeclarationADefinition();
- return isa<ObjCProtocolDecl>(D);
-}
-
-/// \brief Read the declaration at the given offset from the PCH file.
-Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
- // Keep track of where we are in the stream, then jump back there
- // after reading this declaration.
- SavedStreamPosition SavedPosition(Stream);
-
- Decl *D = 0;
- Stream.JumpToBit(Offset);
- RecordData Record;
- unsigned Code = Stream.ReadCode();
- unsigned Idx = 0;
- PCHDeclReader Reader(*this, Record, Idx);
-
- switch ((pch::DeclCode)Stream.ReadRecord(Code, Record)) {
- case pch::DECL_ATTR:
- case pch::DECL_CONTEXT_LEXICAL:
- case pch::DECL_CONTEXT_VISIBLE:
- assert(false && "Record cannot be de-serialized with ReadDeclRecord");
- break;
-
- case pch::DECL_TRANSLATION_UNIT:
- assert(Index == 0 && "Translation unit must be at index 0");
- D = Context.getTranslationUnitDecl();
- break;
-
- case pch::DECL_TYPEDEF: {
- D = TypedefDecl::Create(Context, 0, SourceLocation(), 0, QualType());
- break;
- }
-
- case pch::DECL_ENUM: {
- D = EnumDecl::Create(Context, 0, SourceLocation(), 0, 0);
- break;
- }
-
- case pch::DECL_RECORD: {
- D = RecordDecl::Create(Context, TagDecl::TK_struct, 0, SourceLocation(),
- 0, 0);
- break;
- }
-
- case pch::DECL_ENUM_CONSTANT: {
- D = EnumConstantDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
- 0, llvm::APSInt());
- break;
- }
-
- case pch::DECL_FUNCTION: {
- D = FunctionDecl::Create(Context, 0, SourceLocation(), DeclarationName(),
- QualType());
- break;
- }
-
- case pch::DECL_OBJC_METHOD: {
- D = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
- Selector(), QualType(), 0);
- break;
- }
-
- case pch::DECL_OBJC_INTERFACE: {
- D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
- break;
- }
-
- case pch::DECL_OBJC_IVAR: {
- D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
- ObjCIvarDecl::None);
- break;
- }
-
- case pch::DECL_OBJC_PROTOCOL: {
- D = ObjCProtocolDecl::Create(Context, 0, SourceLocation(), 0);
- break;
- }
-
- case pch::DECL_OBJC_AT_DEFS_FIELD: {
- D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(), 0,
- QualType(), 0);
- break;
- }
-
- case pch::DECL_OBJC_CLASS: {
- D = ObjCClassDecl::Create(Context, 0, SourceLocation());
- break;
- }
-
- case pch::DECL_OBJC_FORWARD_PROTOCOL: {
- D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation());
- break;
- }
-
- case pch::DECL_OBJC_CATEGORY: {
- D = ObjCCategoryDecl::Create(Context, 0, SourceLocation(), 0);
- break;
- }
-
- case pch::DECL_OBJC_CATEGORY_IMPL: {
- D = ObjCCategoryImplDecl::Create(Context, 0, SourceLocation(), 0, 0);
- break;
- }
-
- case pch::DECL_OBJC_IMPLEMENTATION: {
- D = ObjCImplementationDecl::Create(Context, 0, SourceLocation(), 0, 0);
- break;
- }
-
- case pch::DECL_OBJC_COMPATIBLE_ALIAS: {
- D = ObjCCompatibleAliasDecl::Create(Context, 0, SourceLocation(), 0, 0);
- break;
- }
-
- case pch::DECL_OBJC_PROPERTY: {
- D = ObjCPropertyDecl::Create(Context, 0, SourceLocation(), 0, QualType());
- break;
- }
-
- case pch::DECL_OBJC_PROPERTY_IMPL: {
- D = ObjCPropertyImplDecl::Create(Context, 0, SourceLocation(),
- SourceLocation(), 0,
- ObjCPropertyImplDecl::Dynamic, 0);
- break;
- }
-
- case pch::DECL_FIELD: {
- D = FieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 0,
- false);
- break;
- }
-
- case pch::DECL_VAR:
- D = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
- VarDecl::None, SourceLocation());
- break;
-
- case pch::DECL_IMPLICIT_PARAM:
- D = ImplicitParamDecl::Create(Context, 0, SourceLocation(), 0, QualType());
- break;
-
- case pch::DECL_PARM_VAR: {
- D = ParmVarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
- VarDecl::None, 0);
- break;
- }
-
- case pch::DECL_ORIGINAL_PARM_VAR: {
- D = OriginalParmVarDecl::Create(Context, 0, SourceLocation(), 0,
- QualType(), QualType(), VarDecl::None,
- 0);
- break;
- }
-
- case pch::DECL_FILE_SCOPE_ASM: {
- D = FileScopeAsmDecl::Create(Context, 0, SourceLocation(), 0);
- break;
- }
-
- case pch::DECL_BLOCK: {
- D = BlockDecl::Create(Context, 0, SourceLocation());
- break;
- }
- }
-
- assert(D && "Unknown declaration reading PCH file");
- if (D) {
- LoadedDecl(Index, D);
- Reader.Visit(D);
- }
-
- // If this declaration is also a declaration context, get the
- // offsets for its tables of lexical and visible declarations.
- if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
- std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
- if (Offsets.first || Offsets.second) {
- DC->setHasExternalLexicalStorage(Offsets.first != 0);
- DC->setHasExternalVisibleStorage(Offsets.second != 0);
- DeclContextOffsets[DC] = Offsets;
- }
- }
- assert(Idx == Record.size());
-
- // If we have deserialized a declaration that has a definition the
- // AST consumer might need to know about, notify the consumer
- // about that definition now or queue it for later.
- if (isConsumerInterestedIn(D)) {
- if (Consumer) {
- DeclGroupRef DG(D);
- Consumer->HandleTopLevelDecl(DG);
- } else {
- InterestingDecls.push_back(D);
- }
- }
-
- return D;
-}
QualType PCHReader::GetType(pch::TypeID ID) {
unsigned Quals = ID & 0x07;
--- /dev/null
+//===--- PCHReaderDecl.cpp - Decl Deserialization ---------------*- 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 PCHReader::ReadDeclRecord method, which is the
+// entrypoint for loading a decl.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHReader.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/Expr.h"
+using namespace clang;
+
+// FIXME: Temporarily cloned from PCHReader.cpp.
+namespace {
+ /// \brief Helper class that saves the current stream position and
+ /// then restores it when destroyed.
+ struct SavedStreamPosition {
+ explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
+ : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+
+ ~SavedStreamPosition() {
+ Cursor.JumpToBit(Offset);
+ }
+
+ private:
+ llvm::BitstreamCursor &Cursor;
+ uint64_t Offset;
+ };
+}
+
+
+//===----------------------------------------------------------------------===//
+// Declaration deserialization
+//===----------------------------------------------------------------------===//
+
+namespace {
+ class PCHDeclReader : public DeclVisitor<PCHDeclReader, void> {
+ PCHReader &Reader;
+ const PCHReader::RecordData &Record;
+ unsigned &Idx;
+
+ public:
+ PCHDeclReader(PCHReader &Reader, const PCHReader::RecordData &Record,
+ unsigned &Idx)
+ : Reader(Reader), Record(Record), Idx(Idx) { }
+
+ void VisitDecl(Decl *D);
+ void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+ void VisitNamedDecl(NamedDecl *ND);
+ void VisitTypeDecl(TypeDecl *TD);
+ void VisitTypedefDecl(TypedefDecl *TD);
+ void VisitTagDecl(TagDecl *TD);
+ void VisitEnumDecl(EnumDecl *ED);
+ void VisitRecordDecl(RecordDecl *RD);
+ void VisitValueDecl(ValueDecl *VD);
+ void VisitEnumConstantDecl(EnumConstantDecl *ECD);
+ void VisitFunctionDecl(FunctionDecl *FD);
+ void VisitFieldDecl(FieldDecl *FD);
+ void VisitVarDecl(VarDecl *VD);
+ void VisitImplicitParamDecl(ImplicitParamDecl *PD);
+ void VisitParmVarDecl(ParmVarDecl *PD);
+ void VisitOriginalParmVarDecl(OriginalParmVarDecl *PD);
+ void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
+ void VisitBlockDecl(BlockDecl *BD);
+ std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
+ void VisitObjCMethodDecl(ObjCMethodDecl *D);
+ void VisitObjCContainerDecl(ObjCContainerDecl *D);
+ void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+ void VisitObjCIvarDecl(ObjCIvarDecl *D);
+ void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+ void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
+ void VisitObjCClassDecl(ObjCClassDecl *D);
+ void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *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 PCHDeclReader::VisitDecl(Decl *D) {
+ D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
+ D->setLexicalDeclContext(
+ cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
+ D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ D->setInvalidDecl(Record[Idx++]);
+ if (Record[Idx++])
+ D->addAttr(Reader.ReadAttributes());
+ D->setImplicit(Record[Idx++]);
+ D->setAccess((AccessSpecifier)Record[Idx++]);
+}
+
+void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+ VisitDecl(TU);
+}
+
+void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
+ VisitDecl(ND);
+ ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
+}
+
+void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
+ VisitNamedDecl(TD);
+ TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+}
+
+void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
+ // Note that we cannot use VisitTypeDecl here, because we need to
+ // set the underlying type of the typedef *before* we try to read
+ // the type associated with the TypedefDecl.
+ VisitNamedDecl(TD);
+ TD->setUnderlyingType(Reader.GetType(Record[Idx + 1]));
+ TD->setTypeForDecl(Reader.GetType(Record[Idx]).getTypePtr());
+ Idx += 2;
+}
+
+void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
+ VisitTypeDecl(TD);
+ TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
+ TD->setDefinition(Record[Idx++]);
+ TD->setTypedefForAnonDecl(
+ cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
+ VisitTagDecl(ED);
+ ED->setIntegerType(Reader.GetType(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
+ VisitTagDecl(RD);
+ RD->setHasFlexibleArrayMember(Record[Idx++]);
+ RD->setAnonymousStructOrUnion(Record[Idx++]);
+}
+
+void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
+ VisitNamedDecl(VD);
+ VD->setType(Reader.GetType(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
+ VisitValueDecl(ECD);
+ if (Record[Idx++])
+ ECD->setInitExpr(Reader.ReadExpr());
+ ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
+}
+
+void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
+ VisitValueDecl(FD);
+ if (Record[Idx++])
+ FD->setLazyBody(Reader.getStream().GetCurrentBitNo());
+ FD->setPreviousDeclaration(
+ cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
+ FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
+ FD->setInline(Record[Idx++]);
+ FD->setC99InlineDefinition(Record[Idx++]);
+ FD->setVirtual(Record[Idx++]);
+ FD->setPure(Record[Idx++]);
+ FD->setInheritedPrototype(Record[Idx++]);
+ FD->setHasPrototype(Record[Idx++]);
+ FD->setDeleted(Record[Idx++]);
+ FD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ unsigned NumParams = Record[Idx++];
+ llvm::SmallVector<ParmVarDecl *, 16> Params;
+ Params.reserve(NumParams);
+ for (unsigned I = 0; I != NumParams; ++I)
+ Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+ FD->setParams(Reader.getContext(), &Params[0], NumParams);
+}
+
+void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+ VisitNamedDecl(MD);
+ if (Record[Idx++]) {
+ // In practice, this won't be executed (since method definitions
+ // don't occur in header files).
+ MD->setBody(Reader.ReadStmt());
+ MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
+ MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));
+ }
+ MD->setInstanceMethod(Record[Idx++]);
+ MD->setVariadic(Record[Idx++]);
+ MD->setSynthesized(Record[Idx++]);
+ MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
+ MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+ MD->setResultType(Reader.GetType(Record[Idx++]));
+ MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ unsigned NumParams = Record[Idx++];
+ llvm::SmallVector<ParmVarDecl *, 16> Params;
+ Params.reserve(NumParams);
+ for (unsigned I = 0; I != NumParams; ++I)
+ Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+ MD->setMethodParams(Reader.getContext(), &Params[0], NumParams);
+}
+
+void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
+ VisitNamedDecl(CD);
+ CD->setAtEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
+ VisitObjCContainerDecl(ID);
+ ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
+ ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
+ (Reader.GetDecl(Record[Idx++])));
+ unsigned NumProtocols = Record[Idx++];
+ llvm::SmallVector<ObjCProtocolDecl *, 16> Protocols;
+ Protocols.reserve(NumProtocols);
+ for (unsigned I = 0; I != NumProtocols; ++I)
+ Protocols.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+ ID->setProtocolList(&Protocols[0], NumProtocols, Reader.getContext());
+ unsigned NumIvars = Record[Idx++];
+ llvm::SmallVector<ObjCIvarDecl *, 16> IVars;
+ IVars.reserve(NumIvars);
+ for (unsigned I = 0; I != NumIvars; ++I)
+ IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+ ID->setIVarList(&IVars[0], NumIvars, Reader.getContext());
+ ID->setCategoryList(
+ cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+ ID->setForwardDecl(Record[Idx++]);
+ ID->setImplicitInterfaceDecl(Record[Idx++]);
+ ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ ID->setAtEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
+ VisitFieldDecl(IVD);
+ IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
+}
+
+void PCHDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
+ VisitObjCContainerDecl(PD);
+ PD->setForwardDecl(Record[Idx++]);
+ PD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ unsigned NumProtoRefs = Record[Idx++];
+ llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+ ProtoRefs.reserve(NumProtoRefs);
+ for (unsigned I = 0; I != NumProtoRefs; ++I)
+ ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+ PD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
+}
+
+void PCHDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
+ VisitFieldDecl(FD);
+}
+
+void PCHDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
+ VisitDecl(CD);
+ unsigned NumClassRefs = Record[Idx++];
+ llvm::SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
+ ClassRefs.reserve(NumClassRefs);
+ for (unsigned I = 0; I != NumClassRefs; ++I)
+ ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ CD->setClassList(Reader.getContext(), &ClassRefs[0], NumClassRefs);
+}
+
+void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
+ VisitDecl(FPD);
+ unsigned NumProtoRefs = Record[Idx++];
+ llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+ ProtoRefs.reserve(NumProtoRefs);
+ for (unsigned I = 0; I != NumProtoRefs; ++I)
+ ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+ FPD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
+}
+
+void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
+ VisitObjCContainerDecl(CD);
+ CD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ unsigned NumProtoRefs = Record[Idx++];
+ llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+ ProtoRefs.reserve(NumProtoRefs);
+ for (unsigned I = 0; I != NumProtoRefs; ++I)
+ ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+ CD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
+ CD->setNextClassCategory(cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+ CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
+ VisitNamedDecl(CAD);
+ CAD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ VisitNamedDecl(D);
+ D->setType(Reader.GetType(Record[Idx++]));
+ // FIXME: stable encoding
+ D->setPropertyAttributes(
+ (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+ // FIXME: stable encoding
+ D->setPropertyImplementation(
+ (ObjCPropertyDecl::PropertyControl)Record[Idx++]);
+ D->setGetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
+ D->setSetterName(Reader.ReadDeclarationName(Record, Idx).getObjCSelector());
+ D->setGetterMethodDecl(
+ cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setSetterMethodDecl(
+ cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setPropertyIvarDecl(
+ cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
+ VisitNamedDecl(D);
+ D->setClassInterface(
+ cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ VisitObjCImplDecl(D);
+ D->setIdentifier(Reader.GetIdentifierInfo(Record, Idx));
+}
+
+void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ VisitObjCImplDecl(D);
+ D->setSuperClass(
+ cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+
+void PCHDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+ VisitDecl(D);
+ D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ D->setPropertyDecl(
+ cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setPropertyIvarDecl(
+ cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
+ VisitValueDecl(FD);
+ FD->setMutable(Record[Idx++]);
+ if (Record[Idx++])
+ FD->setBitWidth(Reader.ReadExpr());
+}
+
+void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
+ VisitValueDecl(VD);
+ VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
+ VD->setThreadSpecified(Record[Idx++]);
+ VD->setCXXDirectInitializer(Record[Idx++]);
+ VD->setDeclaredInCondition(Record[Idx++]);
+ VD->setPreviousDeclaration(
+ cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
+ VD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ if (Record[Idx++])
+ VD->setInit(Reader.ReadExpr());
+}
+
+void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
+ VisitVarDecl(PD);
+}
+
+void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
+ VisitVarDecl(PD);
+ PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+ // FIXME: default argument (C++ only)
+}
+
+void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) {
+ VisitParmVarDecl(PD);
+ PD->setOriginalType(Reader.GetType(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
+ VisitDecl(AD);
+ AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr()));
+}
+
+void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
+ VisitDecl(BD);
+ BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt()));
+ unsigned NumParams = Record[Idx++];
+ llvm::SmallVector<ParmVarDecl *, 16> Params;
+ Params.reserve(NumParams);
+ for (unsigned I = 0; I != NumParams; ++I)
+ Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+ BD->setParams(Reader.getContext(), &Params[0], NumParams);
+}
+
+std::pair<uint64_t, uint64_t>
+PCHDeclReader::VisitDeclContext(DeclContext *DC) {
+ uint64_t LexicalOffset = Record[Idx++];
+ uint64_t VisibleOffset = Record[Idx++];
+ return std::make_pair(LexicalOffset, VisibleOffset);
+}
+
+//===----------------------------------------------------------------------===//
+// PCHReader Implementation
+//===----------------------------------------------------------------------===//
+
+
+/// \brief 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 PCHReader::LoadedDecl(unsigned Index, Decl *D) {
+ assert(!DeclsLoaded[Index] && "Decl loaded twice?");
+ DeclsLoaded[Index] = D;
+}
+
+
+/// \brief 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(Decl *D) {
+ if (VarDecl *Var = dyn_cast<VarDecl>(D))
+ return Var->isFileVarDecl() && Var->getInit();
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
+ return Func->isThisDeclarationADefinition();
+ return isa<ObjCProtocolDecl>(D);
+}
+
+/// \brief Read the declaration at the given offset from the PCH file.
+Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
+ // Keep track of where we are in the stream, then jump back there
+ // after reading this declaration.
+ SavedStreamPosition SavedPosition(Stream);
+
+ Decl *D = 0;
+ Stream.JumpToBit(Offset);
+ RecordData Record;
+ unsigned Code = Stream.ReadCode();
+ unsigned Idx = 0;
+ PCHDeclReader Reader(*this, Record, Idx);
+
+ switch ((pch::DeclCode)Stream.ReadRecord(Code, Record)) {
+ case pch::DECL_ATTR:
+ case pch::DECL_CONTEXT_LEXICAL:
+ case pch::DECL_CONTEXT_VISIBLE:
+ assert(false && "Record cannot be de-serialized with ReadDeclRecord");
+ break;
+
+ case pch::DECL_TRANSLATION_UNIT:
+ assert(Index == 0 && "Translation unit must be at index 0");
+ D = Context.getTranslationUnitDecl();
+ break;
+
+ case pch::DECL_TYPEDEF: {
+ D = TypedefDecl::Create(Context, 0, SourceLocation(), 0, QualType());
+ break;
+ }
+
+ case pch::DECL_ENUM: {
+ D = EnumDecl::Create(Context, 0, SourceLocation(), 0, 0);
+ break;
+ }
+
+ case pch::DECL_RECORD: {
+ D = RecordDecl::Create(Context, TagDecl::TK_struct, 0, SourceLocation(),
+ 0, 0);
+ break;
+ }
+
+ case pch::DECL_ENUM_CONSTANT: {
+ D = EnumConstantDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
+ 0, llvm::APSInt());
+ break;
+ }
+
+ case pch::DECL_FUNCTION: {
+ D = FunctionDecl::Create(Context, 0, SourceLocation(), DeclarationName(),
+ QualType());
+ break;
+ }
+
+ case pch::DECL_OBJC_METHOD: {
+ D = ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
+ Selector(), QualType(), 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_INTERFACE: {
+ D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_IVAR: {
+ D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
+ ObjCIvarDecl::None);
+ break;
+ }
+
+ case pch::DECL_OBJC_PROTOCOL: {
+ D = ObjCProtocolDecl::Create(Context, 0, SourceLocation(), 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_AT_DEFS_FIELD: {
+ D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(), 0,
+ QualType(), 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_CLASS: {
+ D = ObjCClassDecl::Create(Context, 0, SourceLocation());
+ break;
+ }
+
+ case pch::DECL_OBJC_FORWARD_PROTOCOL: {
+ D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation());
+ break;
+ }
+
+ case pch::DECL_OBJC_CATEGORY: {
+ D = ObjCCategoryDecl::Create(Context, 0, SourceLocation(), 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_CATEGORY_IMPL: {
+ D = ObjCCategoryImplDecl::Create(Context, 0, SourceLocation(), 0, 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_IMPLEMENTATION: {
+ D = ObjCImplementationDecl::Create(Context, 0, SourceLocation(), 0, 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_COMPATIBLE_ALIAS: {
+ D = ObjCCompatibleAliasDecl::Create(Context, 0, SourceLocation(), 0, 0);
+ break;
+ }
+
+ case pch::DECL_OBJC_PROPERTY: {
+ D = ObjCPropertyDecl::Create(Context, 0, SourceLocation(), 0, QualType());
+ break;
+ }
+
+ case pch::DECL_OBJC_PROPERTY_IMPL: {
+ D = ObjCPropertyImplDecl::Create(Context, 0, SourceLocation(),
+ SourceLocation(), 0,
+ ObjCPropertyImplDecl::Dynamic, 0);
+ break;
+ }
+
+ case pch::DECL_FIELD: {
+ D = FieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 0,
+ false);
+ break;
+ }
+
+ case pch::DECL_VAR:
+ D = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
+ VarDecl::None, SourceLocation());
+ break;
+
+ case pch::DECL_IMPLICIT_PARAM:
+ D = ImplicitParamDecl::Create(Context, 0, SourceLocation(), 0, QualType());
+ break;
+
+ case pch::DECL_PARM_VAR: {
+ D = ParmVarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
+ VarDecl::None, 0);
+ break;
+ }
+
+ case pch::DECL_ORIGINAL_PARM_VAR: {
+ D = OriginalParmVarDecl::Create(Context, 0, SourceLocation(), 0,
+ QualType(), QualType(), VarDecl::None,
+ 0);
+ break;
+ }
+
+ case pch::DECL_FILE_SCOPE_ASM: {
+ D = FileScopeAsmDecl::Create(Context, 0, SourceLocation(), 0);
+ break;
+ }
+
+ case pch::DECL_BLOCK: {
+ D = BlockDecl::Create(Context, 0, SourceLocation());
+ break;
+ }
+ }
+
+ assert(D && "Unknown declaration reading PCH file");
+ if (D) {
+ LoadedDecl(Index, D);
+ Reader.Visit(D);
+ }
+
+ // If this declaration is also a declaration context, get the
+ // offsets for its tables of lexical and visible declarations.
+ if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+ std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
+ if (Offsets.first || Offsets.second) {
+ DC->setHasExternalLexicalStorage(Offsets.first != 0);
+ DC->setHasExternalVisibleStorage(Offsets.second != 0);
+ DeclContextOffsets[DC] = Offsets;
+ }
+ }
+ assert(Idx == Record.size());
+
+ // If we have deserialized a declaration that has a definition the
+ // AST consumer might need to know about, notify the consumer
+ // about that definition now or queue it for later.
+ if (isConsumerInterestedIn(D)) {
+ if (Consumer) {
+ DeclGroupRef DG(D);
+ Consumer->HandleTopLevelDecl(DG);
+ } else {
+ InterestingDecls.push_back(D);
+ }
+ }
+
+ return D;
+}
+