diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 6 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 70 |
2 files changed, 69 insertions, 7 deletions
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()); |