diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 41d9065bf0..3dfe6658ca 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -175,6 +175,7 @@ DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */; }; DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */; }; DECB77F70FA5850200F5FBC7 /* PCHWriterDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */; }; + DECB78170FA5882F00F5FBC7 /* PCHWriterStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.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 */; }; @@ -589,6 +590,8 @@ DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderStmt.cpp; path = lib/Frontend/PCHReaderStmt.cpp; sourceTree = ""; }; DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderDecl.cpp; path = lib/Frontend/PCHReaderDecl.cpp; sourceTree = ""; }; DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriterDecl.cpp; path = lib/Frontend/PCHWriterDecl.cpp; sourceTree = ""; }; + DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriterStmt.cpp; path = lib/Frontend/PCHWriterStmt.cpp; sourceTree = ""; }; + DECB78540FA58F5500F5FBC7 /* AccessSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AccessSpecifier.h; path = clang/Parse/AccessSpecifier.h; sourceTree = ""; }; DED626C80AE0C065001E80A4 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TargetInfo.cpp; sourceTree = ""; tabWidth = 2; }; DED62ABA0AE2EDF1001E80A4 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Decl.cpp; path = lib/AST/Decl.cpp; sourceTree = ""; tabWidth = 2; usesTabs = 0; }; DED676D00B6C786700AAD4A3 /* Builtins.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; name = Builtins.def; path = clang/AST/Builtins.def; sourceTree = ""; tabWidth = 2; }; @@ -818,6 +821,7 @@ DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */, DEF165700F8FB34D0098507F /* PCHWriter.cpp */, DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */, + DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.cpp */, 352246E40F5C6BE000D0D279 /* PlistDiagnostics.cpp */, 352246E50F5C6BE000D0D279 /* TextDiagnosticBuffer.cpp */, 352246E60F5C6BE000D0D279 /* TextDiagnosticPrinter.cpp */, @@ -1105,6 +1109,7 @@ DEC8D98B0A9433BC00353FCA /* AST */ = { isa = PBXGroup; children = ( + DECB78540FA58F5500F5FBC7 /* AccessSpecifier.h */, DE613EF30E0E148D00B05B79 /* APValue.h */, DEC8D9A30A94346E00353FCA /* AST.h */, 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */, @@ -1673,6 +1678,7 @@ DECB77130FA5752300F5FBC7 /* PCHReaderStmt.cpp in Sources */, DECB77790FA579B000F5FBC7 /* PCHReaderDecl.cpp in Sources */, DECB77F70FA5850200F5FBC7 /* PCHWriterDecl.cpp in Sources */, + DECB78170FA5882F00F5FBC7 /* PCHWriterStmt.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 1aabf7d3e6..9cd22eeb3b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -285,7 +285,7 @@ public: /// variable. const VarDecl *getPreviousDeclaration() const { return PreviousDeclaration; } - void setPreviousDeclaration(VarDecl * PrevDecl) { + void setPreviousDeclaration(VarDecl *PrevDecl) { PreviousDeclaration = PrevDecl; } diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index b2ce43acd3..4d1262223e 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -168,11 +168,15 @@ private: void WriteTypesBlock(ASTContext &Context); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); + void WriteDeclsBlock(ASTContext &Context); void WriteMethodPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP); void WriteAttributeRecord(const Attr *Attr); + unsigned ParmVarDeclAbbrev; + void WriteDeclsBlockAbbrevs(); + public: /// \brief Create a new precompiled header writer that outputs to /// the given bitstream. @@ -264,6 +268,7 @@ public: /// or may not have been emitted yet. unsigned GetLabelID(LabelStmt *S); + unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; } }; } // end namespace clang diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index d181013a37..bb72f78546 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -18,7 +18,6 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclContextInternals.h" #include "clang/AST/Expr.h" -#include "clang/AST/StmtVisitor.h" #include "clang/AST/Type.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" @@ -484,8 +483,8 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.Freestanding); // Freestanding implementation Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin) - Record.push_back(LangOpts.ThreadsafeStatics); // Whether static initializers are protected - // by locks. + // Whether static initializers are protected by locks. + Record.push_back(LangOpts.ThreadsafeStatics); Record.push_back(LangOpts.Blocks); // block extension to C Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if // they are unused. @@ -1737,6 +1736,7 @@ pch::DeclID PCHWriter::getDeclID(const Decl *D) { } void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) { + // FIXME: Emit a stable enum for NameKind. 0 = Identifier etc. Record.push_back(Name.getNameKind()); switch (Name.getNameKind()) { case DeclarationName::Identifier: diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index e2cf3d8ce5..799c77b03f 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -30,10 +30,12 @@ namespace { public: pch::DeclCode Code; + unsigned AbbrevToUse; PCHDeclWriter(PCHWriter &Writer, ASTContext &Context, PCHWriter::RecordData &Record) - : Writer(Writer), Context(Context), Record(Record) { } + : Writer(Writer), Context(Context), Record(Record) { + } void VisitDecl(Decl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *D); @@ -349,12 +351,34 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // FIXME: why isn't the "default argument" just stored as the initializer // in VarDecl? Code = pch::DECL_PARM_VAR; + + + // If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here + // we dynamically check for the properties that we optimize for, but don't + // know are true of all PARM_VAR_DECLs. + if (!D->hasAttrs() && + !D->isImplicit() && + D->getAccess() == AS_none && + D->getStorageClass() == 0 && + !D->hasCXXDirectInitializer() && // Can params have this ever? + D->getObjCDeclQualifier() == 0) + AbbrevToUse = Writer.getParmVarDeclAbbrev(); + + // Check things we know are true of *every* PARM_VAR_DECL, which is more than + // just us assuming it. + assert(!D->isInvalidDecl() && "Shouldn't emit invalid decls"); + assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread"); + assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private"); + assert(!D->isDeclaredInCondition() && "PARM_VAR_DECL can't be in condition"); + assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl"); + assert(D->getInit() == 0 && "PARM_VAR_DECL never has init"); } void PCHDeclWriter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) { VisitParmVarDecl(D); Writer.AddTypeRef(D->getOriginalType(), Record); Code = pch::DECL_ORIGINAL_PARM_VAR; + AbbrevToUse = 0; } void PCHDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { @@ -395,11 +419,48 @@ void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, // PCHWriter Implementation //===----------------------------------------------------------------------===// +void PCHWriter::WriteDeclsBlockAbbrevs() { + using namespace llvm; + // Abbreviation for DECL_PARM_VAR. + BitCodeAbbrev *Abv = new BitCodeAbbrev(); + Abv->Add(BitCodeAbbrevOp(pch::DECL_PARM_VAR)); + + // Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location + Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl (!?) + Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs + Abv->Add(BitCodeAbbrevOp(0)); // isImplicit + Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier + + // NamedDecl + Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + // ValueDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // VarDecl + Abv->Add(BitCodeAbbrevOp(0)); // StorageClass + Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified + Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer + Abv->Add(BitCodeAbbrevOp(0)); // isDeclaredInCondition + Abv->Add(BitCodeAbbrevOp(0)); // PrevDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeSpecStartLoc + Abv->Add(BitCodeAbbrevOp(0)); // HasInit + // ParmVarDecl + Abv->Add(BitCodeAbbrevOp(0)); // ObjCDeclQualifier + + ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv); +} + /// \brief Write a block containing all of the declarations. void PCHWriter::WriteDeclsBlock(ASTContext &Context) { // Enter the declarations block. - Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 2); + Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 3); + // Output the abbreviations that we will use in this block. + WriteDeclsBlockAbbrevs(); + // Emit all of the declarations. RecordData Record; PCHDeclWriter W(*this, Context, Record); @@ -439,6 +500,7 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) { // Build and emit a record for this declaration Record.clear(); W.Code = (pch::DeclCode)0; + W.AbbrevToUse = 0; W.Visit(D); if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); @@ -448,8 +510,8 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) { assert(false && "Unhandled declaration kind while generating PCH"); exit(-1); } - Stream.EmitRecord(W.Code, Record); - + Stream.EmitRecord(W.Code, Record, W.AbbrevToUse); + // If the declaration had any attributes, write them now. if (D->hasAttrs()) WriteAttributeRecord(D->getAttrs());