zcov: / lib/Frontend/PCHWriter.cpp


Files: 1 Branches Taken: 74.3% 298 / 401
Generated: 2010-02-10 01:31 Branches Executed: 98.0% 393 / 401
Line Coverage: 87.9% 1182 / 1344


Programs: 1 Runs 2897


       1                 : //===--- PCHWriter.h - Precompiled Headers Writer ---------------*- C++ -*-===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : //  This file defines the PCHWriter class, which writes a precompiled header.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Frontend/PCHWriter.h"
      15                 : #include "../Sema/Sema.h" // FIXME: move header into include/clang/Sema
      16                 : #include "../Sema/IdentifierResolver.h" // FIXME: move header
      17                 : #include "clang/AST/ASTContext.h"
      18                 : #include "clang/AST/Decl.h"
      19                 : #include "clang/AST/DeclContextInternals.h"
      20                 : #include "clang/AST/Expr.h"
      21                 : #include "clang/AST/Type.h"
      22                 : #include "clang/AST/TypeLocVisitor.h"
      23                 : #include "clang/Lex/MacroInfo.h"
      24                 : #include "clang/Lex/Preprocessor.h"
      25                 : #include "clang/Lex/HeaderSearch.h"
      26                 : #include "clang/Basic/FileManager.h"
      27                 : #include "clang/Basic/OnDiskHashTable.h"
      28                 : #include "clang/Basic/SourceManager.h"
      29                 : #include "clang/Basic/SourceManagerInternals.h"
      30                 : #include "clang/Basic/TargetInfo.h"
      31                 : #include "clang/Basic/Version.h"
      32                 : #include "llvm/ADT/APFloat.h"
      33                 : #include "llvm/ADT/APInt.h"
      34                 : #include "llvm/ADT/StringExtras.h"
      35                 : #include "llvm/Bitcode/BitstreamWriter.h"
      36                 : #include "llvm/Support/MemoryBuffer.h"
      37                 : #include "llvm/System/Path.h"
      38                 : #include <cstdio>
      39                 : using namespace clang;
      40                 : 
      41                 : //===----------------------------------------------------------------------===//
      42                 : // Type serialization
      43                 : //===----------------------------------------------------------------------===//
      44                 : 
      45                 : namespace {
      46                 :   class PCHTypeWriter {
      47                 :     PCHWriter &Writer;
      48                 :     PCHWriter::RecordData &Record;
      49                 : 
      50                 :   public:
      51                 :     /// \brief Type code that corresponds to the record generated.
      52                 :     pch::TypeCode Code;
      53                 : 
      54              373:     PCHTypeWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
      55              373:       : Writer(Writer), Record(Record), Code(pch::TYPE_EXT_QUAL) { }
      56                 : 
      57                 :     void VisitArrayType(const ArrayType *T);
      58                 :     void VisitFunctionType(const FunctionType *T);
      59                 :     void VisitTagType(const TagType *T);
      60                 : 
      61                 : #define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T);
      62                 : #define ABSTRACT_TYPE(Class, Base)
      63                 : #define DEPENDENT_TYPE(Class, Base)
      64                 : #include "clang/AST/TypeNodes.def"
      65                 :   };
      66                 : }
      67                 : 
      68                0: void PCHTypeWriter::VisitBuiltinType(const BuiltinType *T) {
      69                0:   assert(false && "Built-in types are never serialized");
      70                 : }
      71                 : 
      72                2: void PCHTypeWriter::VisitComplexType(const ComplexType *T) {
      73                2:   Writer.AddTypeRef(T->getElementType(), Record);
      74                2:   Code = pch::TYPE_COMPLEX;
      75                2: }
      76                 : 
      77              100: void PCHTypeWriter::VisitPointerType(const PointerType *T) {
      78              100:   Writer.AddTypeRef(T->getPointeeType(), Record);
      79              100:   Code = pch::TYPE_POINTER;
      80              100: }
      81                 : 
      82                2: void PCHTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
      83                2:   Writer.AddTypeRef(T->getPointeeType(), Record);
      84                2:   Code = pch::TYPE_BLOCK_POINTER;
      85                2: }
      86                 : 
      87                8: void PCHTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
      88                8:   Writer.AddTypeRef(T->getPointeeType(), Record);
      89                8:   Code = pch::TYPE_LVALUE_REFERENCE;
      90                8: }
      91                 : 
      92                0: void PCHTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
      93                0:   Writer.AddTypeRef(T->getPointeeType(), Record);
      94                0:   Code = pch::TYPE_RVALUE_REFERENCE;
      95                0: }
      96                 : 
      97                0: void PCHTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
      98                0:   Writer.AddTypeRef(T->getPointeeType(), Record);
      99                0:   Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
     100                0:   Code = pch::TYPE_MEMBER_POINTER;
     101                0: }
     102                 : 
     103               31: void PCHTypeWriter::VisitArrayType(const ArrayType *T) {
     104               31:   Writer.AddTypeRef(T->getElementType(), Record);
     105               31:   Record.push_back(T->getSizeModifier()); // FIXME: stable values
     106               31:   Record.push_back(T->getIndexTypeCVRQualifiers()); // FIXME: stable values
     107               31: }
     108                 : 
     109               24: void PCHTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
     110               24:   VisitArrayType(T);
     111               24:   Writer.AddAPInt(T->getSize(), Record);
     112               24:   Code = pch::TYPE_CONSTANT_ARRAY;
     113               24: }
     114                 : 
     115                6: void PCHTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
     116                6:   VisitArrayType(T);
     117                6:   Code = pch::TYPE_INCOMPLETE_ARRAY;
     118                6: }
     119                 : 
     120                1: void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
     121                1:   VisitArrayType(T);
     122                1:   Writer.AddSourceLocation(T->getLBracketLoc(), Record);
     123                1:   Writer.AddSourceLocation(T->getRBracketLoc(), Record);
     124                1:   Writer.AddStmt(T->getSizeExpr());
     125                1:   Code = pch::TYPE_VARIABLE_ARRAY;
     126                1: }
     127                 : 
     128                5: void PCHTypeWriter::VisitVectorType(const VectorType *T) {
     129                5:   Writer.AddTypeRef(T->getElementType(), Record);
     130                5:   Record.push_back(T->getNumElements());
     131                5:   Record.push_back(T->isAltiVec());
     132                5:   Record.push_back(T->isPixel());
     133                5:   Code = pch::TYPE_VECTOR;
     134                5: }
     135                 : 
     136                4: void PCHTypeWriter::VisitExtVectorType(const ExtVectorType *T) {
     137                4:   VisitVectorType(T);
     138                4:   Code = pch::TYPE_EXT_VECTOR;
     139                4: }
     140                 : 
     141               53: void PCHTypeWriter::VisitFunctionType(const FunctionType *T) {
     142               53:   Writer.AddTypeRef(T->getResultType(), Record);
     143               53:   Record.push_back(T->getNoReturnAttr());
     144                 :   // FIXME: need to stabilize encoding of calling convention...
     145               53:   Record.push_back(T->getCallConv());
     146               53: }
     147                 : 
     148                6: void PCHTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
     149                6:   VisitFunctionType(T);
     150                6:   Code = pch::TYPE_FUNCTION_NO_PROTO;
     151                6: }
     152                 : 
     153               47: void PCHTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
     154               47:   VisitFunctionType(T);
     155               47:   Record.push_back(T->getNumArgs());
                       62: branch 1 taken
                       47: branch 2 taken
     156              109:   for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
     157               62:     Writer.AddTypeRef(T->getArgType(I), Record);
     158               47:   Record.push_back(T->isVariadic());
     159               47:   Record.push_back(T->getTypeQuals());
     160               47:   Record.push_back(T->hasExceptionSpec());
     161               47:   Record.push_back(T->hasAnyExceptionSpec());
     162               47:   Record.push_back(T->getNumExceptions());
                        0: branch 1 not taken
                       47: branch 2 taken
     163               47:   for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I)
     164                0:     Writer.AddTypeRef(T->getExceptionType(I), Record);
     165               47:   Code = pch::TYPE_FUNCTION_PROTO;
     166               47: }
     167                 : 
     168                 : #if 0
     169                 : // For when we want it....
     170                 : void PCHTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
     171                 :   Writer.AddDeclRef(T->getDecl(), Record);
     172                 :   Code = pch::TYPE_UNRESOLVED_USING;
     173                 : }
     174                 : #endif
     175                 : 
     176               42: void PCHTypeWriter::VisitTypedefType(const TypedefType *T) {
     177               42:   Writer.AddDeclRef(T->getDecl(), Record);
     178               42:   Code = pch::TYPE_TYPEDEF;
     179               42: }
     180                 : 
     181               39: void PCHTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
     182               39:   Writer.AddStmt(T->getUnderlyingExpr());
     183               39:   Code = pch::TYPE_TYPEOF_EXPR;
     184               39: }
     185                 : 
     186                4: void PCHTypeWriter::VisitTypeOfType(const TypeOfType *T) {
     187                4:   Writer.AddTypeRef(T->getUnderlyingType(), Record);
     188                4:   Code = pch::TYPE_TYPEOF;
     189                4: }
     190                 : 
     191                0: void PCHTypeWriter::VisitDecltypeType(const DecltypeType *T) {
     192                0:   Writer.AddStmt(T->getUnderlyingExpr());
     193                0:   Code = pch::TYPE_DECLTYPE;
     194                0: }
     195                 : 
     196               30: void PCHTypeWriter::VisitTagType(const TagType *T) {
     197               30:   Writer.AddDeclRef(T->getDecl(), Record);
     198                 :   assert(!T->isBeingDefined() &&
                       30: branch 1 taken
                        0: branch 2 not taken
     199               30:          "Cannot serialize in the middle of a type definition");
     200               30: }
     201                 : 
     202               25: void PCHTypeWriter::VisitRecordType(const RecordType *T) {
     203               25:   VisitTagType(T);
     204               25:   Code = pch::TYPE_RECORD;
     205               25: }
     206                 : 
     207                5: void PCHTypeWriter::VisitEnumType(const EnumType *T) {
     208                5:   VisitTagType(T);
     209                5:   Code = pch::TYPE_ENUM;
     210                5: }
     211                 : 
     212                0: void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
     213                0:   Writer.AddTypeRef(T->getUnderlyingType(), Record);
     214                0:   Record.push_back(T->getTagKind());
     215                0:   Code = pch::TYPE_ELABORATED;
     216                0: }
     217                 : 
     218                 : void
     219                 : PCHTypeWriter::VisitSubstTemplateTypeParmType(
     220                0:                                         const SubstTemplateTypeParmType *T) {
     221                0:   Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record);
     222                0:   Writer.AddTypeRef(T->getReplacementType(), Record);
     223                0:   Code = pch::TYPE_SUBST_TEMPLATE_TYPE_PARM;
     224                0: }
     225                 : 
     226                 : void
     227                 : PCHTypeWriter::VisitTemplateSpecializationType(
     228                0:                                        const TemplateSpecializationType *T) {
     229                 :   // FIXME: Serialize this type (C++ only)
     230                0:   assert(false && "Cannot serialize template specialization types");
     231                 : }
     232                 : 
     233                0: void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) {
     234                 :   // FIXME: Serialize this type (C++ only)
     235                0:   assert(false && "Cannot serialize qualified name types");
     236                 : }
     237                 : 
     238               20: void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
     239               20:   Writer.AddDeclRef(T->getDecl(), Record);
     240               20:   Record.push_back(T->getNumProtocols());
                        1: branch 1 taken
                       20: branch 2 taken
     241               41:   for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
     242               20:        E = T->qual_end(); I != E; ++I)
     243                1:     Writer.AddDeclRef(*I, Record);
     244               20:   Code = pch::TYPE_OBJC_INTERFACE;
     245               20: }
     246                 : 
     247                 : void
     248               36: PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
     249               36:   Writer.AddTypeRef(T->getPointeeType(), Record);
     250               36:   Record.push_back(T->getNumProtocols());
                        6: branch 1 taken
                       36: branch 2 taken
     251               78:   for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
     252               36:        E = T->qual_end(); I != E; ++I)
     253                6:     Writer.AddDeclRef(*I, Record);
     254               36:   Code = pch::TYPE_OBJC_OBJECT_POINTER;
     255               36: }
     256                 : 
     257                 : namespace {
     258                 : 
     259                 : class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
     260                 :   PCHWriter &Writer;
     261                 :   PCHWriter::RecordData &Record;
     262                 : 
     263                 : public:
     264              420:   TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
     265              420:     : Writer(Writer), Record(Record) { }
     266                 : 
     267                 : #define ABSTRACT_TYPELOC(CLASS, PARENT)
     268                 : #define TYPELOC(CLASS, PARENT) \
     269                 :     void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
     270                 : #include "clang/AST/TypeLocNodes.def"
     271                 : 
     272                 :   void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
     273                 :   void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
     274                 : };
     275                 : 
     276                 : }
     277                 : 
     278               16: void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
     279                 :   // nothing to do
     280               16: }
     281              321: void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
     282              321:   Writer.AddSourceLocation(TL.getBuiltinLoc(), Record);
                      187: branch 1 taken
                      134: branch 2 taken
     283              321:   if (TL.needsExtraLocalData()) {
     284              187:     Record.push_back(TL.getWrittenTypeSpec());
     285              187:     Record.push_back(TL.getWrittenSignSpec());
     286              187:     Record.push_back(TL.getWrittenWidthSpec());
     287              187:     Record.push_back(TL.hasModeAttr());
     288                 :   }
     289              321: }
     290                1: void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
     291                1:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     292                1: }
     293              108: void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
     294              108:   Writer.AddSourceLocation(TL.getStarLoc(), Record);
     295              108: }
     296                2: void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
     297                2:   Writer.AddSourceLocation(TL.getCaretLoc(), Record);
     298                2: }
     299                2: void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
     300                2:   Writer.AddSourceLocation(TL.getAmpLoc(), Record);
     301                2: }
     302                0: void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
     303                0:   Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record);
     304                0: }
     305                0: void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
     306                0:   Writer.AddSourceLocation(TL.getStarLoc(), Record);
     307                0: }
     308               19: void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
     309               19:   Writer.AddSourceLocation(TL.getLBracketLoc(), Record);
     310               19:   Writer.AddSourceLocation(TL.getRBracketLoc(), Record);
                       12: branch 1 taken
                        7: branch 2 taken
     311               19:   Record.push_back(TL.getSizeExpr() ? 1 : 0);
                       12: branch 1 taken
                        7: branch 2 taken
     312               19:   if (TL.getSizeExpr())
     313               12:     Writer.AddStmt(TL.getSizeExpr());
     314               19: }
     315               11: void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
     316               11:   VisitArrayTypeLoc(TL);
     317               11: }
     318                7: void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
     319                7:   VisitArrayTypeLoc(TL);
     320                7: }
     321                1: void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
     322                1:   VisitArrayTypeLoc(TL);
     323                1: }
     324                 : void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
     325                0:                                             DependentSizedArrayTypeLoc TL) {
     326                0:   VisitArrayTypeLoc(TL);
     327                0: }
     328                 : void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
     329                0:                                         DependentSizedExtVectorTypeLoc TL) {
     330                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     331                0: }
     332                1: void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
     333                1:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     334                1: }
     335                4: void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
     336                4:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     337                4: }
     338               50: void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
     339               50:   Writer.AddSourceLocation(TL.getLParenLoc(), Record);
     340               50:   Writer.AddSourceLocation(TL.getRParenLoc(), Record);
                       57: branch 1 taken
                       50: branch 2 taken
     341              107:   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     342               57:     Writer.AddDeclRef(TL.getArg(i), Record);
     343               50: }
     344               44: void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
     345               44:   VisitFunctionTypeLoc(TL);
     346               44: }
     347                6: void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
     348                6:   VisitFunctionTypeLoc(TL);
     349                6: }
     350                0: void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
     351                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     352                0: }
     353               15: void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
     354               15:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     355               15: }
     356               39: void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
     357               39:   Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
     358               39:   Writer.AddSourceLocation(TL.getLParenLoc(), Record);
     359               39:   Writer.AddSourceLocation(TL.getRParenLoc(), Record);
     360               39: }
     361                4: void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
     362                4:   Writer.AddSourceLocation(TL.getTypeofLoc(), Record);
     363                4:   Writer.AddSourceLocation(TL.getLParenLoc(), Record);
     364                4:   Writer.AddSourceLocation(TL.getRParenLoc(), Record);
     365                4:   Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record);
     366                4: }
     367                0: void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
     368                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     369                0: }
     370               28: void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
     371               28:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     372               28: }
     373                1: void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
     374                1:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     375                1: }
     376                0: void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
     377                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     378                0: }
     379                0: void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
     380                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     381                0: }
     382                 : void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
     383                0:                                             SubstTemplateTypeParmTypeLoc TL) {
     384                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     385                0: }
     386                 : void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
     387                0:                                            TemplateSpecializationTypeLoc TL) {
     388                0:   Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
     389                0:   Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
     390                0:   Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
                        0: branch 1 not taken
                        0: branch 2 not taken
     391                0:   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     392                0:     Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record);
     393                0: }
     394                0: void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
     395                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     396                0: }
     397                0: void TypeLocWriter::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
     398                0:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     399                0: }
     400                6: void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
     401                6:   Writer.AddSourceLocation(TL.getNameLoc(), Record);
     402                6:   Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
     403                6:   Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
                        1: branch 1 taken
                        6: branch 2 taken
     404                7:   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
     405                1:     Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
     406                6: }
     407               31: void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
     408               31:   Writer.AddSourceLocation(TL.getStarLoc(), Record);
     409               31:   Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
     410               31:   Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
     411               31:   Record.push_back(TL.hasBaseTypeAsWritten());
     412               31:   Record.push_back(TL.hasProtocolsAsWritten());
                        5: branch 1 taken
                       26: branch 2 taken
     413               31:   if (TL.hasProtocolsAsWritten())
                        5: branch 1 taken
                        5: branch 2 taken
     414               10:     for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
     415                5:       Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
     416               31: }
     417                 : 
     418                 : //===----------------------------------------------------------------------===//
     419                 : // PCHWriter Implementation
     420                 : //===----------------------------------------------------------------------===//
     421                 : 
     422                 : static void EmitBlockID(unsigned ID, const char *Name,
     423                 :                         llvm::BitstreamWriter &Stream,
     424              176:                         PCHWriter::RecordData &Record) {
     425              176:   Record.clear();
     426              176:   Record.push_back(ID);
     427              176:   Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
     428                 : 
     429                 :   // Emit the block name if present.
                      176: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                      176: branch 3 taken
     430              176:   if (Name == 0 || Name[0] == 0) return;
     431              176:   Record.clear();
                     2728: branch 0 taken
                      176: branch 1 taken
     432             3080:   while (*Name)
     433             2728:     Record.push_back(*Name++);
     434              176:   Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
     435                 : }
     436                 : 
     437                 : static void EmitRecordID(unsigned ID, const char *Name,
     438                 :                          llvm::BitstreamWriter &Stream,
     439             6776:                          PCHWriter::RecordData &Record) {
     440             6776:   Record.clear();
     441             6776:   Record.push_back(ID);
                   114444: branch 0 taken
                     6776: branch 1 taken
     442           127996:   while (*Name)
     443           114444:     Record.push_back(*Name++);
     444             6776:   Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
     445             6776: }
     446                 : 
     447                 : static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
     448               44:                           PCHWriter::RecordData &Record) {
     449                 : #define RECORD(X) EmitRecordID(pch::X, #X, Stream, Record)
     450               44:   RECORD(STMT_STOP);
     451               44:   RECORD(STMT_NULL_PTR);
     452               44:   RECORD(STMT_NULL);
     453               44:   RECORD(STMT_COMPOUND);
     454               44:   RECORD(STMT_CASE);
     455               44:   RECORD(STMT_DEFAULT);
     456               44:   RECORD(STMT_LABEL);
     457               44:   RECORD(STMT_IF);
     458               44:   RECORD(STMT_SWITCH);
     459               44:   RECORD(STMT_WHILE);
     460               44:   RECORD(STMT_DO);
     461               44:   RECORD(STMT_FOR);
     462               44:   RECORD(STMT_GOTO);
     463               44:   RECORD(STMT_INDIRECT_GOTO);
     464               44:   RECORD(STMT_CONTINUE);
     465               44:   RECORD(STMT_BREAK);
     466               44:   RECORD(STMT_RETURN);
     467               44:   RECORD(STMT_DECL);
     468               44:   RECORD(STMT_ASM);
     469               44:   RECORD(EXPR_PREDEFINED);
     470               44:   RECORD(EXPR_DECL_REF);
     471               44:   RECORD(EXPR_INTEGER_LITERAL);
     472               44:   RECORD(EXPR_FLOATING_LITERAL);
     473               44:   RECORD(EXPR_IMAGINARY_LITERAL);
     474               44:   RECORD(EXPR_STRING_LITERAL);
     475               44:   RECORD(EXPR_CHARACTER_LITERAL);
     476               44:   RECORD(EXPR_PAREN);
     477               44:   RECORD(EXPR_UNARY_OPERATOR);
     478               44:   RECORD(EXPR_SIZEOF_ALIGN_OF);
     479               44:   RECORD(EXPR_ARRAY_SUBSCRIPT);
     480               44:   RECORD(EXPR_CALL);
     481               44:   RECORD(EXPR_MEMBER);
     482               44:   RECORD(EXPR_BINARY_OPERATOR);
     483               44:   RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR);
     484               44:   RECORD(EXPR_CONDITIONAL_OPERATOR);
     485               44:   RECORD(EXPR_IMPLICIT_CAST);
     486               44:   RECORD(EXPR_CSTYLE_CAST);
     487               44:   RECORD(EXPR_COMPOUND_LITERAL);
     488               44:   RECORD(EXPR_EXT_VECTOR_ELEMENT);
     489               44:   RECORD(EXPR_INIT_LIST);
     490               44:   RECORD(EXPR_DESIGNATED_INIT);
     491               44:   RECORD(EXPR_IMPLICIT_VALUE_INIT);
     492               44:   RECORD(EXPR_VA_ARG);
     493               44:   RECORD(EXPR_ADDR_LABEL);
     494               44:   RECORD(EXPR_STMT);
     495               44:   RECORD(EXPR_TYPES_COMPATIBLE);
     496               44:   RECORD(EXPR_CHOOSE);
     497               44:   RECORD(EXPR_GNU_NULL);
     498               44:   RECORD(EXPR_SHUFFLE_VECTOR);
     499               44:   RECORD(EXPR_BLOCK);
     500               44:   RECORD(EXPR_BLOCK_DECL_REF);
     501               44:   RECORD(EXPR_OBJC_STRING_LITERAL);
     502               44:   RECORD(EXPR_OBJC_ENCODE);
     503               44:   RECORD(EXPR_OBJC_SELECTOR_EXPR);
     504               44:   RECORD(EXPR_OBJC_PROTOCOL_EXPR);
     505               44:   RECORD(EXPR_OBJC_IVAR_REF_EXPR);
     506               44:   RECORD(EXPR_OBJC_PROPERTY_REF_EXPR);
     507               44:   RECORD(EXPR_OBJC_KVC_REF_EXPR);
     508               44:   RECORD(EXPR_OBJC_MESSAGE_EXPR);
     509               44:   RECORD(EXPR_OBJC_SUPER_EXPR);
     510               44:   RECORD(STMT_OBJC_FOR_COLLECTION);
     511               44:   RECORD(STMT_OBJC_CATCH);
     512               44:   RECORD(STMT_OBJC_FINALLY);
     513               44:   RECORD(STMT_OBJC_AT_TRY);
     514               44:   RECORD(STMT_OBJC_AT_SYNCHRONIZED);
     515               44:   RECORD(STMT_OBJC_AT_THROW);
     516               44:   RECORD(EXPR_CXX_OPERATOR_CALL);
     517               44:   RECORD(EXPR_CXX_CONSTRUCT);
     518               44:   RECORD(EXPR_CXX_STATIC_CAST);
     519               44:   RECORD(EXPR_CXX_DYNAMIC_CAST);
     520               44:   RECORD(EXPR_CXX_REINTERPRET_CAST);
     521               44:   RECORD(EXPR_CXX_CONST_CAST);
     522               44:   RECORD(EXPR_CXX_FUNCTIONAL_CAST);
     523               44:   RECORD(EXPR_CXX_BOOL_LITERAL);
     524               44:   RECORD(EXPR_CXX_NULL_PTR_LITERAL);
     525                 : #undef RECORD
     526               44: }
     527                 : 
     528               44: void PCHWriter::WriteBlockInfoBlock() {
     529               44:   RecordData Record;
     530               44:   Stream.EnterSubblock(llvm::bitc::BLOCKINFO_BLOCK_ID, 3);
     531                 : 
     532                 : #define BLOCK(X) EmitBlockID(pch::X ## _ID, #X, Stream, Record)
     533                 : #define RECORD(X) EmitRecordID(pch::X, #X, Stream, Record)
     534                 : 
     535                 :   // PCH Top-Level Block.
     536               44:   BLOCK(PCH_BLOCK);
     537               44:   RECORD(ORIGINAL_FILE_NAME);
     538               44:   RECORD(TYPE_OFFSET);
     539               44:   RECORD(DECL_OFFSET);
     540               44:   RECORD(LANGUAGE_OPTIONS);
     541               44:   RECORD(METADATA);
     542               44:   RECORD(IDENTIFIER_OFFSET);
     543               44:   RECORD(IDENTIFIER_TABLE);
     544               44:   RECORD(EXTERNAL_DEFINITIONS);
     545               44:   RECORD(SPECIAL_TYPES);
     546               44:   RECORD(STATISTICS);
     547               44:   RECORD(TENTATIVE_DEFINITIONS);
     548               44:   RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS);
     549               44:   RECORD(SELECTOR_OFFSETS);
     550               44:   RECORD(METHOD_POOL);
     551               44:   RECORD(PP_COUNTER_VALUE);
     552               44:   RECORD(SOURCE_LOCATION_OFFSETS);
     553               44:   RECORD(SOURCE_LOCATION_PRELOADS);
     554               44:   RECORD(STAT_CACHE);
     555               44:   RECORD(EXT_VECTOR_DECLS);
     556               44:   RECORD(COMMENT_RANGES);
     557               44:   RECORD(VERSION_CONTROL_BRANCH_REVISION);
     558                 :   
     559                 :   // SourceManager Block.
     560               44:   BLOCK(SOURCE_MANAGER_BLOCK);
     561               44:   RECORD(SM_SLOC_FILE_ENTRY);
     562               44:   RECORD(SM_SLOC_BUFFER_ENTRY);
     563               44:   RECORD(SM_SLOC_BUFFER_BLOB);
     564               44:   RECORD(SM_SLOC_INSTANTIATION_ENTRY);
     565               44:   RECORD(SM_LINE_TABLE);
     566               44:   RECORD(SM_HEADER_FILE_INFO);
     567                 : 
     568                 :   // Preprocessor Block.
     569               44:   BLOCK(PREPROCESSOR_BLOCK);
     570               44:   RECORD(PP_MACRO_OBJECT_LIKE);
     571               44:   RECORD(PP_MACRO_FUNCTION_LIKE);
     572               44:   RECORD(PP_TOKEN);
     573                 : 
     574                 :   // Decls and Types block.
     575               44:   BLOCK(DECLTYPES_BLOCK);
     576               44:   RECORD(TYPE_EXT_QUAL);
     577               44:   RECORD(TYPE_COMPLEX);
     578               44:   RECORD(TYPE_POINTER);
     579               44:   RECORD(TYPE_BLOCK_POINTER);
     580               44:   RECORD(TYPE_LVALUE_REFERENCE);
     581               44:   RECORD(TYPE_RVALUE_REFERENCE);
     582               44:   RECORD(TYPE_MEMBER_POINTER);
     583               44:   RECORD(TYPE_CONSTANT_ARRAY);
     584               44:   RECORD(TYPE_INCOMPLETE_ARRAY);
     585               44:   RECORD(TYPE_VARIABLE_ARRAY);
     586               44:   RECORD(TYPE_VECTOR);
     587               44:   RECORD(TYPE_EXT_VECTOR);
     588               44:   RECORD(TYPE_FUNCTION_PROTO);
     589               44:   RECORD(TYPE_FUNCTION_NO_PROTO);
     590               44:   RECORD(TYPE_TYPEDEF);
     591               44:   RECORD(TYPE_TYPEOF_EXPR);
     592               44:   RECORD(TYPE_TYPEOF);
     593               44:   RECORD(TYPE_RECORD);
     594               44:   RECORD(TYPE_ENUM);
     595               44:   RECORD(TYPE_OBJC_INTERFACE);
     596               44:   RECORD(TYPE_OBJC_OBJECT_POINTER);
     597               44:   RECORD(DECL_ATTR);
     598               44:   RECORD(DECL_TRANSLATION_UNIT);
     599               44:   RECORD(DECL_TYPEDEF);
     600               44:   RECORD(DECL_ENUM);
     601               44:   RECORD(DECL_RECORD);
     602               44:   RECORD(DECL_ENUM_CONSTANT);
     603               44:   RECORD(DECL_FUNCTION);
     604               44:   RECORD(DECL_OBJC_METHOD);
     605               44:   RECORD(DECL_OBJC_INTERFACE);
     606               44:   RECORD(DECL_OBJC_PROTOCOL);
     607               44:   RECORD(DECL_OBJC_IVAR);
     608               44:   RECORD(DECL_OBJC_AT_DEFS_FIELD);
     609               44:   RECORD(DECL_OBJC_CLASS);
     610               44:   RECORD(DECL_OBJC_FORWARD_PROTOCOL);
     611               44:   RECORD(DECL_OBJC_CATEGORY);
     612               44:   RECORD(DECL_OBJC_CATEGORY_IMPL);
     613               44:   RECORD(DECL_OBJC_IMPLEMENTATION);
     614               44:   RECORD(DECL_OBJC_COMPATIBLE_ALIAS);
     615               44:   RECORD(DECL_OBJC_PROPERTY);
     616               44:   RECORD(DECL_OBJC_PROPERTY_IMPL);
     617               44:   RECORD(DECL_FIELD);
     618               44:   RECORD(DECL_VAR);
     619               44:   RECORD(DECL_IMPLICIT_PARAM);
     620               44:   RECORD(DECL_PARM_VAR);
     621               44:   RECORD(DECL_FILE_SCOPE_ASM);
     622               44:   RECORD(DECL_BLOCK);
     623               44:   RECORD(DECL_CONTEXT_LEXICAL);
     624               44:   RECORD(DECL_CONTEXT_VISIBLE);
     625                 :   // Statements and Exprs can occur in the Decls and Types block.
     626               44:   AddStmtsExprs(Stream, Record);
     627                 : #undef RECORD
     628                 : #undef BLOCK
     629               44:   Stream.ExitBlock();
     630               44: }
     631                 : 
     632                 : /// \brief Adjusts the given filename to only write out the portion of the
     633                 : /// filename that is not part of the system root directory.
     634                 : ///
     635                 : /// \param Filename the file name to adjust.
     636                 : ///
     637                 : /// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and
     638                 : /// the returned filename will be adjusted by this system root.
     639                 : ///
     640                 : /// \returns either the original filename (if it needs no adjustment) or the
     641                 : /// adjusted filename (which points into the @p Filename parameter).
     642                 : static const char *
     643              268: adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) {
                        0: branch 0 not taken
                      268: branch 1 taken
     644              268:   assert(Filename && "No file name to adjust?");
     645                 : 
                      262: branch 0 taken
                        6: branch 1 taken
     646              268:   if (!isysroot)
     647              262:     return Filename;
     648                 : 
     649                 :   // Verify that the filename and the system root have the same prefix.
     650                6:   unsigned Pos = 0;
                      194: branch 0 taken
                        0: branch 1 not taken
                      191: branch 2 taken
                        3: branch 3 taken
     651              194:   for (; Filename[Pos] && isysroot[Pos]; ++Pos)
                        3: branch 0 taken
                      188: branch 1 taken
     652              191:     if (Filename[Pos] != isysroot[Pos])
     653                3:       return Filename; // Prefixes don't match.
     654                 : 
     655                 :   // We hit the end of the filename before we hit the end of the system root.
                        0: branch 0 not taken
                        3: branch 1 taken
     656                3:   if (!Filename[Pos])
     657                0:     return Filename;
     658                 : 
     659                 :   // If the file name has a '/' at the current position, skip over the '/'.
     660                 :   // We distinguish sysroot-based includes from absolute includes by the
     661                 :   // absence of '/' at the beginning of sysroot-based includes.
                        3: branch 0 taken
                        0: branch 1 not taken
     662                3:   if (Filename[Pos] == '/')
     663                3:     ++Pos;
     664                 : 
     665                3:   return Filename + Pos;
     666                 : }
     667                 : 
     668                 : /// \brief Write the PCH metadata (e.g., i686-apple-darwin9).
     669               44: void PCHWriter::WriteMetadata(ASTContext &Context, const char *isysroot) {
     670                 :   using namespace llvm;
     671                 : 
     672                 :   // Metadata
     673               44:   const TargetInfo &Target = Context.Target;
     674               44:   BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
     675               44:   MetaAbbrev->Add(BitCodeAbbrevOp(pch::METADATA));
     676               44:   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH major
     677               44:   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH minor
     678               44:   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
     679               44:   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
     680               44:   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
     681               44:   MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
     682               44:   unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
     683                 : 
     684               44:   RecordData Record;
     685               44:   Record.push_back(pch::METADATA);
     686               44:   Record.push_back(pch::VERSION_MAJOR);
     687               44:   Record.push_back(pch::VERSION_MINOR);
     688               44:   Record.push_back(CLANG_VERSION_MAJOR);
     689               44:   Record.push_back(CLANG_VERSION_MINOR);
     690               44:   Record.push_back(isysroot != 0);
     691               44:   const std::string &TripleStr = Target.getTriple().getTriple();
     692               44:   Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, TripleStr);
     693                 : 
     694                 :   // Original file name
     695               44:   SourceManager &SM = Context.getSourceManager();
                       44: branch 2 taken
                        0: branch 3 not taken
     696               44:   if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
     697               44:     BitCodeAbbrev *FileAbbrev = new BitCodeAbbrev();
     698               44:     FileAbbrev->Add(BitCodeAbbrevOp(pch::ORIGINAL_FILE_NAME));
     699               44:     FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
     700               44:     unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev);
     701                 : 
     702               44:     llvm::sys::Path MainFilePath(MainFile->getName());
     703               44:     std::string MainFileName;
     704                 : 
                        0: branch 1 not taken
                       44: branch 2 taken
     705               44:     if (!MainFilePath.isAbsolute()) {
     706                0:       llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
     707                0:       P.appendComponent(MainFilePath.str());
     708                0:       MainFileName = P.str();
     709                 :     } else {
     710               44:       MainFileName = MainFilePath.str();
     711                 :     }
     712                 : 
     713               44:     const char *MainFileNameStr = MainFileName.c_str();
     714                 :     MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr,
     715               44:                                                       isysroot);
     716               44:     RecordData Record;
     717               44:     Record.push_back(pch::ORIGINAL_FILE_NAME);
     718               44:     Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr);
     719                 :   }
     720                 :   
     721                 :   // Repository branch/version information.
     722               44:   BitCodeAbbrev *RepoAbbrev = new BitCodeAbbrev();
     723               44:   RepoAbbrev->Add(BitCodeAbbrevOp(pch::VERSION_CONTROL_BRANCH_REVISION));
     724               44:   RepoAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
     725               44:   unsigned RepoAbbrevCode = Stream.EmitAbbrev(RepoAbbrev);
     726               44:   Record.clear();
     727               44:   Record.push_back(pch::VERSION_CONTROL_BRANCH_REVISION);
     728                 :   Stream.EmitRecordWithBlob(RepoAbbrevCode, Record,
     729               44:                             getClangFullRepositoryVersion());
     730               44: }
     731                 : 
     732                 : /// \brief Write the LangOptions structure.
     733               44: void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
     734               44:   RecordData Record;
     735               44:   Record.push_back(LangOpts.Trigraphs);
     736               44:   Record.push_back(LangOpts.BCPLComment);  // BCPL-style '//' comments.
     737               44:   Record.push_back(LangOpts.DollarIdents);  // '$' allowed in identifiers.
     738               44:   Record.push_back(LangOpts.AsmPreprocessor);  // Preprocessor in asm mode.
     739               44:   Record.push_back(LangOpts.GNUMode);  // True in gnu99 mode false in c99 mode (etc)
     740               44:   Record.push_back(LangOpts.ImplicitInt);  // C89 implicit 'int'.
     741               44:   Record.push_back(LangOpts.Digraphs);  // C94, C99 and C++
     742               44:   Record.push_back(LangOpts.HexFloats);  // C99 Hexadecimal float constants.
     743               44:   Record.push_back(LangOpts.C99);  // C99 Support
     744               44:   Record.push_back(LangOpts.Microsoft);  // Microsoft extensions.
     745               44:   Record.push_back(LangOpts.CPlusPlus);  // C++ Support
     746               44:   Record.push_back(LangOpts.CPlusPlus0x);  // C++0x Support
     747               44:   Record.push_back(LangOpts.CXXOperatorNames);  // Treat C++ operator names as keywords.
     748                 : 
     749               44:   Record.push_back(LangOpts.ObjC1);  // Objective-C 1 support enabled.
     750               44:   Record.push_back(LangOpts.ObjC2);  // Objective-C 2 support enabled.
     751               44:   Record.push_back(LangOpts.ObjCNonFragileABI);  // Objective-C 
     752                 :                                                  // modern abi enabled.
     753               44:   Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced 
     754                 :                                                  // modern abi enabled.
     755                 : 
     756               44:   Record.push_back(LangOpts.PascalStrings);  // Allow Pascal strings
     757               44:   Record.push_back(LangOpts.WritableStrings);  // Allow writable strings
     758               44:   Record.push_back(LangOpts.LaxVectorConversions);
     759               44:   Record.push_back(LangOpts.AltiVec);
     760               44:   Record.push_back(LangOpts.Exceptions);  // Support exception handling.
     761                 : 
     762               44:   Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
     763               44:   Record.push_back(LangOpts.Freestanding); // Freestanding implementation
     764               44:   Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin)
     765                 : 
     766                 :   // Whether static initializers are protected by locks.
     767               44:   Record.push_back(LangOpts.ThreadsafeStatics);
     768               44:   Record.push_back(LangOpts.POSIXThreads);
     769               44:   Record.push_back(LangOpts.Blocks); // block extension to C
     770               44:   Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if
     771                 :                                   // they are unused.
     772               44:   Record.push_back(LangOpts.MathErrno); // Math functions must respect errno
     773                 :                                   // (modulo the platform support).
     774                 : 
     775               44:   Record.push_back(LangOpts.OverflowChecking); // Extension to call a handler function when
     776                 :                                   // signed integer arithmetic overflows.
     777                 : 
     778               44:   Record.push_back(LangOpts.HeinousExtensions); // Extensions that we really don't like and
     779                 :                                   // may be ripped out at any time.
     780                 : 
     781               44:   Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
     782               44:   Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
     783                 :                                   // defined.
     784               44:   Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
     785                 :                                   // opposed to __DYNAMIC__).
     786               44:   Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero.
     787                 : 
     788               44:   Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be
     789                 :                                   // used (instead of C99 semantics).
     790               44:   Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined.
     791               44:   Record.push_back(LangOpts.AccessControl); // Whether C++ access control should
     792                 :                                             // be enabled.
     793               44:   Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or
     794                 :                                            // unsigned type
     795               44:   Record.push_back(LangOpts.ShortWChar);  // force wchar_t to be unsigned short
     796               44:   Record.push_back(LangOpts.getGCMode());
     797               44:   Record.push_back(LangOpts.getVisibilityMode());
     798               44:   Record.push_back(LangOpts.getStackProtectorMode());
     799               44:   Record.push_back(LangOpts.InstantiationDepth);
     800               44:   Record.push_back(LangOpts.OpenCL);
     801               44:   Record.push_back(LangOpts.CatchUndefined);
     802               44:   Record.push_back(LangOpts.ElideConstructors);
     803               44:   Stream.EmitRecord(pch::LANGUAGE_OPTIONS, Record);
     804               44: }
     805                 : 
     806                 : //===----------------------------------------------------------------------===//
     807                 : // stat cache Serialization
     808                 : //===----------------------------------------------------------------------===//
     809                 : 
     810                 : namespace {
     811                 : // Trait used for the on-disk hash table of stat cache results.
     812                 : class PCHStatCacheTrait {
     813                 : public:
     814                 :   typedef const char * key_type;
     815                 :   typedef key_type key_type_ref;
     816                 : 
     817                 :   typedef std::pair<int, struct stat> data_type;
     818                 :   typedef const data_type& data_type_ref;
     819                 : 
     820               87:   static unsigned ComputeHash(const char *path) {
     821               87:     return llvm::HashString(path);
     822                 :   }
     823                 : 
     824                 :   std::pair<unsigned,unsigned>
     825                 :     EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
     826               87:                       data_type_ref Data) {
     827               87:     unsigned StrLen = strlen(path);
     828               87:     clang::io::Emit16(Out, StrLen);
     829               87:     unsigned DataLen = 1; // result value
                       87: branch 0 taken
                        0: branch 1 not taken
     830               87:     if (Data.first == 0)
     831               87:       DataLen += 4 + 4 + 2 + 8 + 8;
     832               87:     clang::io::Emit8(Out, DataLen);
     833               87:     return std::make_pair(StrLen + 1, DataLen);
     834                 :   }
     835                 : 
     836               87:   void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
     837               87:     Out.write(path, KeyLen);
     838               87:   }
     839                 : 
     840                 :   void EmitData(llvm::raw_ostream& Out, key_type_ref,
     841               87:                 data_type_ref Data, unsigned DataLen) {
     842                 :     using namespace clang::io;
     843               87:     uint64_t Start = Out.tell(); (void)Start;
     844                 : 
     845                 :     // Result of stat()
                        0: branch 0 not taken
                       87: branch 1 taken
     846               87:     Emit8(Out, Data.first? 1 : 0);
     847                 : 
                       87: branch 0 taken
                        0: branch 1 not taken
     848               87:     if (Data.first == 0) {
     849               87:       Emit32(Out, (uint32_t) Data.second.st_ino);
     850               87:       Emit32(Out, (uint32_t) Data.second.st_dev);
     851               87:       Emit16(Out, (uint16_t) Data.second.st_mode);
     852               87:       Emit64(Out, (uint64_t) Data.second.st_mtime);
     853               87:       Emit64(Out, (uint64_t) Data.second.st_size);
     854                 :     }
     855                 : 
                       87: branch 1 taken
                        0: branch 2 not taken
     856               87:     assert(Out.tell() - Start == DataLen && "Wrong data length");
     857               87:   }
     858                 : };
     859                 : } // end anonymous namespace
     860                 : 
     861                 : /// \brief Write the stat() system call cache to the PCH file.
     862                 : void PCHWriter::WriteStatCache(MemorizeStatCalls &StatCalls,
     863               43:                                const char *isysroot) {
     864                 :   // Build the on-disk hash table containing information about every
     865                 :   // stat() call.
     866               43:   OnDiskChainedHashTableGenerator<PCHStatCacheTrait> Generator;
     867               43:   unsigned NumStatEntries = 0;
                       87: branch 3 taken
                       43: branch 4 taken
     868              173:   for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
     869               43:                                 StatEnd = StatCalls.end();
     870                 :        Stat != StatEnd; ++Stat, ++NumStatEntries) {
     871               87:     const char *Filename = Stat->first();
     872               87:     Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
     873               87:     Generator.insert(Filename, Stat->second);
     874                 :   }
     875                 : 
     876                 :   // Create the on-disk hash table in a buffer.
     877               43:   llvm::SmallString<4096> StatCacheData;
     878                 :   uint32_t BucketOffset;
     879                 :   {
     880               43:     llvm::raw_svector_ostream Out(StatCacheData);
     881                 :     // Make sure that no bucket is at offset 0
     882               43:     clang::io::Emit32(Out, 0);
     883               43:     BucketOffset = Generator.Emit(Out);
     884                 :   }
     885                 : 
     886                 :   // Create a blob abbreviation
     887                 :   using namespace llvm;
     888               43:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
     889               43:   Abbrev->Add(BitCodeAbbrevOp(pch::STAT_CACHE));
     890               43:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
     891               43:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
     892               43:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
     893               43:   unsigned StatCacheAbbrev = Stream.EmitAbbrev(Abbrev);
     894                 : 
     895                 :   // Write the stat cache
     896               43:   RecordData Record;
     897               43:   Record.push_back(pch::STAT_CACHE);
     898               43:   Record.push_back(BucketOffset);
     899               43:   Record.push_back(NumStatEntries);
     900               43:   Stream.EmitRecordWithBlob(StatCacheAbbrev, Record, StatCacheData.str());
     901               43: }
     902                 : 
     903                 : //===----------------------------------------------------------------------===//
     904                 : // Source Manager Serialization
     905                 : //===----------------------------------------------------------------------===//
     906                 : 
     907                 : /// \brief Create an abbreviation for the SLocEntry that refers to a
     908                 : /// file.
     909               44: static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
     910                 :   using namespace llvm;
     911               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
     912               44:   Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_FILE_ENTRY));
     913               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
     914               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
     915               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
     916               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
     917               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
     918               44:   return Stream.EmitAbbrev(Abbrev);
     919                 : }
     920                 : 
     921                 : /// \brief Create an abbreviation for the SLocEntry that refers to a
     922                 : /// buffer.
     923               44: static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
     924                 :   using namespace llvm;
     925               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
     926               44:   Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_ENTRY));
     927               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
     928               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
     929               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
     930               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
     931               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
     932               44:   return Stream.EmitAbbrev(Abbrev);
     933                 : }
     934                 : 
     935                 : /// \brief Create an abbreviation for the SLocEntry that refers to a
     936                 : /// buffer's blob.
     937               44: static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream) {
     938                 :   using namespace llvm;
     939               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
     940               44:   Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_BLOB));
     941               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
     942               44:   return Stream.EmitAbbrev(Abbrev);
     943                 : }
     944                 : 
     945                 : /// \brief Create an abbreviation for the SLocEntry that refers to an
     946                 : /// buffer.
     947               44: static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) {
     948                 :   using namespace llvm;
     949               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
     950               44:   Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_INSTANTIATION_ENTRY));
     951               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
     952               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
     953               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
     954               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
     955               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length
     956               44:   return Stream.EmitAbbrev(Abbrev);
     957                 : }
     958                 : 
     959                 : /// \brief Writes the block containing the serialized form of the
     960                 : /// source manager.
     961                 : ///
     962                 : /// TODO: We should probably use an on-disk hash table (stored in a
     963                 : /// blob), indexed based on the file name, so that we only create
     964                 : /// entries for files that we actually need. In the common case (no
     965                 : /// errors), we probably won't have to create file entries for any of
     966                 : /// the files in the AST.
     967                 : void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
     968                 :                                         const Preprocessor &PP,
     969               44:                                         const char *isysroot) {
     970               44:   RecordData Record;
     971                 : 
     972                 :   // Enter the source manager block.
     973               44:   Stream.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
     974                 : 
     975                 :   // Abbreviations for the various kinds of source-location entries.
     976               44:   unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
     977               44:   unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
     978               44:   unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream);
     979               44:   unsigned SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(Stream);
     980                 : 
     981                 :   // Write the line table.
                       44: branch 1 taken
                        0: branch 2 not taken
     982               44:   if (SourceMgr.hasLineTable()) {
     983               44:     LineTableInfo &LineTable = SourceMgr.getLineTable();
     984                 : 
     985                 :     // Emit the file names
     986               44:     Record.push_back(LineTable.getNumFilenames());
                       89: branch 1 taken
                       44: branch 2 taken
     987              133:     for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
     988                 :       // Emit the file name
     989               89:       const char *Filename = LineTable.getFilename(I);
     990               89:       Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
                       89: branch 0 taken
                        0: branch 1 not taken
     991               89:       unsigned FilenameLen = Filename? strlen(Filename) : 0;
     992               89:       Record.push_back(FilenameLen);
                       89: branch 0 taken
                        0: branch 1 not taken
     993               89:       if (FilenameLen)
     994               89:         Record.insert(Record.end(), Filename, Filename + FilenameLen);
     995                 :     }
     996                 : 
     997                 :     // Emit the line entries
                       45: branch 4 taken
                       44: branch 5 taken
     998               89:     for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
     999                 :          L != LEnd; ++L) {
    1000                 :       // Emit the file ID
    1001               45:       Record.push_back(L->first);
    1002                 : 
    1003                 :       // Emit the line entries
    1004               45:       Record.push_back(L->second.size());
                      133: branch 4 taken
                       45: branch 5 taken
    1005              223:       for (std::vector<LineEntry>::iterator LE = L->second.begin(),
    1006               45:                                          LEEnd = L->second.end();
    1007                 :            LE != LEEnd; ++LE) {
    1008              133:         Record.push_back(LE->FileOffset);
    1009              133:         Record.push_back(LE->LineNo);
    1010              133:         Record.push_back(LE->FilenameID);
    1011              133:         Record.push_back((unsigned)LE->FileKind);
    1012              133:         Record.push_back(LE->IncludeOffset);
    1013                 :       }
    1014                 :     }
    1015               44:     Stream.EmitRecord(pch::SM_LINE_TABLE, Record);
    1016                 :   }
    1017                 : 
    1018                 :   // Write out entries for all of the header files we know about.
    1019               44:   HeaderSearch &HS = PP.getHeaderSearchInfo();
    1020               44:   Record.clear();
                       49: branch 3 taken
                       44: branch 4 taken
    1021              137:   for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
    1022               44:                                           E = HS.header_file_end();
    1023                 :        I != E; ++I) {
    1024               49:     Record.push_back(I->isImport);
    1025               49:     Record.push_back(I->DirInfo);
    1026               49:     Record.push_back(I->NumIncludes);
    1027               49:     AddIdentifierRef(I->ControllingMacro, Record);
    1028               49:     Stream.EmitRecord(pch::SM_HEADER_FILE_INFO, Record);
    1029               49:     Record.clear();
    1030                 :   }
    1031                 : 
    1032                 :   // Write out the source location entry table. We skip the first
    1033                 :   // entry, which is always the same dummy entry.
    1034               44:   std::vector<uint32_t> SLocEntryOffsets;
    1035               44:   RecordData PreloadSLocs;
    1036               44:   SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1);
                      189: branch 1 taken
                       44: branch 2 taken
    1037              233:   for (unsigned I = 1, N = SourceMgr.sloc_entry_size(); I != N; ++I) {
    1038                 :     // Get this source location entry.
    1039              189:     const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I);
    1040                 :     
    1041                 :     // Record the offset of this source-location entry.
    1042              189:     SLocEntryOffsets.push_back(Stream.GetCurrentBitNo());
    1043                 : 
    1044                 :     // Figure out which record code to use.
    1045                 :     unsigned Code;
                       95: branch 1 taken
                       94: branch 2 taken
    1046              189:     if (SLoc->isFile()) {
                       48: branch 2 taken
                       47: branch 3 taken
    1047               95:       if (SLoc->getFile().getContentCache()->Entry)
    1048               48:         Code = pch::SM_SLOC_FILE_ENTRY;
    1049                 :       else
    1050               47:         Code = pch::SM_SLOC_BUFFER_ENTRY;
    1051                 :     } else
    1052               94:       Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
    1053              189:     Record.clear();
    1054              189:     Record.push_back(Code);
    1055                 : 
    1056              189:     Record.push_back(SLoc->getOffset());
                       95: branch 1 taken
                       94: branch 2 taken
    1057              189:     if (SLoc->isFile()) {
    1058               95:       const SrcMgr::FileInfo &File = SLoc->getFile();
    1059               95:       Record.push_back(File.getIncludeLoc().getRawEncoding());
    1060               95:       Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
    1061               95:       Record.push_back(File.hasLineDirectives());
    1062                 : 
    1063               95:       const SrcMgr::ContentCache *Content = File.getContentCache();
                       48: branch 0 taken
                       47: branch 1 taken
    1064               95:       if (Content->Entry) {
    1065                 :         // The source location entry is a file. The blob associated
    1066                 :         // with this entry is the file name.
    1067                 : 
    1068                 :         // Turn the file name into an absolute path, if it isn't already.
    1069               48:         const char *Filename = Content->Entry->getName();
    1070               48:         llvm::sys::Path FilePath(Filename, strlen(Filename));
    1071               48:         std::string FilenameStr;
                        0: branch 1 not taken
                       48: branch 2 taken
    1072               48:         if (!FilePath.isAbsolute()) {
    1073                0:           llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
    1074                0:           P.appendComponent(FilePath.str());
    1075                0:           FilenameStr = P.str();
    1076                0:           Filename = FilenameStr.c_str();
    1077                 :         }
    1078                 : 
    1079               48:         Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
    1080               48:         Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename);
    1081                 : 
    1082                 :         // FIXME: For now, preload all file source locations, so that
    1083                 :         // we get the appropriate File entries in the reader. This is
    1084                 :         // a temporary measure.
    1085               48:         PreloadSLocs.push_back(SLocEntryOffsets.size());
    1086                 :       } else {
    1087                 :         // The source location entry is a buffer. The blob associated
    1088                 :         // with this entry contains the contents of the buffer.
    1089                 : 
    1090                 :         // We add one to the size so that we capture the trailing NULL
    1091                 :         // that is required by llvm::MemoryBuffer::getMemBuffer (on
    1092                 :         // the reader side).
    1093               47:         const llvm::MemoryBuffer *Buffer = Content->getBuffer();
    1094               47:         const char *Name = Buffer->getBufferIdentifier();
    1095                 :         Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
    1096               47:                                   llvm::StringRef(Name, strlen(Name) + 1));
    1097               47:         Record.clear();
    1098               47:         Record.push_back(pch::SM_SLOC_BUFFER_BLOB);
    1099                 :         Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
    1100                 :                                   llvm::StringRef(Buffer->getBufferStart(),
    1101               47:                                                   Buffer->getBufferSize() + 1));
    1102                 : 
                       45: branch 1 taken
                        2: branch 2 taken
    1103               47:         if (strcmp(Name, "<built-in>") == 0)
    1104               45:           PreloadSLocs.push_back(SLocEntryOffsets.size());
    1105                 :       }
    1106                 :     } else {
    1107                 :       // The source location entry is an instantiation.
    1108               94:       const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
    1109               94:       Record.push_back(Inst.getSpellingLoc().getRawEncoding());
    1110               94:       Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
    1111               94:       Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
    1112                 : 
    1113                 :       // Compute the token length for this macro expansion.
    1114               94:       unsigned NextOffset = SourceMgr.getNextOffset();
                       90: branch 0 taken
                        4: branch 1 taken
    1115               94:       if (I + 1 != N)
    1116               90:         NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset();
    1117               94:       Record.push_back(NextOffset - SLoc->getOffset() - 1);
    1118               94:       Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
    1119                 :     }
    1120                 :   }
    1121                 : 
    1122               44:   Stream.ExitBlock();
    1123                 : 
                        0: branch 1 not taken
                       44: branch 2 taken
    1124               44:   if (SLocEntryOffsets.empty())
    1125                0:     return;
    1126                 : 
    1127                 :   // Write the source-location offsets table into the PCH block. This
    1128                 :   // table is used for lazily loading source-location information.
    1129                 :   using namespace llvm;
    1130               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
    1131               44:   Abbrev->Add(BitCodeAbbrevOp(pch::SOURCE_LOCATION_OFFSETS));
    1132               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
    1133               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // next offset
    1134               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
    1135               44:   unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbrev);
    1136                 : 
    1137               44:   Record.clear();
    1138               44:   Record.push_back(pch::SOURCE_LOCATION_OFFSETS);
    1139               44:   Record.push_back(SLocEntryOffsets.size());
    1140               44:   Record.push_back(SourceMgr.getNextOffset());
    1141                 :   Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
    1142                 :                             (const char *)&SLocEntryOffsets.front(),
    1143               44:                            SLocEntryOffsets.size()*sizeof(SLocEntryOffsets[0]));
    1144                 : 
    1145                 :   // Write the source location entry preloads array, telling the PCH
    1146                 :   // reader which source locations entries it should load eagerly.
                       44: branch 2 taken
                        0: branch 3 not taken
                       44: branch 5 taken
                        0: branch 6 not taken
                       44: branch 8 taken
                        0: branch 9 not taken
    1147               44:   Stream.EmitRecord(pch::SOURCE_LOCATION_PRELOADS, PreloadSLocs);
    1148                 : }
    1149                 : 
    1150                 : //===----------------------------------------------------------------------===//
    1151                 : // Preprocessor Serialization
    1152                 : //===----------------------------------------------------------------------===//
    1153                 : 
    1154                 : /// \brief Writes the block containing the serialized form of the
    1155                 : /// preprocessor.
    1156                 : ///
    1157               44: void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
    1158               44:   RecordData Record;
    1159                 : 
    1160                 :   // If the preprocessor __COUNTER__ value has been bumped, remember it.
                        2: branch 1 taken
                       42: branch 2 taken
    1161               44:   if (PP.getCounterValue() != 0) {
    1162                2:     Record.push_back(PP.getCounterValue());
    1163                2:     Stream.EmitRecord(pch::PP_COUNTER_VALUE, Record);
    1164                2:     Record.clear();
    1165                 :   }
    1166                 : 
    1167                 :   // Enter the preprocessor block.
    1168               44:   Stream.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 2);
    1169                 : 
    1170                 :   // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
    1171                 :   // FIXME: use diagnostics subsystem for localization etc.
                        0: branch 1 not taken
                       44: branch 2 taken
    1172               44:   if (PP.SawDateOrTime())
    1173                0:     fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
    1174                 : 
    1175                 :   // Loop over all the macro definitions that are live at the end of the file,
    1176                 :   // emitting each to the PP section.
                     5221: branch 4 taken
                       44: branch 5 taken
    1177             5265:   for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
    1178                 :        I != E; ++I) {
    1179                 :     // FIXME: This emits macros in hash table order, we should do it in a stable
    1180                 :     // order so that output is reproducible.
    1181             5221:     MacroInfo *MI = I->second;
    1182                 : 
    1183                 :     // Don't emit builtin macros like __LINE__ to the PCH file unless they have
    1184                 :     // been redefined by the header (in which case they are not isBuiltinMacro).
                      572: branch 1 taken
                     4649: branch 2 taken
    1185             5221:     if (MI->isBuiltinMacro())
    1186              572:       continue;
    1187                 : 
    1188             4649:     AddIdentifierRef(I->first, Record);
    1189             4649:     MacroOffsets[I->first] = Stream.GetCurrentBitNo();
    1190             4649:     Record.push_back(MI->getDefinitionLoc().getRawEncoding());
    1191             4649:     Record.push_back(MI->isUsed());
    1192                 : 
    1193                 :     unsigned Code;
                     4634: branch 1 taken
                       15: branch 2 taken
    1194             4649:     if (MI->isObjectLike()) {
    1195             4634:       Code = pch::PP_MACRO_OBJECT_LIKE;
    1196                 :     } else {
    1197               15:       Code = pch::PP_MACRO_FUNCTION_LIKE;
    1198                 : 
    1199               15:       Record.push_back(MI->isC99Varargs());
    1200               15:       Record.push_back(MI->isGNUVarargs());
    1201               15:       Record.push_back(MI->getNumArgs());
                       24: branch 2 taken
                       15: branch 3 taken
    1202               39:       for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
    1203                 :            I != E; ++I)
    1204               24:         AddIdentifierRef(*I, Record);
    1205                 :     }
    1206             4649:     Stream.EmitRecord(Code, Record);
    1207             4649:     Record.clear();
    1208                 : 
    1209                 :     // Emit the tokens array.
                     5879: branch 1 taken
                     4649: branch 2 taken
    1210            10528:     for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
    1211                 :       // Note that we know that the preprocessor does not have any annotation
    1212                 :       // tokens in it because they are created by the parser, and thus can't be
    1213                 :       // in a macro definition.
    1214             5879:       const Token &Tok = MI->getReplacementToken(TokNo);
    1215                 : 
    1216             5879:       Record.push_back(Tok.getLocation().getRawEncoding());
    1217             5879:       Record.push_back(Tok.getLength());
    1218                 : 
    1219                 :       // FIXME: When reading literal tokens, reconstruct the literal pointer if
    1220                 :       // it is needed.
    1221             5879:       AddIdentifierRef(Tok.getIdentifierInfo(), Record);
    1222                 : 
    1223                 :       // FIXME: Should translate token kind to a stable encoding.
    1224             5879:       Record.push_back(Tok.getKind());
    1225                 :       // FIXME: Should translate token flags to a stable encoding.
    1226             5879:       Record.push_back(Tok.getFlags());
    1227                 : 
    1228             5879:       Stream.EmitRecord(pch::PP_TOKEN, Record);
    1229             5879:       Record.clear();
    1230                 :     }
    1231             4649:     ++NumMacros;
    1232                 :   }
    1233               44:   Stream.ExitBlock();
    1234               44: }
    1235                 : 
    1236               44: void PCHWriter::WriteComments(ASTContext &Context) {
    1237                 :   using namespace llvm;
    1238                 : 
                        7: branch 1 taken
                       37: branch 2 taken
    1239               44:   if (Context.Comments.empty())
    1240                7:     return;
    1241                 : 
    1242               37:   BitCodeAbbrev *CommentAbbrev = new BitCodeAbbrev();
    1243               37:   CommentAbbrev->Add(BitCodeAbbrevOp(pch::COMMENT_RANGES));
    1244               37:   CommentAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
    1245               37:   unsigned CommentCode = Stream.EmitAbbrev(CommentAbbrev);
    1246                 : 
    1247               37:   RecordData Record;
    1248               37:   Record.push_back(pch::COMMENT_RANGES);
    1249                 :   Stream.EmitRecordWithBlob(CommentCode, Record,
    1250                 :                             (const char*)&Context.Comments[0],
    1251               37:                             Context.Comments.size() * sizeof(SourceRange));
    1252                 : }
    1253                 : 
    1254                 : //===----------------------------------------------------------------------===//
    1255                 : // Type Serialization
    1256                 : //===----------------------------------------------------------------------===//
    1257                 : 
    1258                 : /// \brief Write the representation of a type to the PCH stream.
    1259              373: void PCHWriter::WriteType(QualType T) {
    1260              373:   pch::TypeID &ID = TypeIDs[T];
                        0: branch 0 not taken
                      373: branch 1 taken
    1261              373:   if (ID == 0) // we haven't seen this type before.
    1262                0:     ID = NextTypeID++;
    1263                 : 
    1264                 :   // Record the offset for this type.
                      373: branch 1 taken
                        0: branch 2 not taken
    1265              373:   if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
    1266              373:     TypeOffsets.push_back(Stream.GetCurrentBitNo());
                        0: branch 1 not taken
                        0: branch 2 not taken
    1267                0:   else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
    1268                0:     TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
    1269                0:     TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = Stream.GetCurrentBitNo();
    1270                 :   }
    1271                 : 
    1272              373:   RecordData Record;
    1273                 : 
    1274                 :   // Emit the type's representation.
    1275              373:   PCHTypeWriter W(*this, Record);
    1276                 : 
                        1: branch 1 taken
                      372: branch 2 taken
    1277              373:   if (T.hasLocalNonFastQualifiers()) {
    1278                1:     Qualifiers Qs = T.getLocalQualifiers();
    1279                1:     AddTypeRef(T.getLocalUnqualifiedType(), Record);
    1280                1:     Record.push_back(Qs.getAsOpaqueValue());
    1281                1:     W.Code = pch::TYPE_EXT_QUAL;
    1282                 :   } else {
                        0: branch 2 not taken
                        2: branch 3 taken
                      100: branch 4 taken
                        2: branch 5 taken
                        8: branch 6 taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                       24: branch 9 taken
                        6: branch 10 taken
                        1: branch 11 taken
                        1: branch 12 taken
                        4: branch 13 taken
                       47: branch 14 taken
                        6: branch 15 taken
                       42: branch 16 taken
                       39: branch 17 taken
                        4: branch 18 taken
                        0: branch 19 not taken
                       25: branch 20 taken
                        5: branch 21 taken
                        0: branch 22 not taken
                        0: branch 23 not taken
                        0: branch 24 not taken
                        0: branch 25 not taken
                       20: branch 26 taken
                       36: branch 27 taken
                        0: branch 28 not taken
                        0: branch 29 not taken
    1283              372:     switch (T->getTypeClass()) {
    1284                 :       // For all of the concrete, non-dependent types, call the
    1285                 :       // appropriate visitor function.
    1286                 : #define TYPE(Class, Base) \
    1287                 :     case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
    1288                 : #define ABSTRACT_TYPE(Class, Base)
    1289                 : #define DEPENDENT_TYPE(Class, Base)
    1290                 : #include "clang/AST/TypeNodes.def"
    1291                 : 
    1292                 :       // For all of the dependent type nodes (which only occur in C++
    1293                 :       // templates), produce an error.
    1294                 : #define TYPE(Class, Base)
    1295                 : #define DEPENDENT_TYPE(Class, Base) case Type::Class:
    1296                 : #include "clang/AST/TypeNodes.def"
    1297                0:       assert(false && "Cannot serialize dependent type nodes");
    1298                 :       break;
    1299                 :     }
    1300                 :   }
    1301                 : 
    1302                 :   // Emit the serialized record.
    1303              373:   Stream.EmitRecord(W.Code, Record);
    1304                 : 
    1305                 :   // Flush any expressions that were written as part of this type.
    1306              373:   FlushStmts();
    1307              373: }
    1308                 : 
    1309                 : //===----------------------------------------------------------------------===//
    1310                 : // Declaration Serialization
    1311                 : //===----------------------------------------------------------------------===//
    1312                 : 
    1313                 : /// \brief Write the block containing all of the declaration IDs
    1314                 : /// lexically declared within the given DeclContext.
    1315                 : ///
    1316                 : /// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
    1317                 : /// bistream, or 0 if no block was written.
    1318                 : uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
    1319              208:                                                  DeclContext *DC) {
                       93: branch 1 taken
                      115: branch 2 taken
    1320              208:   if (DC->decls_empty())
    1321               93:     return 0;
    1322                 : 
    1323              115:   uint64_t Offset = Stream.GetCurrentBitNo();
    1324              115:   RecordData Record;
                      496: branch 4 taken
                      115: branch 5 taken
    1325              611:   for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
    1326                 :          D != DEnd; ++D)
    1327              496:     AddDeclRef(*D, Record);
    1328                 : 
    1329              115:   ++NumLexicalDeclContexts;
    1330              115:   Stream.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
    1331              115:   return Offset;
    1332                 : }
    1333                 : 
    1334                 : /// \brief Write the block containing all of the declaration IDs
    1335                 : /// visible from the given DeclContext.
    1336                 : ///
    1337                 : /// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
    1338                 : /// bistream, or 0 if no block was written.
    1339                 : uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
    1340              208:                                                  DeclContext *DC) {
                        5: branch 1 taken
                      203: branch 2 taken
    1341              208:   if (DC->getPrimaryContext() != DC)
    1342                5:     return 0;
    1343                 : 
    1344                 :   // Since there is no name lookup into functions or methods, and we
    1345                 :   // perform name lookup for the translation unit via the
    1346                 :   // IdentifierInfo chains, don't bother to build a
    1347                 :   // visible-declarations table for these entities.
                      108: branch 1 taken
                       95: branch 2 taken
                       44: branch 4 taken
                       64: branch 5 taken
                      139: branch 6 taken
                       64: branch 7 taken
    1348              203:   if (DC->isFunctionOrMethod() || DC->isTranslationUnit())
    1349              139:     return 0;
    1350                 : 
    1351                 :   // Force the DeclContext to build a its name-lookup table.
    1352               64:   DC->lookup(DeclarationName());
    1353                 : 
    1354                 :   // Serialize the contents of the mapping used for lookup. Note that,
    1355                 :   // although we have two very different code paths, the serialized
    1356                 :   // representation is the same for both cases: a declaration name,
    1357                 :   // followed by a size, followed by references to the visible
    1358                 :   // declarations that have that name.
    1359               64:   uint64_t Offset = Stream.GetCurrentBitNo();
    1360               64:   RecordData Record;
    1361               64:   StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
                       20: branch 0 taken
                       44: branch 1 taken
    1362               64:   if (!Map)
    1363               20:     return 0;
    1364                 : 
                      110: branch 5 taken
                       44: branch 6 taken
    1365              154:   for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
    1366                 :        D != DEnd; ++D) {
    1367              110:     AddDeclarationName(D->first, Record);
    1368              110:     DeclContext::lookup_result Result = D->second.getLookupResult(Context);
    1369              110:     Record.push_back(Result.second - Result.first);
                      116: branch 0 taken
                      110: branch 1 taken
    1370              226:     for (; Result.first != Result.second; ++Result.first)
    1371              116:       AddDeclRef(*Result.first, Record);
    1372                 :   }
    1373                 : 
                        0: branch 1 not taken
                       44: branch 2 taken
    1374               44:   if (Record.size() == 0)
    1375                0:     return 0;
    1376                 : 
    1377               44:   Stream.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
    1378               44:   ++NumVisibleDeclContexts;
    1379               44:   return Offset;
    1380                 : }
    1381                 : 
    1382                 : //===----------------------------------------------------------------------===//
    1383                 : // Global Method Pool and Selector Serialization
    1384                 : //===----------------------------------------------------------------------===//
    1385                 : 
    1386                 : namespace {
    1387                 : // Trait used for the on-disk hash table used in the method pool.
    1388                 : class PCHMethodPoolTrait {
    1389                 :   PCHWriter &Writer;
    1390                 : 
    1391                 : public:
    1392                 :   typedef Selector key_type;
    1393                 :   typedef key_type key_type_ref;
    1394                 : 
    1395                 :   typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
    1396                 :   typedef const data_type& data_type_ref;
    1397                 : 
    1398                6:   explicit PCHMethodPoolTrait(PCHWriter &Writer) : Writer(Writer) { }
    1399                 : 
    1400               25:   static unsigned ComputeHash(Selector Sel) {
    1401               25:     unsigned N = Sel.getNumArgs();
                       20: branch 0 taken
                        5: branch 1 taken
    1402               25:     if (N == 0)
    1403               20:       ++N;
    1404               25:     unsigned R = 5381;
                       25: branch 0 taken
                       25: branch 1 taken
    1405               50:     for (unsigned I = 0; I != N; ++I)
                       25: branch 1 taken
                        0: branch 2 not taken
    1406               25:       if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
    1407               25:         R = llvm::HashString(II->getName(), R);
    1408               25:     return R;
    1409                 :   }
    1410                 : 
    1411                 :   std::pair<unsigned,unsigned>
    1412                 :     EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel,
    1413               25:                       data_type_ref Methods) {
                        5: branch 1 taken
                       20: branch 2 taken
    1414               25:     unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
    1415               25:     clang::io::Emit16(Out, KeyLen);
    1416               25:     unsigned DataLen = 2 + 2; // 2 bytes for each of the method counts
                       26: branch 0 taken
                       25: branch 1 taken
    1417               51:     for (const ObjCMethodList *Method = &Methods.first; Method;
    1418                 :          Method = Method->Next)
                       20: branch 0 taken
                        6: branch 1 taken
    1419               26:       if (Method->Method)
    1420               20:         DataLen += 4;
                       25: branch 0 taken
                       25: branch 1 taken
    1421               50:     for (const ObjCMethodList *Method = &Methods.second; Method;
    1422                 :          Method = Method->Next)
                        6: branch 0 taken
                       19: branch 1 taken
    1423               25:       if (Method->Method)
    1424                6:         DataLen += 4;
    1425               25:     clang::io::Emit16(Out, DataLen);
    1426               25:     return std::make_pair(KeyLen, DataLen);
    1427                 :   }
    1428                 : 
    1429               25:   void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) {
    1430               25:     uint64_t Start = Out.tell();
                        0: branch 0 not taken
                       25: branch 1 taken
    1431               25:     assert((Start >> 32) == 0 && "Selector key offset too large");
    1432               25:     Writer.SetSelectorOffset(Sel, Start);
    1433               25:     unsigned N = Sel.getNumArgs();
    1434               25:     clang::io::Emit16(Out, N);
                       20: branch 0 taken
                        5: branch 1 taken
    1435               25:     if (N == 0)
    1436               20:       N = 1;
                       25: branch 0 taken
                       25: branch 1 taken
    1437               50:     for (unsigned I = 0; I != N; ++I)
    1438                 :       clang::io::Emit32(Out,
    1439               25:                     Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
    1440               25:   }
    1441                 : 
    1442                 :   void EmitData(llvm::raw_ostream& Out, key_type_ref,
    1443               25:                 data_type_ref Methods, unsigned DataLen) {
    1444               25:     uint64_t Start = Out.tell(); (void)Start;
    1445               25:     unsigned NumInstanceMethods = 0;
                       26: branch 0 taken
                       25: branch 1 taken
    1446               51:     for (const ObjCMethodList *Method = &Methods.first; Method;
    1447                 :          Method = Method->Next)
                       20: branch 0 taken
                        6: branch 1 taken
    1448               26:       if (Method->Method)
    1449               20:         ++NumInstanceMethods;
    1450                 : 
    1451               25:     unsigned NumFactoryMethods = 0;
                       25: branch 0 taken
                       25: branch 1 taken
    1452               50:     for (const ObjCMethodList *Method = &Methods.second; Method;
    1453                 :          Method = Method->Next)
                        6: branch 0 taken
                       19: branch 1 taken
    1454               25:       if (Method->Method)
    1455                6:         ++NumFactoryMethods;
    1456                 : 
    1457               25:     clang::io::Emit16(Out, NumInstanceMethods);
    1458               25:     clang::io::Emit16(Out, NumFactoryMethods);
                       26: branch 0 taken
                       25: branch 1 taken
    1459               51:     for (const ObjCMethodList *Method = &Methods.first; Method;
    1460                 :          Method = Method->Next)
                       20: branch 0 taken
                        6: branch 1 taken
    1461               26:       if (Method->Method)
    1462               20:         clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
                       25: branch 0 taken
                       25: branch 1 taken
    1463               50:     for (const ObjCMethodList *Method = &Methods.second; Method;
    1464                 :          Method = Method->Next)
                        6: branch 0 taken
                       19: branch 1 taken
    1465               25:       if (Method->Method)
    1466                6:         clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
    1467                 : 
                       25: branch 1 taken
                        0: branch 2 not taken
    1468               25:     assert(Out.tell() - Start == DataLen && "Data length is wrong");
    1469               25:   }
    1470                 : };
    1471                 : } // end anonymous namespace
    1472                 : 
    1473                 : /// \brief Write the method pool into the PCH file.
    1474                 : ///
    1475                 : /// The method pool contains both instance and factory methods, stored
    1476                 : /// in an on-disk hash table indexed by the selector.
    1477               44: void PCHWriter::WriteMethodPool(Sema &SemaRef) {
    1478                 :   using namespace llvm;
    1479                 : 
    1480                 :   // Create and write out the blob that contains the instance and
    1481                 :   // factor method pools.
    1482               44:   bool Empty = true;
    1483                 :   {
    1484               44:     OnDiskChainedHashTableGenerator<PCHMethodPoolTrait> Generator;
    1485                 : 
    1486                 :     // Create the on-disk hash table representation. Start by
    1487                 :     // iterating through the instance method pool.
    1488               44:     PCHMethodPoolTrait::key_type Key;
    1489               44:     unsigned NumSelectorsInMethodPool = 0;
                       19: branch 3 taken
                       44: branch 4 taken
    1490               63:     for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
    1491               44:            Instance = SemaRef.InstanceMethodPool.begin(),
    1492               44:            InstanceEnd = SemaRef.InstanceMethodPool.end();
    1493                 :          Instance != InstanceEnd; ++Instance) {
    1494                 :       // Check whether there is a factory method with the same
    1495                 :       // selector.
    1496                 :       llvm::DenseMap<Selector, ObjCMethodList>::iterator Factory
    1497               19:         = SemaRef.FactoryMethodPool.find(Instance->first);
    1498                 : 
                       19: branch 3 taken
                        0: branch 4 not taken
    1499               19:       if (Factory == SemaRef.FactoryMethodPool.end())
    1500                 :         Generator.insert(Instance->first,
    1501                 :                          std::make_pair(Instance->second,
    1502               19:                                         ObjCMethodList()));
    1503                 :       else
    1504                 :         Generator.insert(Instance->first,
    1505                0:                          std::make_pair(Instance->second, Factory->second));
    1506                 : 
    1507               19:       ++NumSelectorsInMethodPool;
    1508               19:       Empty = false;
    1509                 :     }
    1510                 : 
    1511                 :     // Now iterate through the factory method pool, to pick up any
    1512                 :     // selectors that weren't already in the instance method pool.
                        6: branch 3 taken
                       44: branch 4 taken
    1513               50:     for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
    1514               44:            Factory = SemaRef.FactoryMethodPool.begin(),
    1515               44:            FactoryEnd = SemaRef.FactoryMethodPool.end();
    1516                 :          Factory != FactoryEnd; ++Factory) {
    1517                 :       // Check whether there is an instance method with the same
    1518                 :       // selector. If so, there is no work to do here.
    1519                 :       llvm::DenseMap<Selector, ObjCMethodList>::iterator Instance
    1520                6:         = SemaRef.InstanceMethodPool.find(Factory->first);
    1521                 : 
                        6: branch 3 taken
                        0: branch 4 not taken
    1522                6:       if (Instance == SemaRef.InstanceMethodPool.end()) {
    1523                 :         Generator.insert(Factory->first,
    1524                6:                          std::make_pair(ObjCMethodList(), Factory->second));
    1525                6:         ++NumSelectorsInMethodPool;
    1526                 :       }
    1527                 : 
    1528                6:       Empty = false;
    1529                 :     }
    1530                 : 
                       38: branch 0 taken
                        6: branch 1 taken
                       38: branch 3 taken
                        0: branch 4 not taken
                       38: branch 5 taken
                        6: branch 6 taken
    1531               44:     if (Empty && SelectorOffsets.empty())
    1532               38:       return;
    1533                 : 
    1534                 :     // Create the on-disk hash table in a buffer.
    1535                6:     llvm::SmallString<4096> MethodPool;
    1536                 :     uint32_t BucketOffset;
    1537                6:     SelectorOffsets.resize(SelVector.size());
    1538                 :     {
    1539                6:       PCHMethodPoolTrait Trait(*this);
    1540                6:       llvm::raw_svector_ostream Out(MethodPool);
    1541                 :       // Make sure that no bucket is at offset 0
    1542                6:       clang::io::Emit32(Out, 0);
    1543                6:       BucketOffset = Generator.Emit(Out, Trait);
    1544                 : 
    1545                 :       // For every selector that we have seen but which was not
    1546                 :       // written into the hash table, write the selector itself and
    1547                 :       // record it's offset.
                       25: branch 1 taken
                        6: branch 2 taken
    1548               31:       for (unsigned I = 0, N = SelVector.size(); I != N; ++I)
                        0: branch 1 not taken
                       25: branch 2 taken
    1549               25:         if (SelectorOffsets[I] == 0)
    1550                6:           Trait.EmitKey(Out, SelVector[I], 0);
    1551                 :     }
    1552                 : 
    1553                 :     // Create a blob abbreviation
    1554                6:     BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
    1555                6:     Abbrev->Add(BitCodeAbbrevOp(pch::METHOD_POOL));
    1556                6:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
    1557                6:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
    1558                6:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
    1559                6:     unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbrev);
    1560                 : 
    1561                 :     // Write the method pool
    1562                6:     RecordData Record;
    1563                6:     Record.push_back(pch::METHOD_POOL);
    1564                6:     Record.push_back(BucketOffset);
    1565                6:     Record.push_back(NumSelectorsInMethodPool);
    1566                6:     Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str());
    1567                 : 
    1568                 :     // Create a blob abbreviation for the selector table offsets.
    1569                6:     Abbrev = new BitCodeAbbrev();
    1570                6:     Abbrev->Add(BitCodeAbbrevOp(pch::SELECTOR_OFFSETS));
    1571                6:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // index
    1572                6:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
    1573                6:     unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
    1574                 : 
    1575                 :     // Write the selector offsets table.
    1576                6:     Record.clear();
    1577                6:     Record.push_back(pch::SELECTOR_OFFSETS);
    1578                6:     Record.push_back(SelectorOffsets.size());
    1579                 :     Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
    1580                 :                               (const char *)&SelectorOffsets.front(),
                        6: branch 6 taken
                       38: branch 7 taken
    1581                6:                               SelectorOffsets.size() * 4);
    1582                 :   }
    1583                 : }
    1584                 : 
    1585                 : //===----------------------------------------------------------------------===//
    1586                 : // Identifier Table Serialization
    1587                 : //===----------------------------------------------------------------------===//
    1588                 : 
    1589                 : namespace {
    1590                 : class PCHIdentifierTableTrait {
    1591                 :   PCHWriter &Writer;
    1592                 :   Preprocessor &PP;
    1593                 : 
    1594                 :   /// \brief Determines whether this is an "interesting" identifier
    1595                 :   /// that needs a full IdentifierInfo structure written into the hash
    1596                 :   /// table.
    1597            79372:   static bool isInterestingIdentifier(const IdentifierInfo *II) {
    1598                 :     return II->isPoisoned() ||
    1599                 :       II->isExtensionToken() ||
    1600                 :       II->hasMacroDefinition() ||
    1601                 :       II->getObjCOrBuiltinID() ||
                    79284: branch 1 taken
                       88: branch 2 taken
                    79116: branch 4 taken
                      168: branch 5 taken
                    68674: branch 7 taken
                    10442: branch 8 taken
                    10310: branch 10 taken
                    58364: branch 11 taken
                      608: branch 13 taken
                     9702: branch 14 taken
    1602            79372:       II->getFETokenInfo<void>();
    1603                 :   }
    1604                 : 
    1605                 : public:
    1606                 :   typedef const IdentifierInfo* key_type;
    1607                 :   typedef key_type  key_type_ref;
    1608                 : 
    1609                 :   typedef pch::IdentID data_type;
    1610                 :   typedef data_type data_type_ref;
    1611                 : 
    1612               44:   PCHIdentifierTableTrait(PCHWriter &Writer, Preprocessor &PP)
    1613               44:     : Writer(Writer), PP(PP) { }
    1614                 : 
    1615            39686:   static unsigned ComputeHash(const IdentifierInfo* II) {
    1616            39686:     return llvm::HashString(II->getName());
    1617                 :   }
    1618                 : 
    1619                 :   std::pair<unsigned,unsigned>
    1620                 :     EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II,
    1621            39686:                       pch::IdentID ID) {
    1622            39686:     unsigned KeyLen = II->getLength() + 1;
    1623            39686:     unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
                    34835: branch 1 taken
                     4851: branch 2 taken
    1624            39686:     if (isInterestingIdentifier(II)) {
    1625            34835:       DataLen += 2; // 2 bytes for builtin ID, flags
                     5221: branch 1 taken
                    29614: branch 2 taken
                     4649: branch 5 taken
                      572: branch 6 taken
                     4649: branch 7 taken
                    30186: branch 8 taken
    1626            34835:       if (II->hasMacroDefinition() &&
    1627                 :           !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro())
    1628             4649:         DataLen += 4;
                      319: branch 4 taken
                    34835: branch 5 taken
    1629            69989:       for (IdentifierResolver::iterator D = IdentifierResolver::begin(II),
    1630            34835:                                      DEnd = IdentifierResolver::end();
    1631                 :            D != DEnd; ++D)
    1632              319:         DataLen += sizeof(pch::DeclID);
    1633                 :     }
    1634            39686:     clang::io::Emit16(Out, DataLen);
    1635                 :     // We emit the key length after the data length so that every
    1636                 :     // string is preceded by a 16-bit length. This matches the PTH
    1637                 :     // format for storing identifiers.
    1638            39686:     clang::io::Emit16(Out, KeyLen);
    1639            39686:     return std::make_pair(KeyLen, DataLen);
    1640                 :   }
    1641                 : 
    1642                 :   void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II,
    1643            39686:                unsigned KeyLen) {
    1644                 :     // Record the location of the key data.  This is used when generating
    1645                 :     // the mapping from persistent IDs to strings.
    1646            39686:     Writer.SetIdentifierOffset(II, Out.tell());
    1647            39686:     Out.write(II->getNameStart(), KeyLen);
    1648            39686:   }
    1649                 : 
    1650                 :   void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II,
    1651            39686:                 pch::IdentID ID, unsigned) {
                     4851: branch 1 taken
                    34835: branch 2 taken
    1652            39686:     if (!isInterestingIdentifier(II)) {
    1653             4851:       clang::io::Emit32(Out, ID << 1);
    1654             4851:       return;
    1655                 :     }
    1656                 : 
    1657            34835:     clang::io::Emit32(Out, (ID << 1) | 0x01);
    1658            34835:     uint32_t Bits = 0;
    1659                 :     bool hasMacroDefinition =
    1660                 :       II->hasMacroDefinition() &&
                     5221: branch 1 taken
                    29614: branch 2 taken
                     4649: branch 5 taken
                      572: branch 6 taken
    1661            34835:       !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro();
    1662            34835:     Bits = (uint32_t)II->getObjCOrBuiltinID();
    1663            34835:     Bits = (Bits << 1) | unsigned(hasMacroDefinition);
    1664            34835:     Bits = (Bits << 1) | unsigned(II->isExtensionToken());
    1665            34835:     Bits = (Bits << 1) | unsigned(II->isPoisoned());
    1666            34835:     Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
    1667            34835:     clang::io::Emit16(Out, Bits);
    1668                 : 
                     4649: branch 0 taken
                    30186: branch 1 taken
    1669            34835:     if (hasMacroDefinition)
    1670             4649:       clang::io::Emit32(Out, Writer.getMacroOffset(II));
    1671                 : 
    1672                 :     // Emit the declaration IDs in reverse order, because the
    1673                 :     // IdentifierResolver provides the declarations as they would be
    1674                 :     // visible (e.g., the function "stat" would come before the struct
    1675                 :     // "stat"), but IdentifierResolver::AddDeclToIdentifierChain()
    1676                 :     // adds declarations to the end of the list (so we need to see the
    1677                 :     // struct "status" before the function "status").
    1678                 :     llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
    1679            34835:                                         IdentifierResolver::end());
                      319: branch 3 taken
                    34835: branch 4 taken
    1680            69989:     for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
    1681            34835:                                                       DEnd = Decls.rend();
    1682                 :          D != DEnd; ++D)
    1683            35154:       clang::io::Emit32(Out, Writer.getDeclID(*D));
    1684                 :   }
    1685                 : };
    1686                 : } // end anonymous namespace
    1687                 : 
    1688                 : /// \brief Write the identifier table into the PCH file.
    1689                 : ///
    1690                 : /// The identifier table consists of a blob containing string data
    1691                 : /// (the actual identifiers themselves) and a separate "offsets" index
    1692                 : /// that maps identifier IDs to locations within the blob.
    1693               44: void PCHWriter::WriteIdentifierTable(Preprocessor &PP) {
    1694                 :   using namespace llvm;
    1695                 : 
    1696                 :   // Create and write out the blob that contains the identifier
    1697                 :   // strings.
    1698                 :   {
    1699               44:     OnDiskChainedHashTableGenerator<PCHIdentifierTableTrait> Generator;
    1700                 : 
    1701                 :     // Look for any identifiers that were named while processing the
    1702                 :     // headers, but are otherwise not needed. We add these to the hash
    1703                 :     // table to enable checking of the predefines buffer in the case
    1704                 :     // where the user adds new macro definitions when building the PCH
    1705                 :     // file.
                    39686: branch 4 taken
                       44: branch 5 taken
    1706            39774:     for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),
    1707               44:                                 IDEnd = PP.getIdentifierTable().end();
    1708                 :          ID != IDEnd; ++ID)
    1709            39686:       getIdentifierRef(ID->second);
    1710                 : 
    1711                 :     // Create the on-disk hash table representation.
    1712               44:     IdentifierOffsets.resize(IdentifierIDs.size());
                    39686: branch 3 taken
                       44: branch 4 taken
    1713            39730:     for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator
    1714               44:            ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
    1715                 :          ID != IDEnd; ++ID) {
                    39686: branch 1 taken
                        0: branch 2 not taken
    1716            39686:       assert(ID->first && "NULL identifier in identifier table");
    1717            39686:       Generator.insert(ID->first, ID->second);
    1718                 :     }
    1719                 : 
    1720                 :     // Create the on-disk hash table in a buffer.
    1721               44:     llvm::SmallString<4096> IdentifierTable;
    1722                 :     uint32_t BucketOffset;
    1723                 :     {
    1724               44:       PCHIdentifierTableTrait Trait(*this, PP);
    1725               44:       llvm::raw_svector_ostream Out(IdentifierTable);
    1726                 :       // Make sure that no bucket is at offset 0
    1727               44:       clang::io::Emit32(Out, 0);
    1728               44:       BucketOffset = Generator.Emit(Out, Trait);
    1729                 :     }
    1730                 : 
    1731                 :     // Create a blob abbreviation
    1732               44:     BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
    1733               44:     Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE));
    1734               44:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
    1735               44:     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
    1736               44:     unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbrev);
    1737                 : 
    1738                 :     // Write the identifier table
    1739               44:     RecordData Record;
    1740               44:     Record.push_back(pch::IDENTIFIER_TABLE);
    1741               44:     Record.push_back(BucketOffset);
    1742               44:     Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str());
    1743                 :   }
    1744                 : 
    1745                 :   // Write the offsets table for identifier IDs.
    1746               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
    1747               44:   Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_OFFSET));
    1748               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
    1749               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
    1750               44:   unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
    1751                 : 
    1752               44:   RecordData Record;
    1753               44:   Record.push_back(pch::IDENTIFIER_OFFSET);
    1754               44:   Record.push_back(IdentifierOffsets.size());
    1755                 :   Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
    1756                 :                             (const char *)&IdentifierOffsets.front(),
    1757               44:                             IdentifierOffsets.size() * sizeof(uint32_t));
    1758               44: }
    1759                 : 
    1760                 : //===----------------------------------------------------------------------===//
    1761                 : // General Serialization Routines
    1762                 : //===----------------------------------------------------------------------===//
    1763                 : 
    1764                 : /// \brief Write a record containing the given attributes.
    1765                7: void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
    1766                7:   RecordData Record;
                        8: branch 1 taken
                        7: branch 2 taken
    1767               15:   for (; Attr; Attr = Attr->getNext()) {
    1768                8:     Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs
    1769                8:     Record.push_back(Attr->isInherited());
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        1: branch 9 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        1: branch 12 taken
                        0: branch 13 not taken
                        0: branch 14 not taken
                        0: branch 15 not taken
                        0: branch 16 not taken
                        4: branch 17 taken
                        0: branch 18 not taken
                        0: branch 19 not taken
                        1: branch 20 taken
                        0: branch 21 not taken
                        1: branch 22 taken
                        0: branch 23 not taken
                        0: branch 24 not taken
                        0: branch 25 not taken
                        0: branch 26 not taken
                        0: branch 27 not taken
                        0: branch 28 not taken
                        0: branch 29 not taken
                        0: branch 30 not taken
                        0: branch 31 not taken
    1770                8:     switch (Attr->getKind()) {
    1771                 :     default:
    1772                0:       assert(0 && "Does not support PCH writing for this attribute yet!");
    1773                 :       break;
    1774                 :     case Attr::Alias:
    1775                0:       AddString(cast<AliasAttr>(Attr)->getAliasee(), Record);
    1776                0:       break;
    1777                 : 
    1778                 :     case Attr::Aligned:
    1779                0:       Record.push_back(cast<AlignedAttr>(Attr)->getAlignment());
    1780                0:       break;
    1781                 : 
    1782                 :     case Attr::AlwaysInline:
    1783                0:       break;
    1784                 : 
    1785                 :     case Attr::AnalyzerNoReturn:
    1786                0:       break;
    1787                 : 
    1788                 :     case Attr::Annotate:
    1789                0:       AddString(cast<AnnotateAttr>(Attr)->getAnnotation(), Record);
    1790                0:       break;
    1791                 : 
    1792                 :     case Attr::AsmLabel:
    1793                0:       AddString(cast<AsmLabelAttr>(Attr)->getLabel(), Record);
    1794                0:       break;
    1795                 : 
    1796                 :     case Attr::BaseCheck:
    1797                0:       break;
    1798                 : 
    1799                 :     case Attr::Blocks:
    1800                1:       Record.push_back(cast<BlocksAttr>(Attr)->getType()); // FIXME: stable
    1801                1:       break;
    1802                 : 
    1803                 :     case Attr::CDecl:
    1804                0:       break;
    1805                 : 
    1806                 :     case Attr::Cleanup:
    1807                0:       AddDeclRef(cast<CleanupAttr>(Attr)->getFunctionDecl(), Record);
    1808                0:       break;
    1809                 : 
    1810                 :     case Attr::Const:
    1811                1:       break;
    1812                 : 
    1813                 :     case Attr::Constructor:
    1814                0:       Record.push_back(cast<ConstructorAttr>(Attr)->getPriority());
    1815                0:       break;
    1816                 : 
    1817                 :     case Attr::DLLExport:
    1818                 :     case Attr::DLLImport:
    1819                 :     case Attr::Deprecated:
    1820                0:       break;
    1821                 : 
    1822                 :     case Attr::Destructor:
    1823                0:       Record.push_back(cast<DestructorAttr>(Attr)->getPriority());
    1824                0:       break;
    1825                 : 
    1826                 :     case Attr::FastCall:
    1827                 :     case Attr::Final:
    1828                0:       break;
    1829                 : 
    1830                 :     case Attr::Format: {
    1831                4:       const FormatAttr *Format = cast<FormatAttr>(Attr);
    1832                4:       AddString(Format->getType(), Record);
    1833                4:       Record.push_back(Format->getFormatIdx());
    1834                4:       Record.push_back(Format->getFirstArg());
    1835                4:       break;
    1836                 :     }
    1837                 : 
    1838                 :     case Attr::FormatArg: {
    1839                0:       const FormatArgAttr *Format = cast<FormatArgAttr>(Attr);
    1840                0:       Record.push_back(Format->getFormatIdx());
    1841                0:       break;
    1842                 :     }
    1843                 : 
    1844                 :     case Attr::Sentinel : {
    1845                0:       const SentinelAttr *Sentinel = cast<SentinelAttr>(Attr);
    1846                0:       Record.push_back(Sentinel->getSentinel());
    1847                0:       Record.push_back(Sentinel->getNullPos());
    1848                0:       break;
    1849                 :     }
    1850                 : 
    1851                 :     case Attr::GNUInline:
    1852                 :     case Attr::Hiding:
    1853                 :     case Attr::IBOutletKind:
    1854                 :     case Attr::Malloc:
    1855                 :     case Attr::NoDebug:
    1856                 :     case Attr::NoReturn:
    1857                 :     case Attr::NoThrow:
    1858                 :     case Attr::NoInline:
    1859                1:       break;
    1860                 : 
    1861                 :     case Attr::NonNull: {
    1862                0:       const NonNullAttr *NonNull = cast<NonNullAttr>(Attr);
    1863                0:       Record.push_back(NonNull->size());
    1864                0:       Record.insert(Record.end(), NonNull->begin(), NonNull->end());
    1865                0:       break;
    1866                 :     }
    1867                 : 
    1868                 :     case Attr::ObjCException:
    1869                 :     case Attr::ObjCNSObject:
    1870                 :     case Attr::CFReturnsRetained:
    1871                 :     case Attr::NSReturnsRetained:
    1872                 :     case Attr::Overloadable:
    1873                 :     case Attr::Override:
    1874                1:       break;
    1875                 : 
    1876                 :     case Attr::PragmaPack:
    1877                0:       Record.push_back(cast<PragmaPackAttr>(Attr)->getAlignment());
    1878                0:       break;
    1879                 : 
    1880                 :     case Attr::Packed:
    1881                0:       break;
    1882                 : 
    1883                 :     case Attr::Pure:
    1884                0:       break;
    1885                 : 
    1886                 :     case Attr::Regparm:
    1887                0:       Record.push_back(cast<RegparmAttr>(Attr)->getNumParams());
    1888                0:       break;
    1889                 : 
    1890                 :     case Attr::ReqdWorkGroupSize:
    1891                0:       Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim());
    1892                0:       Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim());
    1893                0:       Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim());
    1894                0:       break;
    1895                 : 
    1896                 :     case Attr::Section:
    1897                0:       AddString(cast<SectionAttr>(Attr)->getName(), Record);
    1898                0:       break;
    1899                 : 
    1900                 :     case Attr::StdCall:
    1901                 :     case Attr::TransparentUnion:
    1902                 :     case Attr::Unavailable:
    1903                 :     case Attr::Unused:
    1904                 :     case Attr::Used:
    1905                0:       break;
    1906                 : 
    1907                 :     case Attr::Visibility:
    1908                 :       // FIXME: stable encoding
    1909                0:       Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility());
    1910                 :       break;
    1911                 : 
    1912                 :     case Attr::WarnUnusedResult:
    1913                 :     case Attr::Weak:
    1914                 :     case Attr::WeakImport:
    1915                 :       break;
    1916                 :     }
    1917                 :   }
    1918                 : 
    1919                7:   Stream.EmitRecord(pch::DECL_ATTR, Record);
    1920                7: }
    1921                 : 
    1922                4: void PCHWriter::AddString(const std::string &Str, RecordData &Record) {
    1923                4:   Record.push_back(Str.size());
    1924                4:   Record.insert(Record.end(), Str.begin(), Str.end());
    1925                4: }
    1926                 : 
    1927                 : /// \brief Note that the identifier II occurs at the given offset
    1928                 : /// within the identifier table.
    1929            39686: void PCHWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
    1930            39686:   IdentifierOffsets[IdentifierIDs[II] - 1] = Offset;
    1931            39686: }
    1932                 : 
    1933                 : /// \brief Note that the selector Sel occurs at the given offset
    1934                 : /// within the method pool/selector table.
    1935               25: void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
    1936               25:   unsigned ID = SelectorIDs[Sel];
                        0: branch 0 not taken
                       25: branch 1 taken
    1937               25:   assert(ID && "Unknown selector");
    1938               25:   SelectorOffsets[ID - 1] = Offset;
    1939               25: }
    1940                 : 
    1941               44: PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
    1942                 :   : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
    1943                 :     NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
    1944               44:     NumVisibleDeclContexts(0) { }
    1945                 : 
    1946                 : void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
    1947               44:                          const char *isysroot) {
    1948                 :   using namespace llvm;
    1949                 : 
    1950               44:   ASTContext &Context = SemaRef.Context;
    1951               44:   Preprocessor &PP = SemaRef.PP;
    1952                 : 
    1953                 :   // Emit the file header.
    1954               44:   Stream.Emit((unsigned)'C', 8);
    1955               44:   Stream.Emit((unsigned)'P', 8);
    1956               44:   Stream.Emit((unsigned)'C', 8);
    1957               44:   Stream.Emit((unsigned)'H', 8);
    1958                 : 
    1959               44:   WriteBlockInfoBlock();
    1960                 : 
    1961                 :   // The translation unit is the first declaration we'll emit.
    1962               44:   DeclIDs[Context.getTranslationUnitDecl()] = 1;
    1963               44:   DeclTypesToEmit.push(Context.getTranslationUnitDecl());
    1964                 : 
    1965                 :   // Make sure that we emit IdentifierInfos (and any attached
    1966                 :   // declarations) for builtins.
    1967                 :   {
    1968               44:     IdentifierTable &Table = PP.getIdentifierTable();
    1969               44:     llvm::SmallVector<const char *, 32> BuiltinNames;
    1970                 :     Context.BuiltinInfo.GetBuiltinNames(BuiltinNames,
    1971               44:                                         Context.getLangOptions().NoBuiltin);
                    28952: branch 1 taken
                       44: branch 2 taken
    1972            28996:     for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I)
    1973            28996:       getIdentifierRef(&Table.get(BuiltinNames[I]));
    1974                 :   }
    1975                 : 
    1976                 :   // Build a record containing all of the tentative definitions in this file, in
    1977                 :   // TentativeDefinitions order.  Generally, this record will be empty for
    1978                 :   // headers.
    1979               44:   RecordData TentativeDefinitions;
                       29: branch 1 taken
                       44: branch 2 taken
    1980               73:   for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
    1981               29:     AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
    1982                 :   }
    1983                 : 
    1984                 :   // Build a record containing all of the locally-scoped external
    1985                 :   // declarations in this header file. Generally, this record will be
    1986                 :   // empty.
    1987               44:   RecordData LocallyScopedExternalDecls;
    1988                 :   // FIXME: This is filling in the PCH file in densemap order which is
    1989                 :   // nondeterminstic!
                        4: branch 3 taken
                       44: branch 4 taken
    1990               48:   for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
    1991               44:          TD = SemaRef.LocallyScopedExternalDecls.begin(),
    1992               44:          TDEnd = SemaRef.LocallyScopedExternalDecls.end();
    1993                 :        TD != TDEnd; ++TD)
    1994                4:     AddDeclRef(TD->second, LocallyScopedExternalDecls);
    1995                 : 
    1996                 :   // Build a record containing all of the ext_vector declarations.
    1997               44:   RecordData ExtVectorDecls;
                        4: branch 1 taken
                       44: branch 2 taken
    1998               48:   for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I)
    1999                4:     AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
    2000                 : 
    2001                 :   // Write the remaining PCH contents.
    2002               44:   RecordData Record;
    2003               44:   Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
    2004               44:   WriteMetadata(Context, isysroot);
    2005               44:   WriteLanguageOptions(Context.getLangOptions());
                       44: branch 0 taken
                        0: branch 1 not taken
                       43: branch 2 taken
                        1: branch 3 taken
    2006               44:   if (StatCalls && !isysroot)
    2007               43:     WriteStatCache(*StatCalls, isysroot);
    2008               44:   WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
    2009               44:   WriteComments(Context);
    2010                 :   // Write the record of special types.
    2011               44:   Record.clear();
    2012                 : 
    2013               44:   AddTypeRef(Context.getBuiltinVaListType(), Record);
    2014               44:   AddTypeRef(Context.getObjCIdType(), Record);
    2015               44:   AddTypeRef(Context.getObjCSelType(), Record);
    2016               44:   AddTypeRef(Context.getObjCProtoType(), Record);
    2017               44:   AddTypeRef(Context.getObjCClassType(), Record);
    2018               44:   AddTypeRef(Context.getRawCFConstantStringType(), Record);
    2019               44:   AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
    2020               44:   AddTypeRef(Context.getFILEType(), Record);
    2021               44:   AddTypeRef(Context.getjmp_bufType(), Record);
    2022               44:   AddTypeRef(Context.getsigjmp_bufType(), Record);
    2023               44:   AddTypeRef(Context.ObjCIdRedefinitionType, Record);
    2024               44:   AddTypeRef(Context.ObjCClassRedefinitionType, Record);
    2025                 : #if 0
    2026                 :   // FIXME. Accommodate for this in several PCH/Indexer tests
    2027                 :   AddTypeRef(Context.ObjCSelRedefinitionType, Record);
    2028                 : #endif
    2029               44:   AddTypeRef(Context.getRawBlockdescriptorType(), Record);
    2030               44:   AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record);
    2031               44:   Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
    2032                 : 
    2033                 :   // Keep writing types and declarations until all types and
    2034                 :   // declarations have been written.
    2035               44:   Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3);
    2036               44:   WriteDeclsBlockAbbrevs();
                      975: branch 1 taken
                       44: branch 2 taken
    2037             1063:   while (!DeclTypesToEmit.empty()) {
    2038              975:     DeclOrType DOT = DeclTypesToEmit.front();
    2039              975:     DeclTypesToEmit.pop();
                      373: branch 1 taken
                      602: branch 2 taken
    2040              975:     if (DOT.isType())
    2041              373:       WriteType(DOT.getType());
    2042                 :     else
    2043              602:       WriteDecl(Context, DOT.getDecl());
    2044                 :   }
    2045               44:   Stream.ExitBlock();
    2046                 :   
    2047               44:   WritePreprocessor(PP);
    2048               44:   WriteMethodPool(SemaRef);
    2049               44:   WriteIdentifierTable(PP);
    2050                 : 
    2051                 :   // Write the type offsets array
    2052               44:   BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
    2053               44:   Abbrev->Add(BitCodeAbbrevOp(pch::TYPE_OFFSET));
    2054               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
    2055               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
    2056               44:   unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
    2057               44:   Record.clear();
    2058               44:   Record.push_back(pch::TYPE_OFFSET);
    2059               44:   Record.push_back(TypeOffsets.size());
    2060                 :   Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record,
    2061                 :                             (const char *)&TypeOffsets.front(),
    2062               44:                             TypeOffsets.size() * sizeof(TypeOffsets[0]));
    2063                 : 
    2064                 :   // Write the declaration offsets array
    2065               44:   Abbrev = new BitCodeAbbrev();
    2066               44:   Abbrev->Add(BitCodeAbbrevOp(pch::DECL_OFFSET));
    2067               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
    2068               44:   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
    2069               44:   unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev);
    2070               44:   Record.clear();
    2071               44:   Record.push_back(pch::DECL_OFFSET);
    2072               44:   Record.push_back(DeclOffsets.size());
    2073                 :   Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record,
    2074                 :                             (const char *)&DeclOffsets.front(),
    2075               44:                             DeclOffsets.size() * sizeof(DeclOffsets[0]));
    2076                 : 
    2077                 :   // Write the record containing external, unnamed definitions.
                       21: branch 1 taken
                       23: branch 2 taken
    2078               44:   if (!ExternalDefinitions.empty())
    2079               21:     Stream.EmitRecord(pch::EXTERNAL_DEFINITIONS, ExternalDefinitions);
    2080                 : 
    2081                 :   // Write the record containing tentative definitions.
                       11: branch 1 taken
                       33: branch 2 taken
    2082               44:   if (!TentativeDefinitions.empty())
    2083               11:     Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions);
    2084                 : 
    2085                 :   // Write the record containing locally-scoped external definitions.
                        2: branch 1 taken
                       42: branch 2 taken
    2086               44:   if (!LocallyScopedExternalDecls.empty())
    2087                 :     Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
    2088                2:                       LocallyScopedExternalDecls);
    2089                 : 
    2090                 :   // Write the record containing ext_vector type names.
                        3: branch 1 taken
                       41: branch 2 taken
    2091               44:   if (!ExtVectorDecls.empty())
    2092                3:     Stream.EmitRecord(pch::EXT_VECTOR_DECLS, ExtVectorDecls);
    2093                 : 
    2094                 :   // Some simple statistics
    2095               44:   Record.clear();
    2096               44:   Record.push_back(NumStatements);
    2097               44:   Record.push_back(NumMacros);
    2098               44:   Record.push_back(NumLexicalDeclContexts);
    2099               44:   Record.push_back(NumVisibleDeclContexts);
    2100               44:   Stream.EmitRecord(pch::STATISTICS, Record);
    2101               44:   Stream.ExitBlock();
    2102               44: }
    2103                 : 
    2104             2540: void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
    2105             2540:   Record.push_back(Loc.getRawEncoding());
    2106             2540: }
    2107                 : 
    2108              124: void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
    2109              124:   Record.push_back(Value.getBitWidth());
    2110              124:   unsigned N = Value.getNumWords();
    2111              124:   const uint64_t* Words = Value.getRawData();
                      124: branch 0 taken
                      124: branch 1 taken
    2112              248:   for (unsigned I = 0; I != N; ++I)
    2113              124:     Record.push_back(Words[I]);
    2114              124: }
    2115                 : 
    2116               10: void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
    2117               10:   Record.push_back(Value.isUnsigned());
    2118               10:   AddAPInt(Value, Record);
    2119               10: }
    2120                 : 
    2121               12: void PCHWriter::AddAPFloat(const llvm::APFloat &Value, RecordData &Record) {
    2122               12:   AddAPInt(Value.bitcastToAPInt(), Record);
    2123               12: }
    2124                 : 
    2125            11182: void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
    2126            11182:   Record.push_back(getIdentifierRef(II));
    2127            11182: }
    2128                 : 
    2129            79845: pch::IdentID PCHWriter::getIdentifierRef(const IdentifierInfo *II) {
                     4984: branch 0 taken
                    74861: branch 1 taken
    2130            79845:   if (II == 0)
    2131             4984:     return 0;
    2132                 : 
    2133            74861:   pch::IdentID &ID = IdentifierIDs[II];
                    39686: branch 0 taken
                    35175: branch 1 taken
    2134            74861:   if (ID == 0)
    2135            39686:     ID = IdentifierIDs.size();
    2136            74861:   return ID;
    2137                 : }
    2138                 : 
    2139               75: void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {
                        0: branch 1 not taken
                       75: branch 2 taken
    2140               75:   if (SelRef.getAsOpaquePtr() == 0) {
    2141                0:     Record.push_back(0);
    2142                0:     return;
    2143                 :   }
    2144                 : 
    2145               75:   pch::SelectorID &SID = SelectorIDs[SelRef];
                       28: branch 0 taken
                       47: branch 1 taken
    2146               75:   if (SID == 0) {
    2147               28:     SID = SelectorIDs.size();
    2148               28:     SelVector.push_back(SelRef);
    2149                 :   }
    2150               75:   Record.push_back(SID);
    2151                 : }
    2152                 : 
    2153                 : void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
    2154                0:                                        RecordData &Record) {
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
    2155                0:   switch (Arg.getArgument().getKind()) {
    2156                 :   case TemplateArgument::Expression:
    2157                0:     AddStmt(Arg.getLocInfo().getAsExpr());
    2158                0:     break;
    2159                 :   case TemplateArgument::Type:
    2160                0:     AddTypeSourceInfo(Arg.getLocInfo().getAsTypeSourceInfo(), Record);
    2161                0:     break;
    2162                 :   case TemplateArgument::Template:
    2163                 :     Record.push_back(
    2164                0:                    Arg.getTemplateQualifierRange().getBegin().getRawEncoding());
    2165                0:     Record.push_back(Arg.getTemplateQualifierRange().getEnd().getRawEncoding());
    2166                0:     Record.push_back(Arg.getTemplateNameLoc().getRawEncoding());
    2167                 :     break;
    2168                 :   case TemplateArgument::Null:
    2169                 :   case TemplateArgument::Integral:
    2170                 :   case TemplateArgument::Declaration:
    2171                 :   case TemplateArgument::Pack:
    2172                 :     break;
    2173                 :   }
    2174                0: }
    2175                 : 
    2176              458: void PCHWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record) {
                       38: branch 0 taken
                      420: branch 1 taken
    2177              458:   if (TInfo == 0) {
    2178               38:     AddTypeRef(QualType(), Record);
    2179               38:     return;
    2180                 :   }
    2181                 : 
    2182              420:   AddTypeRef(TInfo->getType(), Record);
    2183              420:   TypeLocWriter TLW(*this, Record);
                      648: branch 3 taken
                      420: branch 4 taken
    2184             1068:   for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
    2185              648:     TLW.Visit(TL);  
    2186                 : }
    2187                 : 
    2188             2420: void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
                      731: branch 1 taken
                     1689: branch 2 taken
    2189             2420:   if (T.isNull()) {
    2190              731:     Record.push_back(pch::PREDEF_TYPE_NULL_ID);
    2191              731:     return;
    2192                 :   }
    2193                 : 
    2194             1689:   unsigned FastQuals = T.getLocalFastQualifiers();
    2195             1689:   T.removeFastQualifiers();
    2196                 : 
                        1: branch 1 taken
                     1688: branch 2 taken
    2197             1689:   if (T.hasLocalNonFastQualifiers()) {
    2198                1:     pch::TypeID &ID = TypeIDs[T];
                        1: branch 0 taken
                        0: branch 1 not taken
    2199                1:     if (ID == 0) {
    2200                 :       // We haven't seen these qualifiers applied to this type before.
    2201                 :       // Assign it a new ID.  This is the only time we enqueue a
    2202                 :       // qualified type, and it has no CV qualifiers.
    2203                1:       ID = NextTypeID++;
    2204                1:       DeclTypesToEmit.push(T);
    2205                 :     }
    2206                 :     
    2207                 :     // Encode the type qualifiers in the type reference.
    2208                1:     Record.push_back((ID << Qualifiers::FastWidth) | FastQuals);
    2209                1:     return;
    2210                 :   }
    2211                 : 
                        0: branch 1 not taken
                     1688: branch 2 taken
    2212             1688:   assert(!T.hasLocalQualifiers());
    2213                 :   
                      826: branch 2 taken
                      862: branch 3 taken
    2214             1688:   if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
    2215              826:     pch::TypeID ID = 0;
                       40: branch 1 taken
                        9: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                       44: branch 6 taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        7: branch 9 taken
                       72: branch 10 taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        0: branch 13 not taken
                      472: branch 14 taken
                        2: branch 15 taken
                        0: branch 16 not taken
                        7: branch 17 taken
                       79: branch 18 taken
                       57: branch 19 taken
                        0: branch 20 not taken
                        2: branch 21 taken
                        0: branch 22 not taken
                        0: branch 23 not taken
                        0: branch 24 not taken
                        0: branch 25 not taken
                       15: branch 26 taken
                       10: branch 27 taken
                       10: branch 28 taken
                        0: branch 29 not taken
                        0: branch 30 not taken
    2216              826:     switch (BT->getKind()) {
    2217               40:     case BuiltinType::Void:       ID = pch::PREDEF_TYPE_VOID_ID;       break;
    2218                9:     case BuiltinType::Bool:       ID = pch::PREDEF_TYPE_BOOL_ID;       break;
    2219                0:     case BuiltinType::Char_U:     ID = pch::PREDEF_TYPE_CHAR_U_ID;     break;
    2220                0:     case BuiltinType::UChar:      ID = pch::PREDEF_TYPE_UCHAR_ID;      break;
    2221                0:     case BuiltinType::UShort:     ID = pch::PREDEF_TYPE_USHORT_ID;     break;
    2222               44:     case BuiltinType::UInt:       ID = pch::PREDEF_TYPE_UINT_ID;       break;
    2223                0:     case BuiltinType::ULong:      ID = pch::PREDEF_TYPE_ULONG_ID;      break;
    2224                0:     case BuiltinType::ULongLong:  ID = pch::PREDEF_TYPE_ULONGLONG_ID;  break;
    2225                7:     case BuiltinType::UInt128:    ID = pch::PREDEF_TYPE_UINT128_ID;    break;
    2226               72:     case BuiltinType::Char_S:     ID = pch::PREDEF_TYPE_CHAR_S_ID;     break;
    2227                0:     case BuiltinType::SChar:      ID = pch::PREDEF_TYPE_SCHAR_ID;      break;
    2228                0:     case BuiltinType::WChar:      ID = pch::PREDEF_TYPE_WCHAR_ID;      break;
    2229                0:     case BuiltinType::Short:      ID = pch::PREDEF_TYPE_SHORT_ID;      break;
    2230              472:     case BuiltinType::Int:        ID = pch::PREDEF_TYPE_INT_ID;        break;
    2231                2:     case BuiltinType::Long:       ID = pch::PREDEF_TYPE_LONG_ID;       break;
    2232                0:     case BuiltinType::LongLong:   ID = pch::PREDEF_TYPE_LONGLONG_ID;   break;
    2233                7:     case BuiltinType::Int128:     ID = pch::PREDEF_TYPE_INT128_ID;     break;
    2234               79:     case BuiltinType::Float:      ID = pch::PREDEF_TYPE_FLOAT_ID;      break;
    2235               57:     case BuiltinType::Double:     ID = pch::PREDEF_TYPE_DOUBLE_ID;     break;
    2236                0:     case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
    2237                2:     case BuiltinType::NullPtr:    ID = pch::PREDEF_TYPE_NULLPTR_ID;    break;
    2238                0:     case BuiltinType::Char16:     ID = pch::PREDEF_TYPE_CHAR16_ID;     break;
    2239                0:     case BuiltinType::Char32:     ID = pch::PREDEF_TYPE_CHAR32_ID;     break;
    2240                0:     case BuiltinType::Overload:   ID = pch::PREDEF_TYPE_OVERLOAD_ID;   break;
    2241                0:     case BuiltinType::Dependent:  ID = pch::PREDEF_TYPE_DEPENDENT_ID;  break;
    2242               15:     case BuiltinType::ObjCId:     ID = pch::PREDEF_TYPE_OBJC_ID;       break;
    2243               10:     case BuiltinType::ObjCClass:  ID = pch::PREDEF_TYPE_OBJC_CLASS;    break;
    2244               10:     case BuiltinType::ObjCSel:    ID = pch::PREDEF_TYPE_OBJC_SEL;      break;
    2245                 :     case BuiltinType::UndeducedAuto:
    2246                0:       assert(0 && "Should not see undeduced auto here");
    2247                 :       break;
    2248                 :     }
    2249                 : 
    2250              826:     Record.push_back((ID << Qualifiers::FastWidth) | FastQuals);
    2251              826:     return;
    2252                 :   }
    2253                 : 
    2254              862:   pch::TypeID &ID = TypeIDs[T];
                      372: branch 0 taken
                      490: branch 1 taken
    2255              862:   if (ID == 0) {
    2256                 :     // We haven't seen this type before. Assign it a new ID and put it
    2257                 :     // into the queue of types to emit.
    2258              372:     ID = NextTypeID++;
    2259              372:     DeclTypesToEmit.push(T);
    2260                 :   }
    2261                 : 
    2262                 :   // Encode the type qualifiers in the type reference.
    2263              862:   Record.push_back((ID << Qualifiers::FastWidth) | FastQuals);
    2264                 : }
    2265                 : 
    2266             2660: void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
                      458: branch 0 taken
                     2202: branch 1 taken
    2267             2660:   if (D == 0) {
    2268              458:     Record.push_back(0);
    2269              458:     return;
    2270                 :   }
    2271                 : 
    2272             2202:   pch::DeclID &ID = DeclIDs[D];
                      558: branch 0 taken
                     1644: branch 1 taken
    2273             2202:   if (ID == 0) {
    2274                 :     // We haven't seen this declaration before. Give it a new ID and
    2275                 :     // enqueue it in the list of declarations to emit.
    2276              558:     ID = DeclIDs.size();
    2277              558:     DeclTypesToEmit.push(const_cast<Decl *>(D));
    2278                 :   }
    2279                 : 
    2280             2202:   Record.push_back(ID);
    2281                 : }
    2282                 : 
    2283              345: pch::DeclID PCHWriter::getDeclID(const Decl *D) {
                        0: branch 0 not taken
                      345: branch 1 taken
    2284              345:   if (D == 0)
    2285                0:     return 0;
    2286                 : 
                      345: branch 4 taken
                        0: branch 5 not taken
    2287              345:   assert(DeclIDs.find(D) != DeclIDs.end() && "Declaration not emitted!");
    2288              345:   return DeclIDs[D];
    2289                 : }
    2290                 : 
    2291              664: void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
    2292                 :   // FIXME: Emit a stable enum for NameKind.  0 = Identifier etc.
    2293              664:   Record.push_back(Name.getNameKind());
                      571: branch 1 taken
                       62: branch 2 taken
                       20: branch 3 taken
                       11: branch 4 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    2294              664:   switch (Name.getNameKind()) {
    2295                 :   case DeclarationName::Identifier:
    2296              571:     AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
    2297              571:     break;
    2298                 : 
    2299                 :   case DeclarationName::ObjCZeroArgSelector:
    2300                 :   case DeclarationName::ObjCOneArgSelector:
    2301                 :   case DeclarationName::ObjCMultiArgSelector:
    2302               62:     AddSelectorRef(Name.getObjCSelector(), Record);
    2303               62:     break;
    2304                 : 
    2305                 :   case DeclarationName::CXXConstructorName:
    2306                 :   case DeclarationName::CXXDestructorName:
    2307                 :   case DeclarationName::CXXConversionFunctionName:
    2308               20:     AddTypeRef(Name.getCXXNameType(), Record);
    2309               20:     break;
    2310                 : 
    2311                 :   case DeclarationName::CXXOperatorName:
    2312               11:     Record.push_back(Name.getCXXOverloadedOperator());
    2313               11:     break;
    2314                 : 
    2315                 :   case DeclarationName::CXXLiteralOperatorName:
    2316                0:     AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record);
    2317                 :     break;
    2318                 : 
    2319                 :   case DeclarationName::CXXUsingDirective:
    2320                 :     // No extra data to emit
    2321                 :     break;
    2322                 :   }
    2323              664: }
    2324                 : 

Generated: 2010-02-10 01:31 by zcov