diff options
-rw-r--r-- | clang.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | include/clang/Frontend/PCHReader.h | 1 | ||||
-rw-r--r-- | lib/Frontend/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 585 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 628 |
5 files changed, 634 insertions, 585 deletions
diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 5fdfcd6543..a4c31600fc 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -173,6 +173,7 @@ 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 */; }; @@ -585,6 +586,7 @@ 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; }; @@ -810,6 +812,7 @@ DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */, 352246E30F5C6BE000D0D279 /* ManagerRegistry.cpp */, DEF165740F8FB3510098507F /* PCHReader.cpp */, + DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */, DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */, DEF165700F8FB34D0098507F /* PCHWriter.cpp */, 352246E40F5C6BE000D0D279 /* PlistDiagnostics.cpp */, @@ -1665,6 +1668,7 @@ DECB6D650F9AE26600F5FBC7 /* JumpDiagnostics.cpp in Sources */, DECB6F070F9D93A800F5FBC7 /* InitPreprocessor.cpp in Sources */, DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */, + DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 2c10d3c759..eb24a536f3 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -10,6 +10,7 @@ // 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 diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt index c341007c03..1100198c23 100644 --- a/lib/Frontend/CMakeLists.txt +++ b/lib/Frontend/CMakeLists.txt @@ -8,6 +8,7 @@ add_clang_library(clangFrontend TextDiagnosticBuffer.cpp TextDiagnosticPrinter.cpp PCHReader.cpp + PCHReaderDecl.cpp PCHReaderStmt.cpp PCHWriter.cpp PlistDiagnostics.cpp diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 52afd2db72..0eb3128f5b 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -16,9 +16,6 @@ #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" @@ -34,7 +31,6 @@ #include "llvm/Support/MemoryBuffer.h" #include <algorithm> #include <cstdio> - using namespace clang; namespace { @@ -55,368 +51,6 @@ 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 //===----------------------------------------------------------------------===// @@ -1633,225 +1267,6 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { 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; diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp new file mode 100644 index 0000000000..36ec7b9dbf --- /dev/null +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -0,0 +1,628 @@ +//===--- 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); + I |