zcov: / lib/Frontend/PCHReader.cpp


Files: 1 Branches Taken: 59.4% 462 / 778
Generated: 2010-02-10 01:31 Branches Executed: 88.0% 685 / 778
Line Coverage: 77.9% 1114 / 1430


Programs: 2 Runs 3018


       1                 : //===--- PCHReader.cpp - Precompiled Headers Reader -------------*- 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 PCHReader class, which reads a precompiled header.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/Frontend/PCHReader.h"
      15                 : #include "clang/Frontend/FrontendDiagnostic.h"
      16                 : #include "clang/Frontend/Utils.h"
      17                 : #include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
      18                 : #include "clang/AST/ASTConsumer.h"
      19                 : #include "clang/AST/ASTContext.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/OnDiskHashTable.h"
      27                 : #include "clang/Basic/SourceManager.h"
      28                 : #include "clang/Basic/SourceManagerInternals.h"
      29                 : #include "clang/Basic/FileManager.h"
      30                 : #include "clang/Basic/TargetInfo.h"
      31                 : #include "clang/Basic/Version.h"
      32                 : #include "llvm/ADT/StringExtras.h"
      33                 : #include "llvm/Bitcode/BitstreamReader.h"
      34                 : #include "llvm/Support/MemoryBuffer.h"
      35                 : #include "llvm/Support/ErrorHandling.h"
      36                 : #include "llvm/System/Path.h"
      37                 : #include <algorithm>
      38                 : #include <iterator>
      39                 : #include <cstdio>
      40                 : #include <sys/stat.h>
      41                 : using namespace clang;
      42                 : 
      43                 : //===----------------------------------------------------------------------===//
      44                 : // PCH reader validator implementation
      45                 : //===----------------------------------------------------------------------===//
      46                 : 
                       44: branch 0 taken
                       44: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                       44: branch 7 taken
      47               44: PCHReaderListener::~PCHReaderListener() {}
      48                 : 
      49                 : bool
      50               35: PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
      51               35:   const LangOptions &PPLangOpts = PP.getLangOptions();
      52                 : #define PARSE_LANGOPT_BENIGN(Option)
      53                 : #define PARSE_LANGOPT_IMPORTANT(Option, DiagID)                    \
      54                 :   if (PPLangOpts.Option != LangOpts.Option) {                      \
      55                 :     Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option;   \
      56                 :     return true;                                                   \
      57                 :   }
      58                 : 
      59                 :   PARSE_LANGOPT_BENIGN(Trigraphs);
      60                 :   PARSE_LANGOPT_BENIGN(BCPLComment);
      61                 :   PARSE_LANGOPT_BENIGN(DollarIdents);
      62                 :   PARSE_LANGOPT_BENIGN(AsmPreprocessor);
                        0: branch 0 not taken
                       35: branch 1 taken
      63               35:   PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
      64                 :   PARSE_LANGOPT_BENIGN(ImplicitInt);
      65                 :   PARSE_LANGOPT_BENIGN(Digraphs);
      66                 :   PARSE_LANGOPT_BENIGN(HexFloats);
                        0: branch 0 not taken
                       35: branch 1 taken
      67               35:   PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
                        0: branch 0 not taken
                       35: branch 1 taken
      68               35:   PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
                        0: branch 0 not taken
                       35: branch 1 taken
      69               35:   PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
                        0: branch 0 not taken
                       35: branch 1 taken
      70               35:   PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
      71                 :   PARSE_LANGOPT_BENIGN(CXXOperatorName);
                        0: branch 0 not taken
                       35: branch 1 taken
      72               35:   PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
                        0: branch 0 not taken
                       35: branch 1 taken
      73               35:   PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
                        0: branch 0 not taken
                       35: branch 1 taken
      74               35:   PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
                        0: branch 0 not taken
                       35: branch 1 taken
      75               35:   PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
      76                 :   PARSE_LANGOPT_BENIGN(PascalStrings);
      77                 :   PARSE_LANGOPT_BENIGN(WritableStrings);
                        0: branch 0 not taken
                       35: branch 1 taken
      78               35:   PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
      79                 :                           diag::warn_pch_lax_vector_conversions);
                        0: branch 0 not taken
                       35: branch 1 taken
      80               35:   PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
                        0: branch 0 not taken
                       35: branch 1 taken
      81               35:   PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
                        0: branch 0 not taken
                       35: branch 1 taken
      82               35:   PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
                        0: branch 0 not taken
                       35: branch 1 taken
      83               35:   PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
                        0: branch 0 not taken
                       35: branch 1 taken
      84               35:   PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
                        0: branch 0 not taken
                       35: branch 1 taken
      85               35:   PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
      86                 :                           diag::warn_pch_thread_safe_statics);
                        0: branch 0 not taken
                       35: branch 1 taken
      87               35:   PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
                        0: branch 0 not taken
                       35: branch 1 taken
      88               35:   PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
      89                 :   PARSE_LANGOPT_BENIGN(EmitAllDecls);
                        0: branch 0 not taken
                       35: branch 1 taken
      90               35:   PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
                        0: branch 0 not taken
                       35: branch 1 taken
      91               35:   PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
                        0: branch 0 not taken
                       35: branch 1 taken
      92               35:   PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
      93                 :                           diag::warn_pch_heinous_extensions);
      94                 :   // FIXME: Most of the options below are benign if the macro wasn't
      95                 :   // used. Unfortunately, this means that a PCH compiled without
      96                 :   // optimization can't be used with optimization turned on, even
      97                 :   // though the only thing that changes is whether __OPTIMIZE__ was
      98                 :   // defined... but if __OPTIMIZE__ never showed up in the header, it
      99                 :   // doesn't matter. We could consider making this some special kind
     100                 :   // of check.
                        0: branch 0 not taken
                       35: branch 1 taken
     101               35:   PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
                        0: branch 0 not taken
                       35: branch 1 taken
     102               35:   PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
                        0: branch 0 not taken
                       35: branch 1 taken
     103               35:   PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
                        0: branch 0 not taken
                       35: branch 1 taken
     104               35:   PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
                        0: branch 0 not taken
                       35: branch 1 taken
     105               35:   PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
                        0: branch 0 not taken
                       35: branch 1 taken
     106               35:   PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
                        0: branch 0 not taken
                       35: branch 1 taken
     107               35:   PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
                        0: branch 0 not taken
                       35: branch 1 taken
     108               35:   PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
                        0: branch 0 not taken
                       35: branch 1 taken
     109               35:   PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
                        0: branch 2 not taken
                       35: branch 3 taken
     110               35:   if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
     111                 :     Reader.Diag(diag::warn_pch_gc_mode)
     112                0:       << LangOpts.getGCMode() << PPLangOpts.getGCMode();
     113                0:     return true;
     114                 :   }
     115                 :   PARSE_LANGOPT_BENIGN(getVisibilityMode());
                        0: branch 2 not taken
                       35: branch 3 taken
     116               35:   PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
     117                 :                           diag::warn_pch_stack_protector);
     118                 :   PARSE_LANGOPT_BENIGN(InstantiationDepth);
                        0: branch 0 not taken
                       35: branch 1 taken
     119               35:   PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
     120                 :   PARSE_LANGOPT_BENIGN(CatchUndefined);
                        0: branch 0 not taken
                       35: branch 1 taken
     121               35:   PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
     122                 : #undef PARSE_LANGOPT_IRRELEVANT
     123                 : #undef PARSE_LANGOPT_BENIGN
     124                 : 
     125               35:   return false;
     126                 : }
     127                 : 
     128               35: bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
                       35: branch 5 taken
                        0: branch 6 not taken
     129               35:   if (Triple == PP.getTargetInfo().getTriple().str())
     130               35:     return false;
     131                 : 
     132                 :   Reader.Diag(diag::warn_pch_target_triple)
     133                0:     << Triple << PP.getTargetInfo().getTriple().str();
     134                0:   return true;
     135                 : }
     136                 : 
     137                 : bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,
     138                 :                                         FileID PCHBufferID,
     139                 :                                         llvm::StringRef OriginalFileName,
     140               34:                                         std::string &SuggestedPredefines) {
     141                 :   // We are in the context of an implicit include, so the predefines buffer will
     142                 :   // have a #include entry for the PCH file itself (as normalized by the
     143                 :   // preprocessor initialization). Find it and skip over it in the checking
     144                 :   // below.
     145               34:   llvm::SmallString<256> PCHInclude;
     146               34:   PCHInclude += "#include \"";
     147               34:   PCHInclude += NormalizeDashIncludePath(OriginalFileName);
     148               34:   PCHInclude += "\"\n";
     149                 :   std::pair<llvm::StringRef,llvm::StringRef> Split =
     150               34:     llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
     151               34:   llvm::StringRef Left =  Split.first, Right = Split.second;
                       34: branch 3 taken
                        0: branch 4 not taken
     152               34:   assert(Left != PP.getPredefines() && "Missing PCH include entry!");
     153                 : 
     154                 :   // If the predefines is equal to the joined left and right halves, we're done!
                       31: branch 3 taken
                        3: branch 4 taken
                       31: branch 6 taken
                        0: branch 7 not taken
                       31: branch 9 taken
                        0: branch 10 not taken
                       31: branch 11 taken
                        3: branch 12 taken
     155               65:   if (Left.size() + Right.size() == PCHPredef.size() &&
     156                 :       PCHPredef.startswith(Left) && PCHPredef.endswith(Right))
     157               31:     return false;
     158                 : 
     159                3:   SourceManager &SourceMgr = PP.getSourceManager();
     160                 : 
     161                 :   // The predefines buffers are different. Determine what the differences are,
     162                 :   // and whether they require us to reject the PCH file.
     163                3:   llvm::SmallVector<llvm::StringRef, 8> PCHLines;
     164                3:   PCHPredef.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
     165                 : 
     166                3:   llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
     167                3:   Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
     168                3:   Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
     169                 : 
     170                 :   // Sort both sets of predefined buffer lines, since we allow some extra
     171                 :   // definitions and they may appear at any point in the output.
     172                3:   std::sort(CmdLineLines.begin(), CmdLineLines.end());
     173                3:   std::sort(PCHLines.begin(), PCHLines.end());
     174                 : 
     175                 :   // Determine which predefines that were used to build the PCH file are missing
     176                 :   // from the command line.
     177                3:   std::vector<llvm::StringRef> MissingPredefines;
     178                 :   std::set_difference(PCHLines.begin(), PCHLines.end(),
     179                 :                       CmdLineLines.begin(), CmdLineLines.end(),
     180                3:                       std::back_inserter(MissingPredefines));
     181                 : 
     182                3:   bool MissingDefines = false;
     183                3:   bool ConflictingDefines = false;
                        1: branch 2 taken
                        0: branch 3 not taken
                        1: branch 4 taken
                        3: branch 5 taken
     184                5:   for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
     185                1:     llvm::StringRef Missing = MissingPredefines[I];
                        0: branch 2 not taken
                        1: branch 3 taken
     186                1:     if (!Missing.startswith("#define ")) {
     187                0:       Reader.Diag(diag::warn_pch_compiler_options_mismatch);
     188                0:       return true;
     189                 :     }
     190                 : 
     191                 :     // This is a macro definition. Determine the name of the macro we're
     192                 :     // defining.
     193                1:     std::string::size_type StartOfMacroName = strlen("#define ");
     194                 :     std::string::size_type EndOfMacroName
     195                1:       = Missing.find_first_of("( \n\r", StartOfMacroName);
     196                 :     assert(EndOfMacroName != std::string::npos &&
                        0: branch 0 not taken
                        1: branch 1 taken
     197                1:            "Couldn't find the end of the macro name");
     198                1:     llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
     199                 : 
     200                 :     // Determine whether this macro was given a different definition on the
     201                 :     // command line.
     202                1:     std::string MacroDefStart = "#define " + MacroName.str();
     203                1:     std::string::size_type MacroDefLen = MacroDefStart.size();
     204                 :     llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
     205                 :       = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
     206                1:                          MacroDefStart);
                        1: branch 1 taken
                        0: branch 2 not taken
     207                1:     for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
                        1: branch 2 taken
                        0: branch 3 not taken
     208                1:       if (!ConflictPos->startswith(MacroDefStart)) {
     209                 :         // Different macro; we're done.
     210                1:         ConflictPos = CmdLineLines.end();
     211                1:         break;
     212                 :       }
     213                 : 
     214                 :       assert(ConflictPos->size() > MacroDefLen &&
                        0: branch 1 not taken
                        0: branch 2 not taken
     215                0:              "Invalid #define in predefines buffer?");
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     216                0:       if ((*ConflictPos)[MacroDefLen] != ' ' &&
     217                 :           (*ConflictPos)[MacroDefLen] != '(')
     218                0:         continue; // Longer macro name; keep trying.
     219                 : 
     220                 :       // We found a conflicting macro definition.
     221                0:       break;
     222                 :     }
     223                 : 
                        0: branch 1 not taken
                        1: branch 2 taken
     224                1:     if (ConflictPos != CmdLineLines.end()) {
     225                 :       Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
     226                0:           << MacroName;
     227                 : 
     228                 :       // Show the definition of this macro within the PCH file.
     229                0:       llvm::StringRef::size_type Offset = PCHPredef.find(Missing);
                        0: branch 0 not taken
                        0: branch 1 not taken
     230                0:       assert(Offset != llvm::StringRef::npos && "Unable to find macro!");
     231                 :       SourceLocation PCHMissingLoc = SourceMgr.getLocForStartOfFile(PCHBufferID)
     232                0:         .getFileLocWithOffset(Offset);
     233                0:       Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
     234                 : 
     235                0:       ConflictingDefines = true;
     236                0:       continue;
     237                 :     }
     238                 : 
     239                 :     // If the macro doesn't conflict, then we'll just pick up the macro
     240                 :     // definition from the PCH file. Warn the user that they made a mistake.
                        0: branch 0 not taken
                        1: branch 1 taken
     241                1:     if (ConflictingDefines)
     242                 :       continue; // Don't complain if there are already conflicting defs
     243                 : 
                        1: branch 0 taken
                        0: branch 1 not taken
     244                1:     if (!MissingDefines) {
     245                1:       Reader.Diag(diag::warn_cmdline_missing_macro_defs);
     246                1:       MissingDefines = true;
     247                 :     }
     248                 : 
     249                 :     // Show the definition of this macro within the PCH file.
     250                1:     llvm::StringRef::size_type Offset = PCHPredef.find(Missing);
                        0: branch 0 not taken
                        1: branch 1 taken
     251                1:     assert(Offset != llvm::StringRef::npos && "Unable to find macro!");
     252                 :     SourceLocation PCHMissingLoc = SourceMgr.getLocForStartOfFile(PCHBufferID)
     253                1:       .getFileLocWithOffset(Offset);
     254                1:     Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
     255                 :   }
     256                 : 
                        0: branch 0 not taken
                        3: branch 1 taken
     257                3:   if (ConflictingDefines)
     258                0:     return true;
     259                 : 
     260                 :   // Determine what predefines were introduced based on command-line
     261                 :   // parameters that were not present when building the PCH
     262                 :   // file. Extra #defines are okay, so long as the identifiers being
     263                 :   // defined were not used within the precompiled header.
     264                3:   std::vector<llvm::StringRef> ExtraPredefines;
     265                 :   std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
     266                 :                       PCHLines.begin(), PCHLines.end(),
     267                3:                       std::back_inserter(ExtraPredefines));
                        4: branch 1 taken
                        2: branch 2 taken
     268                6:   for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
     269                4:     llvm::StringRef &Extra = ExtraPredefines[I];
                        0: branch 2 not taken
                        4: branch 3 taken
     270                4:     if (!Extra.startswith("#define ")) {
     271                0:       Reader.Diag(diag::warn_pch_compiler_options_mismatch);
     272                0:       return true;
     273                 :     }
     274                 : 
     275                 :     // This is an extra macro definition. Determine the name of the
     276                 :     // macro we're defining.
     277                4:     std::string::size_type StartOfMacroName = strlen("#define ");
     278                 :     std::string::size_type EndOfMacroName
     279                4:       = Extra.find_first_of("( \n\r", StartOfMacroName);
     280                 :     assert(EndOfMacroName != std::string::npos &&
                        0: branch 0 not taken
                        4: branch 1 taken
     281                4:            "Couldn't find the end of the macro name");
     282                4:     llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
     283                 : 
     284                 :     // Check whether this name was used somewhere in the PCH file. If
     285                 :     // so, defining it as a macro could change behavior, so we reject
     286                 :     // the PCH file.
                        1: branch 1 taken
                        3: branch 2 taken
     287                4:     if (IdentifierInfo *II = Reader.get(MacroName)) {
     288                1:       Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
     289                1:       return true;
     290                 :     }
     291                 : 
     292                 :     // Add this definition to the suggested predefines buffer.
     293                3:     SuggestedPredefines += Extra;
     294                3:     SuggestedPredefines += '\n';
     295                 :   }
     296                 : 
     297                 :   // If we get here, it's because the predefines buffer had compatible
     298                 :   // contents. Accept the PCH file.
     299                2:   return false;
     300                 : }
     301                 : 
     302               39: void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI) {
     303               39:   PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
     304               39: }
     305                 : 
     306                4: void PCHValidator::ReadCounter(unsigned Value) {
     307                4:   PP.setCounterValue(Value);
     308                4: }
     309                 : 
     310                 : //===----------------------------------------------------------------------===//
     311                 : // PCH reader implementation
     312                 : //===----------------------------------------------------------------------===//
     313                 : 
     314                 : PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
     315               35:                      const char *isysroot)
     316                 :   : Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
     317                 :     FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
     318                 :     SemaObj(0), PP(&PP), Context(Context), StatCache(0), Consumer(0),
     319                 :     IdentifierTableData(0), IdentifierLookupTable(0),
     320                 :     IdentifierOffsets(0),
     321                 :     MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
     322                 :     TotalSelectorsInMethodPool(0), SelectorOffsets(0),
     323                 :     TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
     324                 :     NumStatHits(0), NumStatMisses(0),
     325                 :     NumSLocEntriesRead(0), NumStatementsRead(0),
     326                 :     NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
     327                 :     NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
     328               35:     CurrentlyLoadingTypeOrDecl(0) {
     329               35:   RelocatablePCH = false;
     330               35: }
     331                 : 
     332                 : PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
     333               13:                      Diagnostic &Diags, const char *isysroot)
     334                 :   : SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags),
     335                 :     SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),
     336                 :     IdentifierTableData(0), IdentifierLookupTable(0),
     337                 :     IdentifierOffsets(0),
     338                 :     MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
     339                 :     TotalSelectorsInMethodPool(0), SelectorOffsets(0),
     340                 :     TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
     341                 :     NumStatHits(0), NumStatMisses(0),
     342                 :     NumSLocEntriesRead(0), NumStatementsRead(0),
     343                 :     NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
     344                 :     NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
     345               13:     CurrentlyLoadingTypeOrDecl(0) {
     346               13:   RelocatablePCH = false;
     347               13: }
     348                 : 
                       44: branch 34 taken
                        0: branch 35 not taken
                        0: branch 71 not taken
                        0: branch 72 not taken
                        0: branch 108 not taken
                        0: branch 109 not taken
     349               44: PCHReader::~PCHReader() {}
     350                 : 
     351               41: Expr *PCHReader::ReadDeclExpr() {
     352               41:   return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
     353                 : }
     354                 : 
     355               37: Expr *PCHReader::ReadTypeExpr() {
     356               37:   return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
     357                 : }
     358                 : 
     359                 : 
     360                 : namespace {
     361                 : class PCHMethodPoolLookupTrait {
     362                 :   PCHReader &Reader;
     363                 : 
     364                 : public:
     365                 :   typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
     366                 : 
     367                 :   typedef Selector external_key_type;
     368                 :   typedef external_key_type internal_key_type;
     369                 : 
     370               30:   explicit PCHMethodPoolLookupTrait(PCHReader &Reader) : Reader(Reader) { }
     371                 : 
     372                 :   static bool EqualKey(const internal_key_type& a,
     373                1:                        const internal_key_type& b) {
     374                1:     return a == b;
     375                 :   }
     376                 : 
     377                1:   static unsigned ComputeHash(Selector Sel) {
     378                1:     unsigned N = Sel.getNumArgs();
                        0: branch 0 not taken
                        1: branch 1 taken
     379                1:     if (N == 0)
     380                0:       ++N;
     381                1:     unsigned R = 5381;
                        1: branch 0 taken
                        1: branch 1 taken
     382                2:     for (unsigned I = 0; I != N; ++I)
                        1: branch 1 taken
                        0: branch 2 not taken
     383                1:       if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
     384                1:         R = llvm::HashString(II->getName(), R);
     385                1:     return R;
     386                 :   }
     387                 : 
     388                 :   // This hopefully will just get inlined and removed by the optimizer.
     389                 :   static const internal_key_type&
     390                1:   GetInternalKey(const external_key_type& x) { return x; }
     391                 : 
     392                 :   static std::pair<unsigned, unsigned>
     393                1:   ReadKeyDataLength(const unsigned char*& d) {
     394                 :     using namespace clang::io;
     395                1:     unsigned KeyLen = ReadUnalignedLE16(d);
     396                1:     unsigned DataLen = ReadUnalignedLE16(d);
     397                1:     return std::make_pair(KeyLen, DataLen);
     398                 :   }
     399                 : 
     400               25:   internal_key_type ReadKey(const unsigned char* d, unsigned) {
     401                 :     using namespace clang::io;
     402               25:     SelectorTable &SelTable = Reader.getContext()->Selectors;
     403               25:     unsigned N = ReadUnalignedLE16(d);
     404                 :     IdentifierInfo *FirstII
     405               25:       = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
                       19: branch 0 taken
                        6: branch 1 taken
     406               25:     if (N == 0)
     407               19:       return SelTable.getNullarySelector(FirstII);
                        6: branch 0 taken
                        0: branch 1 not taken
     408                6:     else if (N == 1)
     409                6:       return SelTable.getUnarySelector(FirstII);
     410                 : 
     411                0:     llvm::SmallVector<IdentifierInfo *, 16> Args;
     412                0:     Args.push_back(FirstII);
                        0: branch 0 not taken
                        0: branch 1 not taken
     413                0:     for (unsigned I = 1; I != N; ++I)
     414                0:       Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
     415                 : 
     416                0:     return SelTable.getSelector(N, Args.data());
     417                 :   }
     418                 : 
     419                1:   data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
     420                 :     using namespace clang::io;
     421                1:     unsigned NumInstanceMethods = ReadUnalignedLE16(d);
     422                1:     unsigned NumFactoryMethods = ReadUnalignedLE16(d);
     423                 : 
     424                1:     data_type Result;
     425                 : 
     426                 :     // Load instance methods
     427                1:     ObjCMethodList *Prev = 0;
                        2: branch 0 taken
                        1: branch 1 taken
     428                3:     for (unsigned I = 0; I != NumInstanceMethods; ++I) {
     429                 :       ObjCMethodDecl *Method
     430                2:         = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
                        1: branch 0 taken
                        1: branch 1 taken
     431                2:       if (!Result.first.Method) {
     432                 :         // This is the first method, which is the easy case.
     433                1:         Result.first.Method = Method;
     434                1:         Prev = &Result.first;
     435                1:         continue;
     436                 :       }
     437                 : 
     438                1:       Prev->Next = new ObjCMethodList(Method, 0);
     439                1:       Prev = Prev->Next;
     440                 :     }
     441                 : 
     442                 :     // Load factory methods
     443                1:     Prev = 0;
                        0: branch 0 not taken
                        1: branch 1 taken
     444                1:     for (unsigned I = 0; I != NumFactoryMethods; ++I) {
     445                 :       ObjCMethodDecl *Method
     446                0:         = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
                        0: branch 0 not taken
                        0: branch 1 not taken
     447                0:       if (!Result.second.Method) {
     448                 :         // This is the first method, which is the easy case.
     449                0:         Result.second.Method = Method;
     450                0:         Prev = &Result.second;
     451                0:         continue;
     452                 :       }
     453                 : 
     454                0:       Prev->Next = new ObjCMethodList(Method, 0);
     455                0:       Prev = Prev->Next;
     456                 :     }
     457                 : 
     458                 :     return Result;
     459                 :   }
     460                 : };
     461                 : 
     462                 : } // end anonymous namespace
     463                 : 
     464                 : /// \brief The on-disk hash table used for the global method pool.
     465                 : typedef OnDiskChainedHashTable<PCHMethodPoolLookupTrait>
     466                 :   PCHMethodPoolLookupTable;
     467                 : 
     468                 : namespace {
     469                 : class PCHIdentifierLookupTrait {
     470                 :   PCHReader &Reader;
     471                 : 
     472                 :   // If we know the IdentifierInfo in advance, it is here and we will
     473                 :   // not build a new one. Used when deserializing information about an
     474                 :   // identifier that was constructed before the PCH file was read.
     475                 :   IdentifierInfo *KnownII;
     476                 : 
     477                 : public:
     478                 :   typedef IdentifierInfo * data_type;
     479                 : 
     480                 :   typedef const std::pair<const char*, unsigned> external_key_type;
     481                 : 
     482                 :   typedef external_key_type internal_key_type;
     483                 : 
     484             3890:   explicit PCHIdentifierLookupTrait(PCHReader &Reader, IdentifierInfo *II = 0)
     485             3890:     : Reader(Reader), KnownII(II) { }
     486                 : 
     487                 :   static bool EqualKey(const internal_key_type& a,
     488             5417:                        const internal_key_type& b) {
     489                 :     return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
                     5417: branch 0 taken
                        0: branch 1 not taken
                     5416: branch 3 taken
                        1: branch 4 taken
     490             5417:                                   : false;
     491                 :   }
     492                 : 
     493             5613:   static unsigned ComputeHash(const internal_key_type& a) {
     494             5613:     return llvm::HashString(llvm::StringRef(a.first, a.second));
     495                 :   }
     496                 : 
     497                 :   // This hopefully will just get inlined and removed by the optimizer.
     498                 :   static const internal_key_type&
     499             5613:   GetInternalKey(const external_key_type& x) { return x; }
     500                 : 
     501                 :   static std::pair<unsigned, unsigned>
     502             6779:   ReadKeyDataLength(const unsigned char*& d) {
     503                 :     using namespace clang::io;
     504             6779:     unsigned DataLen = ReadUnalignedLE16(d);
     505             6779:     unsigned KeyLen = ReadUnalignedLE16(d);
     506             6779:     return std::make_pair(KeyLen, DataLen);
     507                 :   }
     508                 : 
     509                 :   static std::pair<const char*, unsigned>
     510             5417:   ReadKey(const unsigned char* d, unsigned n) {
                     5417: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                     5417: branch 3 taken
     511             5417:     assert(n >= 2 && d[n-1] == '\0');
     512             5417:     return std::make_pair((const char*) d, n-1);
     513                 :   }
     514                 : 
     515                 :   IdentifierInfo *ReadData(const internal_key_type& k,
     516                 :                            const unsigned char* d,
     517             5416:                            unsigned DataLen) {
     518                 :     using namespace clang::io;
     519             5416:     pch::IdentID ID = ReadUnalignedLE32(d);
     520             5416:     bool IsInteresting = ID & 0x01;
     521                 : 
     522                 :     // Wipe out the "is interesting" bit.
     523             5416:     ID = ID >> 1;
     524                 : 
                     3483: branch 0 taken
                     1933: branch 1 taken
     525             5416:     if (!IsInteresting) {
     526                 :       // For unintersting identifiers, just build the IdentifierInfo
     527                 :       // and associate it with the persistent ID.
     528             3483:       IdentifierInfo *II = KnownII;
                      305: branch 0 taken
                     3178: branch 1 taken
     529             3483:       if (!II)
     530                 :         II = &Reader.getIdentifierTable().CreateIdentifierInfo(
     531              305:                                                  k.first, k.first + k.second);
     532             3483:       Reader.SetIdentifierInfo(ID, II);
     533             3483:       return II;
     534                 :     }
     535                 : 
     536             1933:     unsigned Bits = ReadUnalignedLE16(d);
     537             1933:     bool CPlusPlusOperatorKeyword = Bits & 0x01;
     538             1933:     Bits >>= 1;
     539             1933:     bool Poisoned = Bits & 0x01;
     540             1933:     Bits >>= 1;
     541             1933:     bool ExtensionToken = Bits & 0x01;
     542             1933:     Bits >>= 1;
     543             1933:     bool hasMacroDefinition = Bits & 0x01;
     544             1933:     Bits >>= 1;
     545             1933:     unsigned ObjCOrBuiltinID = Bits & 0x3FF;
     546             1933:     Bits >>= 10;
     547                 : 
                        0: branch 0 not taken
                     1933: branch 1 taken
     548             1933:     assert(Bits == 0 && "Extra bits in the identifier?");
     549             1933:     DataLen -= 6;
     550                 : 
     551                 :     // Build the IdentifierInfo itself and link the identifier ID with
     552                 :     // the new IdentifierInfo.
     553             1933:     IdentifierInfo *II = KnownII;
                     1268: branch 0 taken
                      665: branch 1 taken
     554             1933:     if (!II)
     555                 :       II = &Reader.getIdentifierTable().CreateIdentifierInfo(
     556             1268:                                                  k.first, k.first + k.second);
     557             1933:     Reader.SetIdentifierInfo(ID, II);
     558                 : 
     559                 :     // Set or check the various bits in the IdentifierInfo structure.
     560                 :     // FIXME: Load token IDs lazily, too?
     561             1933:     II->setObjCOrBuiltinID(ObjCOrBuiltinID);
     562                 :     assert(II->isExtensionToken() == ExtensionToken &&
                     1933: branch 1 taken
                        0: branch 2 not taken
     563             1933:            "Incorrect extension token flag");
     564                 :     (void)ExtensionToken;
     565             1933:     II->setIsPoisoned(Poisoned);
     566                 :     assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
                     1933: branch 1 taken
                        0: branch 2 not taken
     567             1933:            "Incorrect C++ operator keyword flag");
     568                 :     (void)CPlusPlusOperatorKeyword;
     569                 : 
     570                 :     // If this identifier is a macro, deserialize the macro
     571                 :     // definition.
                      324: branch 0 taken
                     1609: branch 1 taken
     572             1933:     if (hasMacroDefinition) {
     573              324:       uint32_t Offset = ReadUnalignedLE32(d);
     574              324:       Reader.ReadMacroRecord(Offset);
     575              324:       DataLen -= 4;
     576                 :     }
     577                 : 
     578                 :     // Read all of the declarations visible at global scope with this
     579                 :     // name.
                        0: branch 1 not taken
                     1933: branch 2 taken
     580             1933:     if (Reader.getContext() == 0) return II;
                      287: branch 0 taken
                     1646: branch 1 taken
     581             1933:     if (DataLen > 0) {
     582              287:       llvm::SmallVector<uint32_t, 4> DeclIDs;
                      299: branch 0 taken
                      287: branch 1 taken
     583              586:       for (; DataLen > 0; DataLen -= 4)
     584              299:         DeclIDs.push_back(ReadUnalignedLE32(d));
     585              287:       Reader.SetGloballyVisibleDecls(II, DeclIDs);
     586                 :     }
     587                 : 
     588             1933:     return II;
     589                 :   }
     590                 : };
     591                 : 
     592                 : } // end anonymous namespace
     593                 : 
     594                 : /// \brief The on-disk hash table used to contain information about
     595                 : /// all of the identifiers in the program.
     596                 : typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>
     597                 :   PCHIdentifierLookupTable;
     598                 : 
     599                1: bool PCHReader::Error(const char *Msg) {
     600                1:   unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Fatal, Msg);
     601                1:   Diag(DiagID);
     602                1:   return true;
     603                 : }
     604                 : 
     605                 : /// \brief Check the contents of the predefines buffer against the
     606                 : /// contents of the predefines buffer used to build the PCH file.
     607                 : ///
     608                 : /// The contents of the two predefines buffers should be the same. If
     609                 : /// not, then some command-line option changed the preprocessor state
     610                 : /// and we must reject the PCH file.
     611                 : ///
     612                 : /// \param PCHPredef The start of the predefines buffer in the PCH
     613                 : /// file.
     614                 : ///
     615                 : /// \param PCHPredefLen The length of the predefines buffer in the PCH
     616                 : /// file.
     617                 : ///
     618                 : /// \param PCHBufferID The FileID for the PCH predefines buffer.
     619                 : ///
     620                 : /// \returns true if there was a mismatch (in which case the PCH file
     621                 : /// should be ignored), or false otherwise.
     622                 : bool PCHReader::CheckPredefinesBuffer(llvm::StringRef PCHPredef,
     623               47:                                       FileID PCHBufferID) {
                       47: branch 1 taken
                        0: branch 2 not taken
     624               47:   if (Listener)
     625                 :     return Listener->ReadPredefinesBuffer(PCHPredef, PCHBufferID,
     626                 :                                           ActualOriginalFileName,
     627               47:                                           SuggestedPredefines);
     628                0:   return false;
     629                 : }
     630                 : 
     631                 : //===----------------------------------------------------------------------===//
     632                 : // Source Manager Deserialization
     633                 : //===----------------------------------------------------------------------===//
     634                 : 
     635                 : /// \brief Read the line table in the source manager block.
     636                 : /// \returns true if ther was an error.
     637               48: bool PCHReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
     638               48:   unsigned Idx = 0;
     639               48:   LineTableInfo &LineTable = SourceMgr.getLineTable();
     640                 : 
     641                 :   // Parse the file names
     642               48:   std::map<int, int> FileIDs;
                       97: branch 2 taken
                       48: branch 3 taken
     643              145:   for (int I = 0, N = Record[Idx++]; I != N; ++I) {
     644                 :     // Extract the file name
     645               97:     unsigned FilenameLen = Record[Idx++];
     646               97:     std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
     647               97:     Idx += FilenameLen;
     648               97:     MaybeAddSystemRootToFilename(Filename);
     649                 :     FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
     650               97:                                                   Filename.size());
     651                 :   }
     652                 : 
     653                 :   // Parse the line entries
     654               48:   std::vector<LineEntry> Entries;
                       49: branch 1 taken
                       48: branch 2 taken
     655              145:   while (Idx < Record.size()) {
     656               49:     int FID = FileIDs[Record[Idx++]];
     657                 : 
     658                 :     // Extract the line entries
     659               49:     unsigned NumEntries = Record[Idx++];
     660               49:     Entries.clear();
     661               49:     Entries.reserve(NumEntries);
                      145: branch 0 taken
                       49: branch 1 taken
     662              194:     for (unsigned I = 0; I != NumEntries; ++I) {
     663              145:       unsigned FileOffset = Record[Idx++];
     664              145:       unsigned LineNo = Record[Idx++];
     665              145:       int FilenameID = Record[Idx++];
     666                 :       SrcMgr::CharacteristicKind FileKind
     667              145:         = (SrcMgr::CharacteristicKind)Record[Idx++];
     668              145:       unsigned IncludeOffset = Record[Idx++];
     669                 :       Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
     670              145:                                        FileKind, IncludeOffset));
     671                 :     }
     672               49:     LineTable.AddEntry(FID, Entries);
     673                 :   }
     674                 : 
     675               48:   return false;
     676                 : }
     677                 : 
     678                 : namespace {
     679                 : 
     680                 : class PCHStatData {
     681                 : public:
     682                 :   const bool hasStat;
     683                 :   const ino_t ino;
     684                 :   const dev_t dev;
     685                 :   const mode_t mode;
     686                 :   const time_t mtime;
     687                 :   const off_t size;
     688                 : 
     689               95:   PCHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
     690               95:   : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
     691                 : 
     692                0:   PCHStatData()
     693                0:     : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
     694                 : };
     695                 : 
     696                 : class PCHStatLookupTrait {
     697                 :  public:
     698                 :   typedef const char *external_key_type;
     699                 :   typedef const char *internal_key_type;
     700                 : 
     701                 :   typedef PCHStatData data_type;
     702                 : 
     703              133:   static unsigned ComputeHash(const char *path) {
     704              133:     return llvm::HashString(path);
     705                 :   }
     706                 : 
     707              133:   static internal_key_type GetInternalKey(const char *path) { return path; }
     708                 : 
     709               95:   static bool EqualKey(internal_key_type a, internal_key_type b) {
     710               95:     return strcmp(a, b) == 0;
     711                 :   }
     712                 : 
     713                 :   static std::pair<unsigned, unsigned>
     714               96:   ReadKeyDataLength(const unsigned char*& d) {
     715               96:     unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
     716               96:     unsigned DataLen = (unsigned) *d++;
     717               96:     return std::make_pair(KeyLen + 1, DataLen);
     718                 :   }
     719                 : 
     720               95:   static internal_key_type ReadKey(const unsigned char *d, unsigned) {
     721               95:     return (const char *)d;
     722                 :   }
     723                 : 
     724                 :   static data_type ReadData(const internal_key_type, const unsigned char *d,
     725               95:                             unsigned /*DataLen*/) {
     726                 :     using namespace clang::io;
     727                 : 
                        0: branch 0 not taken
                       95: branch 1 taken
     728               95:     if (*d++ == 1)
     729                0:       return data_type();
     730                 : 
     731               95:     ino_t ino = (ino_t) ReadUnalignedLE32(d);
     732               95:     dev_t dev = (dev_t) ReadUnalignedLE32(d);
     733               95:     mode_t mode = (mode_t) ReadUnalignedLE16(d);
     734               95:     time_t mtime = (time_t) ReadUnalignedLE64(d);
     735               95:     off_t size = (off_t) ReadUnalignedLE64(d);
     736               95:     return data_type(ino, dev, mode, mtime, size);
     737                 :   }
     738                 : };
     739                 : 
     740                 : /// \brief stat() cache for precompiled headers.
     741                 : ///
     742                 : /// This cache is very similar to the stat cache used by pretokenized
     743                 : /// headers.
     744                 : class PCHStatCache : public StatSysCallCache {
     745                 :   typedef OnDiskChainedHashTable<PCHStatLookupTrait> CacheTy;
     746                 :   CacheTy *Cache;
     747                 : 
     748                 :   unsigned &NumStatHits, &NumStatMisses;
     749                 : public:
     750                 :   PCHStatCache(const unsigned char *Buckets,
     751                 :                const unsigned char *Base,
     752                 :                unsigned &NumStatHits,
     753               46:                unsigned &NumStatMisses)
     754               46:     : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
     755               46:     Cache = CacheTy::Create(Buckets, Base);
     756               46:   }
     757                 : 
                       43: branch 2 taken
                        0: branch 3 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
     758               43:   ~PCHStatCache() { delete Cache; }
     759                 : 
     760              133:   int stat(const char *path, struct stat *buf) {
     761                 :     // Do the lookup for the file's data in the PCH file.
     762              133:     CacheTy::iterator I = Cache->find(path);
     763                 : 
     764                 :     // If we don't get a hit in the PCH file just forward to 'stat'.
                       38: branch 2 taken
                       95: branch 3 taken
     765              133:     if (I == Cache->end()) {
     766               38:       ++NumStatMisses;
     767               38:       return StatSysCallCache::stat(path, buf);
     768                 :     }
     769                 : 
     770               95:     ++NumStatHits;
     771               95:     PCHStatData Data = *I;
     772                 : 
                        0: branch 0 not taken
                       95: branch 1 taken
     773               95:     if (!Data.hasStat)
     774                0:       return 1;
     775                 : 
     776               95:     buf->st_ino = Data.ino;
     777               95:     buf->st_dev = Data.dev;
     778               95:     buf->st_mtime = Data.mtime;
     779               95:     buf->st_mode = Data.mode;
     780               95:     buf->st_size = Data.size;
     781               95:     return 0;
     782                 :   }
     783                 : };
     784                 : } // end anonymous namespace
     785                 : 
     786                 : 
     787                 : /// \brief Read the source manager block
     788               48: PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
     789                 :   using namespace SrcMgr;
     790                 : 
     791                 :   // Set the source-location entry cursor to the current position in
     792                 :   // the stream. This cursor will be used to read the contents of the
     793                 :   // source manager block initially, and then lazily read
     794                 :   // source-location entries as needed.
     795               48:   SLocEntryCursor = Stream;
     796                 : 
     797                 :   // The stream itself is going to skip over the source manager block.
                        0: branch 1 not taken
                       48: branch 2 taken
     798               48:   if (Stream.SkipBlock()) {
     799                0:     Error("malformed block record in PCH file");
     800                0:     return Failure;
     801                 :   }
     802                 : 
     803                 :   // Enter the source manager block.
                        0: branch 1 not taken
                       48: branch 2 taken
     804               48:   if (SLocEntryCursor.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
     805                0:     Error("malformed source manager block record in PCH file");
     806                0:     return Failure;
     807                 :   }
     808                 : 
     809               48:   RecordData Record;
     810              296:   while (true) {
     811              344:     unsigned Code = SLocEntryCursor.ReadCode();
                        0: branch 0 not taken
                      344: branch 1 taken
     812              344:     if (Code == llvm::bitc::END_BLOCK) {
                        0: branch 1 not taken
                        0: branch 2 not taken
     813                0:       if (SLocEntryCursor.ReadBlockEnd()) {
     814                0:         Error("error at end of Source Manager block in PCH file");
     815                0:         return Failure;
     816                 :       }
     817                0:       return Success;
     818                 :     }
     819                 : 
                        0: branch 0 not taken
                      344: branch 1 taken
     820              344:     if (Code == llvm::bitc::ENTER_SUBBLOCK) {
     821                 :       // No known subblocks, always skip them.
     822                0:       SLocEntryCursor.ReadSubBlockID();
                        0: branch 1 not taken
                        0: branch 2 not taken
     823                0:       if (SLocEntryCursor.SkipBlock()) {
     824                0:         Error("malformed block record in PCH file");
     825                0:         return Failure;
     826                 :       }
     827                0:       continue;
     828                 :     }
     829                 : 
                      192: branch 0 taken
                      152: branch 1 taken
     830              344:     if (Code == llvm::bitc::DEFINE_ABBREV) {
     831              192:       SLocEntryCursor.ReadAbbrevRecord();
     832              192:       continue;
     833                 :     }
     834                 : 
     835                 :     // Read a record.
     836                 :     const char *BlobStart;
     837                 :     unsigned BlobLen;
     838              152:     Record.clear();
                        0: branch 1 not taken
                       48: branch 2 taken
                       56: branch 3 taken
                       48: branch 4 taken
     839              152:     switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
     840                 :     default:  // Default behavior: ignore.
     841                0:       break;
     842                 : 
     843                 :     case pch::SM_LINE_TABLE:
                        0: branch 1 not taken
                       48: branch 2 taken
     844               48:       if (ParseLineTable(Record))
     845                0:         return Failure;
     846               48:       break;
     847                 : 
     848                 :     case pch::SM_HEADER_FILE_INFO: {
     849               56:       HeaderFileInfo HFI;
     850               56:       HFI.isImport = Record[0];
     851               56:       HFI.DirInfo = Record[1];
     852               56:       HFI.NumIncludes = Record[2];
     853               56:       HFI.ControllingMacroID = Record[3];
                       56: branch 1 taken
                        0: branch 2 not taken
     854               56:       if (Listener)
     855               56:         Listener->ReadHeaderFileInfo(HFI);
     856               56:       break;
     857                 :     }
     858                 : 
     859                 :     case pch::SM_SLOC_FILE_ENTRY:
     860                 :     case pch::SM_SLOC_BUFFER_ENTRY:
     861                 :     case pch::SM_SLOC_INSTANTIATION_ENTRY:
     862                 :       // Once we hit one of the source location entries, we're done.
     863               48:       return Success;
     864                 :     }
     865               48:   }
     866                 : }
     867                 : 
     868                 : /// \brief Read in the source location entry with the given ID.
     869              141: PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
                        0: branch 0 not taken
                      141: branch 1 taken
     870              141:   if (ID == 0)
     871                0:     return Success;
     872                 : 
                        0: branch 0 not taken
                      141: branch 1 taken
     873              141:   if (ID > TotalNumSLocEntries) {
     874                0:     Error("source location entry ID out-of-range for PCH file");
     875                0:     return Failure;
     876                 :   }
     877                 : 
     878              141:   ++NumSLocEntriesRead;
     879              141:   SLocEntryCursor.JumpToBit(SLocOffsets[ID - 1]);
     880              141:   unsigned Code = SLocEntryCursor.ReadCode();
                      141: branch 0 taken
                        0: branch 1 not taken
                      141: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                      141: branch 5 taken
     881              141:   if (Code == llvm::bitc::END_BLOCK ||
     882                 :       Code == llvm::bitc::ENTER_SUBBLOCK ||
     883                 :       Code == llvm::bitc::DEFINE_ABBREV) {
     884                0:     Error("incorrectly-formatted source location entry in PCH file");
     885                0:     return Failure;
     886                 :   }
     887                 : 
     888              141:   RecordData Record;
     889                 :   const char *BlobStart;
     890                 :   unsigned BlobLen;
                        0: branch 1 not taken
                       53: branch 2 taken
                       52: branch 3 taken
                       36: branch 4 taken
     891              141:   switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
     892                 :   default:
     893                0:     Error("incorrectly-formatted source location entry in PCH file");
     894                0:     return Failure;
     895                 : 
     896                 :   case pch::SM_SLOC_FILE_ENTRY: {
     897               53:     std::string Filename(BlobStart, BlobStart + BlobLen);
     898               53:     MaybeAddSystemRootToFilename(Filename);
     899               53:     const FileEntry *File = FileMgr.getFile(Filename);
                        1: branch 0 taken
                       52: branch 1 taken
     900               53:     if (File == 0) {
     901                1:       std::string ErrorStr = "could not find file '";
     902                1:       ErrorStr += Filename;
     903                1:       ErrorStr += "' referenced by PCH file";
     904                1:       Error(ErrorStr.c_str());
     905                1:       return Failure;
     906                 :     }
     907                 : 
     908                 :     FileID FID = SourceMgr.createFileID(File,
     909                 :                                 SourceLocation::getFromRawEncoding(Record[1]),
     910                 :                                        (SrcMgr::CharacteristicKind)Record[2],
     911               52:                                         ID, Record[0]);
                        1: branch 1 taken
                       51: branch 2 taken
     912               52:     if (Record[3])
     913                 :       const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
     914                1:         .setHasLineDirectives();
     915                 : 
                        1: branch 1 taken
                       52: branch 2 taken
     916               53:     break;
     917                 :   }
     918                 : 
     919                 :   case pch::SM_SLOC_BUFFER_ENTRY: {
     920               52:     const char *Name = BlobStart;
     921               52:     unsigned Offset = Record[0];
     922               52:     unsigned Code = SLocEntryCursor.ReadCode();
     923               52:     Record.clear();
     924                 :     unsigned RecCode
     925               52:       = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
                        0: branch 0 not taken
                       52: branch 1 taken
     926               52:     assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file");
     927                 :     (void)RecCode;
     928                 :     llvm::MemoryBuffer *Buffer
     929                 :       = llvm::MemoryBuffer::getMemBuffer(BlobStart,
     930                 :                                          BlobStart + BlobLen - 1,
     931               52:                                          Name);
     932               52:     FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
     933                 : 
                       49: branch 1 taken
                        3: branch 2 taken
     934               52:     if (strcmp(Name, "<built-in>") == 0) {
     935               49:       PCHPredefinesBufferID = BufferID;
     936               49:       PCHPredefines = BlobStart;
     937               49:       PCHPredefinesLen = BlobLen - 1;
     938                 :     }
     939                 : 
     940               52:     break;
     941                 :   }
     942                 : 
     943                 :   case pch::SM_SLOC_INSTANTIATION_ENTRY: {
     944                 :     SourceLocation SpellingLoc
     945               36:       = SourceLocation::getFromRawEncoding(Record[1]);
     946                 :     SourceMgr.createInstantiationLoc(SpellingLoc,
     947                 :                               SourceLocation::getFromRawEncoding(Record[2]),
     948                 :                               SourceLocation::getFromRawEncoding(Record[3]),
     949                 :                                      Record[4],
     950                 :                                      ID,
     951               36:                                      Record[0]);
     952                 :     break;
     953                 :   }
     954                 :   }
     955                 : 
     956              140:   return Success;
     957                 : }
     958                 : 
     959                 : /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
     960                 : /// specified cursor.  Read the abbreviations that are at the top of the block
     961                 : /// and then leave the cursor pointing into the block.
     962                 : bool PCHReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
     963               47:                                  unsigned BlockID) {
                        0: branch 1 not taken
                       47: branch 2 taken
     964               47:   if (Cursor.EnterSubBlock(BlockID)) {
     965                0:     Error("malformed block record in PCH file");
     966                0:     return Failure;
     967                 :   }
     968                 : 
     969               47:   while (true) {
     970               94:     unsigned Code = Cursor.ReadCode();
     971                 : 
     972                 :     // We expect all abbrevs to be at the start of the block.
                       47: branch 0 taken
                       47: branch 1 taken
     973               94:     if (Code != llvm::bitc::DEFINE_ABBREV)
     974               47:       return false;
     975               47:     Cursor.ReadAbbrevRecord();
     976                 :   }
     977                 : }
     978                 : 
     979              324: void PCHReader::ReadMacroRecord(uint64_t Offset) {
                        0: branch 0 not taken
                      324: branch 1 taken
     980              324:   assert(PP && "Forgot to set Preprocessor ?");
     981                 : 
     982                 :   // Keep track of where we are in the stream, then jump back there
     983                 :   // after reading this macro.
     984              324:   SavedStreamPosition SavedPosition(Stream);
     985                 : 
     986              324:   Stream.JumpToBit(Offset);
     987              324:   RecordData Record;
     988              324:   llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
     989              324:   MacroInfo *Macro = 0;
     990                 : 
     991              732:   while (true) {
     992             1056:     unsigned Code = Stream.ReadCode();
                        3: branch 0 taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                     1053: branch 3 taken
     993             1056:     switch (Code) {
     994                 :     case llvm::bitc::END_BLOCK:
     995                 :       return;
     996                 : 
     997                 :     case llvm::bitc::ENTER_SUBBLOCK:
     998                 :       // No known subblocks, always skip them.
     999                0:       Stream.ReadSubBlockID();
                        0: branch 1 not taken
                        0: branch 2 not taken
    1000                0:       if (Stream.SkipBlock()) {
    1001                0:         Error("malformed block record in PCH file");
    1002                 :         return;
    1003                 :       }
    1004                0:       continue;
    1005                 : 
    1006                 :     case llvm::bitc::DEFINE_ABBREV:
    1007                0:       Stream.ReadAbbrevRecord();
    1008                0:       continue;
    1009                 :     default: break;
    1010                 :     }
    1011                 : 
    1012                 :     // Read a record.
    1013             1053:     Record.clear();
    1014                 :     pch::PreprocessorRecordTypes RecType =
    1015             1053:       (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
                      645: branch 0 taken
                      408: branch 1 taken
                        0: branch 2 not taken
    1016             1053:     switch (RecType) {
    1017                 :     case pch::PP_MACRO_OBJECT_LIKE:
    1018                 :     case pch::PP_MACRO_FUNCTION_LIKE: {
    1019                 :       // If we already have a macro, that means that we've hit the end
    1020                 :       // of the definition of the macro we were looking for. We're
    1021                 :       // done.
                      324: branch 0 taken
                      321: branch 1 taken
    1022              645:       if (Macro)
    1023                 :         return;
    1024                 : 
    1025              324:       IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
                        0: branch 0 not taken
                      324: branch 1 taken
    1026              324:       if (II == 0) {
    1027                0:         Error("macro must have a name in PCH file");
    1028                 :         return;
    1029                 :       }
    1030              324:       SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
    1031              324:       bool isUsed = Record[2];
    1032                 : 
    1033              324:       MacroInfo *MI = PP->AllocateMacroInfo(Loc);
    1034              324:       MI->setIsUsed(isUsed);
    1035                 : 
                       10: branch 0 taken
                      314: branch 1 taken
    1036              324:       if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
    1037                 :         // Decode function-like macro info.
    1038               10:         bool isC99VarArgs = Record[3];
    1039               10:         bool isGNUVarArgs = Record[4];
    1040               10:         MacroArgs.clear();
    1041               10:         unsigned NumArgs = Record[5];
                       15: branch 0 taken
                       10: branch 1 taken
    1042               25:         for (unsigned i = 0; i != NumArgs; ++i)
    1043               15:           MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
    1044                 : 
    1045                 :         // Install function-like macro info.
    1046               10:         MI->setIsFunctionLike();
                        2: branch 0 taken
                        8: branch 1 taken
    1047               10:         if (isC99VarArgs) MI->setIsC99Varargs();
                        0: branch 0 not taken
                       10: branch 1 taken
    1048               10:         if (isGNUVarArgs) MI->setIsGNUVarargs();
    1049                 :         MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
    1050               10:                             PP->getPreprocessorAllocator());
    1051                 :       }
    1052                 : 
    1053                 :       // Finally, install the macro.
    1054              324:       PP->setMacroInfo(II, MI);
    1055                 : 
    1056                 :       // Remember that we saw this macro last so that we add the tokens that
    1057                 :       // form its body to it.
    1058              324:       Macro = MI;
    1059              324:       ++NumMacrosRead;
    1060              324:       break;
    1061                 :     }
    1062                 : 
    1063                 :     case pch::PP_TOKEN: {
    1064                 :       // If we see a TOKEN before a PP_MACRO_*, then the file is
    1065                 :       // erroneous, just pretend we didn't see this.
                      408: branch 0 taken
                        0: branch 1 not taken
    1066              408:       if (Macro == 0) break;
    1067                 : 
    1068              408:       Token Tok;
    1069              408:       Tok.startToken();
    1070              408:       Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
    1071              408:       Tok.setLength(Record[1]);
                       77: branch 2 taken
                      331: branch 3 taken
    1072              408:       if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
    1073               77:         Tok.setIdentifierInfo(II);
    1074              408:       Tok.setKind((tok::TokenKind)Record[3]);
    1075              408:       Tok.setFlag((Token::TokenFlags)Record[4]);
    1076              408:       Macro->AddTokenToBody(Tok);
    1077                 :       break;
    1078                 :     }
    1079                 :   }
    1080              324:   }
    1081                 : }
    1082                 : 
    1083                3: void PCHReader::ReadDefinedMacros() {
    1084                 :   // If there was no preprocessor block, do nothing.
                        0: branch 1 not taken
                        3: branch 2 taken
    1085                3:   if (!MacroCursor.getBitStreamReader())
    1086                0:     return;
    1087                 :   
    1088                3:   llvm::BitstreamCursor Cursor = MacroCursor;
                        0: branch 1 not taken
                        3: branch 2 taken
    1089                3:   if (Cursor.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) {
    1090                0:     Error("malformed preprocessor block record in PCH file");
    1091                 :     return;
    1092                 :   }
    1093                 :   
    1094                3:   RecordData Record;
    1095              701:   while (true) {
    1096              704:     unsigned Code = Cursor.ReadCode();
                        3: branch 0 taken
                      701: branch 1 taken
    1097              704:     if (Code == llvm::bitc::END_BLOCK) {
                        0: branch 1 not taken
                        3: branch 2 taken
    1098                3:       if (Cursor.ReadBlockEnd())
    1099                0:         Error("error at end of preprocessor block in PCH file");
    1100                 :       return;
    1101                 :     }
    1102                 :     
                        0: branch 0 not taken
                      701: branch 1 taken
    1103              701:     if (Code == llvm::bitc::ENTER_SUBBLOCK) {
    1104                 :       // No known subblocks, always skip them.
    1105                0:       Cursor.ReadSubBlockID();
                        0: branch 1 not taken
                        0: branch 2 not taken
    1106                0:       if (Cursor.SkipBlock()) {
    1107                0:         Error("malformed block record in PCH file");
    1108                 :         return;
    1109                 :       }
    1110                0:       continue;
    1111                 :     }
    1112                 :     
                        0: branch 0 not taken
                      701: branch 1 taken
    1113              701:     if (Code == llvm::bitc::DEFINE_ABBREV) {
    1114                0:       Cursor.ReadAbbrevRecord();
    1115                0:       continue;
    1116                 :     }
    1117                 :     
    1118                 :     // Read a record.
    1119                 :     const char *BlobStart;
    1120                 :     unsigned BlobLen;
    1121              701:     Record.clear();
                        0: branch 1 not taken
                      315: branch 2 taken
                      386: branch 3 taken
    1122              701:     switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
    1123                 :     default:  // Default behavior: ignore.
    1124                0:       break;
    1125                 :         
    1126                 :     case pch::PP_MACRO_OBJECT_LIKE:
    1127                 :     case pch::PP_MACRO_FUNCTION_LIKE:
    1128              315:         DecodeIdentifierInfo(Record[0]);
    1129                 :       break;
    1130                 : 
    1131                 :     case pch::PP_TOKEN:
    1132                 :       // Ignore tokens.
    1133                 :       break;
    1134                 :     }
    1135                3:   }
    1136                 : }
    1137                 : 
    1138                 : /// \brief If we are loading a relocatable PCH file, and the filename is
    1139                 : /// not an absolute path, add the system root to the beginning of the file
    1140                 : /// name.
    1141              198: void PCHReader::MaybeAddSystemRootToFilename(std::string &Filename) {
    1142                 :   // If this is not a relocatable PCH file, there's nothing to do.
                      188: branch 0 taken
                       10: branch 1 taken
    1143              198:   if (!RelocatablePCH)
    1144              188:     return;
    1145                 : 
                       10: branch 1 taken
                        0: branch 2 not taken
                        1: branch 6 taken
                        9: branch 7 taken
                       10: branch 8 taken
                        0: branch 9 not taken
                        1: branch 11 taken
                        9: branch 12 taken
    1146               10:   if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
    1147                1:     return;
    1148                 : 
                        0: branch 0 not taken
                        9: branch 1 taken
    1149                9:   if (isysroot == 0) {
    1150                 :     // If no system root was given, default to '/'
    1151                0:     Filename.insert(Filename.begin(), '/');
    1152                0:     return;
    1153                 :   }
    1154                 : 
    1155                9:   unsigned Length = strlen(isysroot);
                        5: branch 0 taken
                        4: branch 1 taken
    1156                9:   if (isysroot[Length - 1] != '/')
    1157                5:     Filename.insert(Filename.begin(), '/');
    1158                 : 
    1159                9:   Filename.insert(Filename.begin(), isysroot, isysroot + Length);
    1160                 : }
    1161                 : 
    1162                 : PCHReader::PCHReadResult
    1163               48: PCHReader::ReadPCHBlock() {
                        0: branch 1 not taken
                       48: branch 2 taken
    1164               48:   if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
    1165                0:     Error("malformed block record in PCH file");
    1166                0:     return Failure;
    1167                 :   }
    1168                 : 
    1169                 :   // Read all of the records and blocks for the PCH file.
    1170               48:   RecordData Record;
                     1378: branch 1 taken
                        0: branch 2 not taken
    1171               48:   while (!Stream.AtEndOfStream()) {
    1172             1378:     unsigned Code = Stream.ReadCode();
                       47: branch 0 taken
                     1331: branch 1 taken
    1173             1378:     if (Code == llvm::bitc::END_BLOCK) {
                        0: branch 1 not taken
                       47: branch 2 taken
    1174               47:       if (Stream.ReadBlockEnd()) {
    1175                0:         Error("error at end of module block in PCH file");
    1176                0:         return Failure;
    1177                 :       }
    1178                 : 
    1179               47:       return Success;
    1180                 :     }
    1181                 : 
                      142: branch 0 taken
                     1189: branch 1 taken
    1182             1331:     if (Code == llvm::bitc::ENTER_SUBBLOCK) {
                       47: branch 1 taken
                       47: branch 2 taken
                       48: branch 3 taken
                        0: branch 4 not taken
    1183              142:       switch (Stream.ReadSubBlockID()) {
    1184                 :       case pch::DECLTYPES_BLOCK_ID:
    1185                 :         // We lazily load the decls block, but we want to set up the
    1186                 :         // DeclsCursor cursor to point into it.  Clone our current bitcode
    1187                 :         // cursor to it, enter the block and read the abbrevs in that block.
    1188                 :         // With the main cursor, we just skip over it.
    1189               47:         DeclsCursor = Stream;
                       47: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                       47: branch 5 taken
                        0: branch 6 not taken
                       47: branch 7 taken
    1190               47:         if (Stream.SkipBlock() ||  // Skip with the main cursor.
    1191                 :             // Read the abbrevs.
    1192                 :             ReadBlockAbbrevs(DeclsCursor, pch::DECLTYPES_BLOCK_ID)) {
    1193                0:           Error("malformed block record in PCH file");
    1194                0:           return Failure;
    1195                 :         }
    1196               47:         break;
    1197                 : 
    1198                 :       case pch::PREPROCESSOR_BLOCK_ID:
    1199               47:         MacroCursor = Stream;
                       34: branch 0 taken
                       13: branch 1 taken
    1200               47:         if (PP)
    1201               34:           PP->setExternalSource(this);
    1202                 : 
                        0: branch 1 not taken
                       47: branch 2 taken
    1203               47:         if (Stream.SkipBlock()) {
    1204                0:           Error("malformed block record in PCH file");
    1205                0:           return Failure;
    1206                 :         }
    1207               47:         break;
    1208                 : 
    1209                 :       case pch::SOURCE_MANAGER_BLOCK_ID:
                       48: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
    1210               48:         switch (ReadSourceManagerBlock()) {
    1211                 :         case Success:
    1212               48:           break;
    1213                 : 
    1214                 :         case Failure:
    1215                0:           Error("malformed source manager block in PCH file");
    1216                0:           return Failure;
    1217                 : 
    1218                 :         case IgnorePCH:
    1219                0:           return IgnorePCH;
    1220                 :         }
    1221                 :         break;
    1222                 :       }
    1223              142:       continue;
    1224                 :     }
    1225                 : 
                      477: branch 0 taken
                      712: branch 1 taken
    1226             1189:     if (Code == llvm::bitc::DEFINE_ABBREV) {
    1227              477:       Stream.ReadAbbrevRecord();
    1228              477:       continue;
    1229                 :     }
    1230                 : 
    1231                 :     // Read and process a record.
    1232              712:     Record.clear();
    1233              712:     const char *BlobStart = 0;
    1234              712:     unsigned BlobLen = 0;
                        0: branch 1 not taken
                       47: branch 2 taken
                       47: branch 3 taken
                       48: branch 4 taken
                       48: branch 5 taken
                       47: branch 6 taken
                       47: branch 7 taken
                       23: branch 8 taken
                       47: branch 9 taken
                       47: branch 10 taken
                       13: branch 11 taken
                        2: branch 12 taken
                        6: branch 13 taken
                        6: branch 14 taken
                        4: branch 15 taken
                       48: branch 16 taken
                       48: branch 17 taken
                       46: branch 18 taken
                        3: branch 19 taken
                       48: branch 20 taken
                       39: branch 21 taken
                       48: branch 22 taken
    1235              712:     switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
    1236                 :                                                    &BlobStart, &BlobLen)) {
    1237                 :     default:  // Default behavior: ignore.
    1238                0:       break;
    1239                 : 
    1240                 :     case pch::TYPE_OFFSET:
                        0: branch 1 not taken
                       47: branch 2 taken
    1241               47:       if (!TypesLoaded.empty()) {
    1242                0:         Error("duplicate TYPE_OFFSET record in PCH file");
    1243                0:         return Failure;
    1244                 :       }
    1245               47:       TypeOffsets = (const uint32_t *)BlobStart;
    1246               47:       TypesLoaded.resize(Record[0]);
    1247               47:       break;
    1248                 : 
    1249                 :     case pch::DECL_OFFSET:
                        0: branch 1 not taken
                       47: branch 2 taken
    1250               47:       if (!DeclsLoaded.empty()) {
    1251                0:         Error("duplicate DECL_OFFSET record in PCH file");
    1252                0:         return Failure;
    1253                 :       }
    1254               47:       DeclOffsets = (const uint32_t *)BlobStart;
    1255               47:       DeclsLoaded.resize(Record[0]);
    1256               47:       break;
    1257                 : 
    1258                 :     case pch::LANGUAGE_OPTIONS:
                        0: branch 1 not taken
                       48: branch 2 taken
    1259               48:       if (ParseLanguageOptions(Record))
    1260                0:         return IgnorePCH;
    1261               48:       break;
    1262                 : 
    1263                 :     case pch::METADATA: {
                        0: branch 1 not taken
                       48: branch 2 taken
    1264               48:       if (Record[0] != pch::VERSION_MAJOR) {
    1265                 :         Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old
                        0: branch 1 not taken
                        0: branch 2 not taken
    1266                0:                                            : diag::warn_pch_version_too_new);
    1267                0:         return IgnorePCH;
    1268                 :       }
    1269                 : 
    1270               48:       RelocatablePCH = Record[4];
                       48: branch 1 taken
                        0: branch 2 not taken
    1271               48:       if (Listener) {
    1272               48:         std::string TargetTriple(BlobStart, BlobLen);
                        0: branch 3 not taken
                       48: branch 4 taken
    1273               48:         if (Listener->ReadTargetTriple(TargetTriple))
                       48: branch 1 taken
                        0: branch 2 not taken
    1274                0:           return IgnorePCH;
    1275                 :       }
    1276               48:       break;
    1277                 :     }
    1278                 : 
    1279                 :     case pch::IDENTIFIER_TABLE:
    1280               47:       IdentifierTableData = BlobStart;
                       47: branch 1 taken
                        0: branch 2 not taken
    1281               47:       if (Record[0]) {
    1282                 :         IdentifierLookupTable
    1283                 :           = PCHIdentifierLookupTable::Create(
    1284                 :                         (const unsigned char *)IdentifierTableData + Record[0],
    1285                 :                         (const unsigned char *)IdentifierTableData,
    1286               47:                         PCHIdentifierLookupTrait(*this));
                       34: branch 0 taken
                       13: branch 1 taken
    1287               47:         if (PP)
    1288               34:           PP->getIdentifierTable().setExternalIdentifierLookup(this);
    1289                 :       }
    1290               47:       break;
    1291                 : 
    1292                 :     case pch::IDENTIFIER_OFFSET:
                        0: branch 1 not taken
                       47: branch 2 taken
    1293               47:       if (!IdentifiersLoaded.empty()) {
    1294                0:         Error("duplicate IDENTIFIER_OFFSET record in PCH file");
    1295                0:         return Failure;
    1296                 :       }
    1297               47:       IdentifierOffsets = (const uint32_t *)BlobStart;
    1298               47:       IdentifiersLoaded.resize(Record[0]);
                       34: branch 0 taken
                       13: branch 1 taken
    1299               47:       if (PP)
    1300               34:         PP->getHeaderSearchInfo().SetExternalLookup(this);
    1301               47:       break;
    1302                 : 
    1303                 :     case pch::EXTERNAL_DEFINITIONS:
                        0: branch 1 not taken
                       23: branch 2 taken
    1304               23:       if (!ExternalDefinitions.empty()) {
    1305                0:         Error("duplicate EXTERNAL_DEFINITIONS record in PCH file");
    1306                0:         return Failure;
    1307                 :       }
    1308               23:       ExternalDefinitions.swap(Record);
    1309               23:       break;
    1310                 : 
    1311                 :     case pch::SPECIAL_TYPES:
    1312               47:       SpecialTypes.swap(Record);
    1313               47:       break;
    1314                 : 
    1315                 :     case pch::STATISTICS:
    1316               47:       TotalNumStatements = Record[0];
    1317               47:       TotalNumMacros = Record[1];
    1318               47:       TotalLexicalDeclContexts = Record[2];
    1319               47:       TotalVisibleDeclContexts = Record[3];
    1320               47:       break;
    1321                 : 
    1322                 :     case pch::TENTATIVE_DEFINITIONS:
                        0: branch 1 not taken
                       13: branch 2 taken
    1323               13:       if (!TentativeDefinitions.empty()) {
    1324                0:         Error("duplicate TENTATIVE_DEFINITIONS record in PCH file");
    1325                0:         return Failure;
    1326                 :       }
    1327               13:       TentativeDefinitions.swap(Record);
    1328               13:       break;
    1329                 : 
    1330                 :     case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
                        0: branch 1 not taken
                        2: branch 2 taken
    1331                2:       if (!LocallyScopedExternalDecls.empty()) {
    1332                0:         Error("duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
    1333                0:         return Failure;
    1334                 :       }
    1335                2:       LocallyScopedExternalDecls.swap(Record);
    1336                2:       break;
    1337                 : 
    1338                 :     case pch::SELECTOR_OFFSETS:
    1339                6:       SelectorOffsets = (const uint32_t *)BlobStart;
    1340                6:       TotalNumSelectors = Record[0];
    1341                6:       SelectorsLoaded.resize(TotalNumSelectors);
    1342                6:       break;
    1343                 : 
    1344                 :     case pch::METHOD_POOL:
    1345                6:       MethodPoolLookupTableData = (const unsigned char *)BlobStart;
                        6: branch 1 taken
                        0: branch 2 not taken
    1346                6:       if (Record[0])
    1347                 :         MethodPoolLookupTable
    1348                 :           = PCHMethodPoolLookupTable::Create(
    1349                 :                         MethodPoolLookupTableData + Record[0],
    1350                 :                         MethodPoolLookupTableData,
    1351                6:                         PCHMethodPoolLookupTrait(*this));
    1352                6:       TotalSelectorsInMethodPool = Record[1];
    1353                6:       break;
    1354                 : 
    1355                 :     case pch::PP_COUNTER_VALUE:
                        4: branch 1 taken
                        0: branch 2 not taken
                        4: branch 4 taken
                        0: branch 5 not taken
                        4: branch 6 taken
                        0: branch 7 not taken
    1356                4:       if (!Record.empty() && Listener)
    1357                4:         Listener->ReadCounter(Record[0]);
    1358                4:       break;
    1359                 : 
    1360                 :     case pch::SOURCE_LOCATION_OFFSETS:
    1361               48:       SLocOffsets = (const uint32_t *)BlobStart;
    1362               48:       TotalNumSLocEntries = Record[0];
    1363               48:       SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
    1364               48:       break;
    1365                 : 
    1366                 :     case pch::SOURCE_LOCATION_PRELOADS:
                      102: branch 1 taken
                       47: branch 2 taken
    1367              149:       for (unsigned I = 0, N = Record.size(); I != N; ++I) {
    1368              102:         PCHReadResult Result = ReadSLocEntryRecord(Record[I]);
                        1: branch 0 taken
                      101: branch 1 taken
    1369              102:         if (Result != Success)
    1370                1:           return Result;
    1371                 :       }
    1372               47:       break;
    1373                 : 
    1374                 :     case pch::STAT_CACHE: {
    1375                 :       PCHStatCache *MyStatCache = 
    1376                 :         new PCHStatCache((const unsigned char *)BlobStart + Record[0],
    1377                 :                          (const unsigned char *)BlobStart,
    1378               46:                          NumStatHits, NumStatMisses);
    1379               46:       FileMgr.addStatCache(MyStatCache);
    1380               46:       StatCache = MyStatCache;
    1381               46:       break;
    1382                 :     }
    1383                 :         
    1384                 :     case pch::EXT_VECTOR_DECLS:
                        0: branch 1 not taken
                        3: branch 2 taken
    1385                3:       if (!ExtVectorDecls.empty()) {
    1386                0:         Error("duplicate EXT_VECTOR_DECLS record in PCH file");
    1387                0:         return Failure;
    1388                 :       }
    1389                3:       ExtVectorDecls.swap(Record);
    1390                3:       break;
    1391                 : 
    1392                 :     case pch::ORIGINAL_FILE_NAME:
    1393               48:       ActualOriginalFileName.assign(BlobStart, BlobLen);
    1394               48:       OriginalFileName = ActualOriginalFileName;
    1395               48:       MaybeAddSystemRootToFilename(OriginalFileName);
    1396               48:       break;
    1397                 : 
    1398                 :     case pch::COMMENT_RANGES:
    1399               39:       Comments = (SourceRange *)BlobStart;
    1400               39:       NumComments = BlobLen / sizeof(SourceRange);
    1401               39:       break;
    1402                 :         
    1403                 :     case pch::VERSION_CONTROL_BRANCH_REVISION: {
    1404               48:       llvm::StringRef CurBranch = getClangFullRepositoryVersion();
    1405               48:       llvm::StringRef PCHBranch(BlobStart, BlobLen);
                        0: branch 1 not taken
                       48: branch 2 taken
    1406               48:       if (CurBranch != PCHBranch) {
    1407                0:         Diag(diag::warn_pch_different_branch) << PCHBranch << CurBranch;
    1408                0:         return IgnorePCH;
    1409                 :       }
    1410                 :       break;
    1411                 :     }
    1412                 :     }
    1413                 :   }
    1414                0:   Error("premature end of bitstream in PCH file");
    1415                0:   return Failure;
    1416                 : }
    1417                 : 
    1418               48: PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
    1419                 :   // Set the PCH file name.
    1420               48:   this->FileName = FileName;
    1421                 : 
    1422                 :   // Open the PCH file.
    1423                 :   //
    1424                 :   // FIXME: This shouldn't be here, we should just take a raw_ostream.
    1425               48:   std::string ErrStr;
    1426               48:   Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
                        0: branch 1 not taken
                       48: branch 2 taken
    1427               48:   if (!Buffer) {
    1428                0:     Error(ErrStr.c_str());
    1429                0:     return IgnorePCH;
    1430                 :   }
    1431                 : 
    1432                 :   // Initialize the stream
    1433                 :   StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
    1434               48:                   (const unsigned char *)Buffer->getBufferEnd());
    1435               48:   Stream.init(StreamFile);
    1436                 : 
    1437                 :   // Sniff for the signature.
                       48: branch 1 taken
                        0: branch 2 not taken
                       48: branch 4 taken
                        0: branch 5 not taken
                       48: branch 7 taken
                        0: branch 8 not taken
                        0: branch 10 not taken
                       48: branch 11 taken
                        0: branch 12 not taken
                       48: branch 13 taken
    1438               48:   if (Stream.Read(8) != 'C' ||
    1439                 :       Stream.Read(8) != 'P' ||
    1440                 :       Stream.Read(8) != 'C' ||
    1441                 :       Stream.Read(8) != 'H') {
    1442                0:     Diag(diag::err_not_a_pch_file) << FileName;
    1443                0:     return Failure;
    1444                 :   }
    1445                 : 
                       96: branch 1 taken
                       47: branch 2 taken
    1446              191:   while (!Stream.AtEndOfStream()) {
    1447               96:     unsigned Code = Stream.ReadCode();
    1448                 : 
                        0: branch 0 not taken
                       96: branch 1 taken
    1449               96:     if (Code != llvm::bitc::ENTER_SUBBLOCK) {
    1450                0:       Error("invalid record at top-level of PCH file");
    1451                0:       return Failure;
    1452                 :     }
    1453                 : 
    1454               96:     unsigned BlockID = Stream.ReadSubBlockID();
    1455                 : 
    1456                 :     // We only know the PCH subblock ID.
                       48: branch 0 taken
                       48: branch 1 taken
                        0: branch 2 not taken
    1457               96:     switch (BlockID) {
    1458                 :     case llvm::bitc::BLOCKINFO_BLOCK_ID:
                        0: branch 1 not taken
                       48: branch 2 taken
    1459               48:       if (Stream.ReadBlockInfoBlock()) {
    1460                0:         Error("malformed BlockInfoBlock in PCH file");
    1461                0:         return Failure;
    1462                 :       }
    1463               48:       break;
    1464                 :     case pch::PCH_BLOCK_ID:
                       47: branch 1 taken
                        1: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
    1465               48:       switch (ReadPCHBlock()) {
    1466                 :       case Success:
    1467               47:         break;
    1468                 : 
    1469                 :       case Failure:
    1470                1:         return Failure;
    1471                 : 
    1472                 :       case IgnorePCH:
    1473                 :         // FIXME: We could consider reading through to the end of this
    1474                 :         // PCH block, skipping subblocks, to see if there are other
    1475                 :         // PCH blocks elsewhere.
    1476                 : 
    1477                 :         // Clear out any preallocated source location entries, so that
    1478                 :         // the source manager does not try to resolve them later.
    1479                0:         SourceMgr.ClearPreallocatedSLocEntries();
    1480                 : 
    1481                 :         // Remove the stat cache.
                        0: branch 0 not taken
                        0: branch 1 not taken
    1482                0:         if (StatCache)
    1483                0:           FileMgr.removeStatCache((PCHStatCache*)StatCache);
    1484                 : 
    1485                0:         return IgnorePCH;
    1486                 :       }
    1487               47:       break;
    1488                 :     default:
                        0: branch 1 not taken
                        0: branch 2 not taken
    1489                0:       if (Stream.SkipBlock()) {
    1490                0:         Error("malformed block record in PCH file");
    1491                0:         return Failure;
    1492                 :       }
    1493                 :       break;
    1494                 :     }
    1495                 :   }
    1496                 : 
    1497                 :   // Check the predefines buffer.
                        1: branch 2 taken
                       46: branch 3 taken
    1498               47:   if (CheckPredefinesBuffer(llvm::StringRef(PCHPredefines, PCHPredefinesLen),
    1499                 :                             PCHPredefinesBufferID))
    1500                1:     return IgnorePCH;
    1501                 : 
                       33: branch 0 taken
                       13: branch 1 taken
    1502               46:   if (PP) {
    1503                 :     // Initialization of keywords and pragmas occurs before the
    1504                 :     // PCH file is read, so there may be some identifiers that were
    1505                 :     // loaded into the IdentifierTable before we intercepted the
    1506                 :     // creation of identifiers. Iterate through the list of known
    1507                 :     // identifiers and determine whether we have to establish
    1508                 :     // preprocessor definitions or top-level identifier declaration
    1509                 :     // chains for those identifiers.
    1510                 :     //
    1511                 :     // We copy the IdentifierInfo pointers to a small vector first,
    1512                 :     // since de-serializing declarations or macro definitions can add
    1513                 :     // new entries into the identifier table, invalidating the
    1514                 :     // iterators.
    1515               33:     llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
                     3843: branch 4 taken
                       33: branch 5 taken
    1516             3909:     for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
    1517               33:                                 IdEnd = PP->getIdentifierTable().end();
    1518                 :          Id != IdEnd; ++Id)
    1519             3843:       Identifiers.push_back(Id->second);
    1520                 :     PCHIdentifierLookupTable *IdTable
    1521               33:       = (PCHIdentifierLookupTable *)IdentifierLookupTable;
                     3843: branch 1 taken
                       33: branch 2 taken
    1522             3876:     for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
    1523             3843:       IdentifierInfo *II = Identifiers[I];
    1524                 :       // Look in the on-disk hash table for an entry for
    1525             3843:       PCHIdentifierLookupTrait Info(*this, II);
    1526             3843:       std::pair<const char*, unsigned> Key(II->getNameStart(), II->getLength());
    1527             3843:       PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
                        0: branch 2 not taken
                     3843: branch 3 taken
    1528             3843:       if (Pos == IdTable->end())
    1529                0:         continue;
    1530                 : 
    1531                 :       // Dereferencing the iterator has the effect of populating the
    1532                 :       // IdentifierInfo node with the various declarations it needs.
    1533             3843:       (void)*Pos;
    1534               33:     }
    1535                 :   }
    1536                 : 
                       33: branch 0 taken
                       13: branch 1 taken
    1537               46:   if (Context)
    1538               33:     InitializeContext(*Context);
    1539                 : 
    1540               46:   return Success;
    1541                 : }
    1542                 : 
    1543               46: void PCHReader::InitializeContext(ASTContext &Ctx) {
    1544               46:   Context = &Ctx;
                        0: branch 0 not taken
                       46: branch 1 taken
    1545               46:   assert(Context && "Passed null context!");
    1546                 : 
                        0: branch 0 not taken
                       46: branch 1 taken
    1547               46:   assert(PP && "Forgot to set Preprocessor ?");
    1548               46:   PP->getIdentifierTable().setExternalIdentifierLookup(this);
    1549               46:   PP->getHeaderSearchInfo().SetExternalLookup(this);
    1550               46:   PP->setExternalSource(this);
    1551                 :   
    1552                 :   // Load the translation unit declaration
    1553               46:   ReadDeclRecord(DeclOffsets[0], 0);
    1554                 : 
    1555                 :   // Load the special types.
    1556                 :   Context->setBuiltinVaListType(
    1557               46:     GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
                       12: branch 1 taken
                       34: branch 2 taken
    1558               46:   if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
    1559               12:     Context->setObjCIdType(GetType(Id));
                       12: branch 1 taken
                       34: branch 2 taken
    1560               46:   if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
    1561               12:     Context->setObjCSelType(GetType(Sel));
                       12: branch 1 taken
                       34: branch 2 taken
    1562               46:   if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
    1563               12:     Context->setObjCProtoType(GetType(Proto));
                       12: branch 1 taken
                       34: branch 2 taken
    1564               46:   if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
    1565               12:     Context->setObjCClassType(GetType(Class));
    1566                 : 
                        0: branch 1 not taken
                       46: branch 2 taken
    1567               46:   if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
    1568                0:     Context->setCFConstantStringType(GetType(String));
                        0: branch 0 not taken
                       46: branch 1 taken
    1569               46:   if (unsigned FastEnum
    1570               46:         = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
    1571                0:     Context->setObjCFastEnumerationStateType(GetType(FastEnum));
                        1: branch 1 taken
                       45: branch 2 taken
    1572               46:   if (unsigned File = SpecialTypes[pch::SPECIAL_TYPE_FILE]) {
    1573                1:     QualType FileType = GetType(File);
                        1: branch 1 taken
                        0: branch 2 not taken
    1574                1:     assert(!FileType.isNull() && "FILE type is NULL");
                        1: branch 2 taken
                        0: branch 3 not taken
    1575                1:     if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
    1576                1:       Context->setFILEDecl(Typedef->getDecl());
    1577                 :     else {
    1578                0:       const TagType *Tag = FileType->getAs<TagType>();
                        0: branch 0 not taken
                        0: branch 1 not taken
    1579                0:       assert(Tag && "Invalid FILE type in PCH file");
    1580                0:       Context->setFILEDecl(Tag->getDecl());
    1581                 :     }
    1582                 :   }
                        0: branch 1 not taken
                       46: branch 2 taken
    1583               46:   if (unsigned Jmp_buf = SpecialTypes[pch::SPECIAL_TYPE_jmp_buf]) {
    1584                0:     QualType Jmp_bufType = GetType(Jmp_buf);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1585                0:     assert(!Jmp_bufType.isNull() && "jmp_bug type is NULL");
                        0: branch 2 not taken
                        0: branch 3 not taken
    1586                0:     if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
    1587                0:       Context->setjmp_bufDecl(Typedef->getDecl());
    1588                 :     else {
    1589                0:       const TagType *Tag = Jmp_bufType->getAs<TagType>();
                        0: branch 0 not taken
                        0: branch 1 not taken
    1590                0:       assert(Tag && "Invalid jmp_bug type in PCH file");
    1591                0:       Context->setjmp_bufDecl(Tag->getDecl());
    1592                 :     }
    1593                 :   }
                        0: branch 1 not taken
                       46: branch 2 taken
    1594               46:   if (unsigned Sigjmp_buf = SpecialTypes[pch::SPECIAL_TYPE_sigjmp_buf]) {
    1595                0:     QualType Sigjmp_bufType = GetType(Sigjmp_buf);
                        0: branch 1 not taken
                        0: branch 2 not taken
    1596                0:     assert(!Sigjmp_bufType.isNull() && "sigjmp_buf type is NULL");
                        0: branch 2 not taken
                        0: branch 3 not taken
    1597                0:     if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
    1598                0:       Context->setsigjmp_bufDecl(Typedef->getDecl());
    1599                 :     else {
    1600                0:       const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
                        0: branch 0 not taken
                        0: branch 1 not taken
    1601                0:       assert(Tag && "Invalid sigjmp_buf type in PCH file");
    1602                0:       Context->setsigjmp_bufDecl(Tag->getDecl());
    1603                 :     }
    1604                 :   }
                       12: branch 0 taken
                       34: branch 1 taken
    1605               46:   if (unsigned ObjCIdRedef
    1606               46:         = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID_REDEFINITION])
    1607               12:     Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
                       12: branch 0 taken
                       34: branch 1 taken
    1608               46:   if (unsigned ObjCClassRedef
    1609               46:       = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
    1610               12:     Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
    1611                 : #if 0
    1612                 :   // FIXME. Accommodate for this in several PCH/Index tests
    1613                 :   if (unsigned ObjCSelRedef
    1614                 :       = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
    1615                 :     Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
    1616                 : #endif
                        0: branch 1 not taken
                       46: branch 2 taken
    1617               46:   if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR])
    1618                0:     Context->setBlockDescriptorType(GetType(String));
                        0: branch 0 not taken
                       46: branch 1 taken
    1619               46:   if (unsigned String
    1620               46:       = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
    1621                0:     Context->setBlockDescriptorExtendedType(GetType(String));
    1622               46: }
    1623                 : 
    1624                 : /// \brief Retrieve the name of the original source file name
    1625                 : /// directly from the PCH file, without actually loading the PCH
    1626                 : /// file.
    1627                 : std::string PCHReader::getOriginalSourceFile(const std::string &PCHFileName,
    1628               36:                                              Diagnostic &Diags) {
    1629                 :   // Open the PCH file.
    1630               36:   std::string ErrStr;
    1631               36:   llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
    1632               36:   Buffer.reset(llvm::MemoryBuffer::getFile(PCHFileName.c_str(), &ErrStr));
                        0: branch 1 not taken
                       36: branch 2 taken
    1633               36:   if (!Buffer) {
    1634                0:     Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
    1635                0:     return std::string();
    1636                 :   }
    1637                 : 
    1638                 :   // Initialize the stream
    1639               36:   llvm::BitstreamReader StreamFile;
    1640               36:   llvm::BitstreamCursor Stream;
    1641                 :   StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
    1642               36:                   (const unsigned char *)Buffer->getBufferEnd());
    1643               36:   Stream.init(StreamFile);
    1644                 : 
    1645                 :   // Sniff for the signature.
                       36: branch 1 taken
                        0: branch 2 not taken
                       36: branch 4 taken
                        0: branch 5 not taken
                       36: branch 7 taken
                        0: branch 8 not taken
                        0: branch 10 not taken
                       36: branch 11 taken
                        0: branch 12 not taken
                       36: branch 13 taken
    1646               36:   if (Stream.Read(8) != 'C' ||
    1647                 :       Stream.Read(8) != 'P' ||
    1648                 :       Stream.Read(8) != 'C' ||
    1649                 :       Stream.Read(8) != 'H') {
    1650                0:     Diags.Report(diag::err_fe_not_a_pch_file) << PCHFileName;
    1651                0:     return std::string();
    1652                 :   }
    1653                 : 
    1654               36:   RecordData Record;
                      216: branch 1 taken
                        0: branch 2 not taken
    1655               36:   while (!Stream.AtEndOfStream()) {
    1656              216:     unsigned Code = Stream.ReadCode();
    1657                 : 
                       72: branch 0 taken
                      144: branch 1 taken
    1658              216:     if (Code == llvm::bitc::ENTER_SUBBLOCK) {
    1659               72:       unsigned BlockID = Stream.ReadSubBlockID();
    1660                 : 
    1661                 :       // We only know the PCH subblock ID.
                       36: branch 0 taken
                       36: branch 1 taken
    1662               72:       switch (BlockID) {
    1663                 :       case pch::PCH_BLOCK_ID:
                        0: branch 1 not taken
                       36: branch 2 taken
    1664               36:         if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
    1665                0:           Diags.Report(diag::err_fe_pch_malformed_block) << PCHFileName;
    1666                0:           return std::string();
    1667                 :         }
    1668               36:         break;
    1669                 : 
    1670                 :       default:
                        0: branch 1 not taken
                       36: branch 2 taken
    1671               36:         if (Stream.SkipBlock()) {
    1672                0:           Diags.Report(diag::err_fe_pch_malformed_block) << PCHFileName;
    1673                0:           return std::string();
    1674                 :         }
    1675                 :         break;
    1676                 :       }
    1677               72:       continue;
    1678                 :     }
    1679                 : 
                        0: branch 0 not taken
                      144: branch 1 taken
    1680              144:     if (Code == llvm::bitc::END_BLOCK) {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1681                0:       if (Stream.ReadBlockEnd()) {
    1682                0:         Diags.Report(diag::err_fe_pch_error_at_end_block) << PCHFileName;
    1683                0:         return std::string();
    1684                 :       }
    1685                0:       continue;
    1686                 :     }
    1687                 : 
                       72: branch 0 taken
                       72: branch 1 taken
    1688              144:     if (Code == llvm::bitc::DEFINE_ABBREV) {
    1689               72:       Stream.ReadAbbrevRecord();
    1690               72:       continue;
    1691                 :     }
    1692                 : 
    1693               72:     Record.clear();
    1694               72:     const char *BlobStart = 0;
    1695               72:     unsigned BlobLen = 0;
                       36: branch 1 taken
                       36: branch 2 taken
    1696               72:     if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
    1697                 :           == pch::ORIGINAL_FILE_NAME)
    1698               36:       return std::string(BlobStart, BlobLen);
    1699                 :   }
    1700                 : 
    1701                0:   return std::string();
    1702                 : }
    1703                 : 
    1704                 : /// \brief Parse the record that corresponds to a LangOptions data
    1705                 : /// structure.
    1706                 : ///
    1707                 : /// This routine compares the language options used to generate the
    1708                 : /// PCH file against the language options set for the current
    1709                 : /// compilation. For each option, we classify differences between the
    1710                 : /// two compiler states as either "benign" or "important". Benign
    1711                 : /// differences don't matter, and we accept them without complaint
    1712                 : /// (and without modifying the language options). Differences between
    1713                 : /// the states for important options cause the PCH file to be
    1714                 : /// unusable, so we emit a warning and return true to indicate that
    1715                 : /// there was an error.
    1716                 : ///
    1717                 : /// \returns true if the PCH file is unacceptable, false otherwise.
    1718                 : bool PCHReader::ParseLanguageOptions(
    1719               48:                              const llvm::SmallVectorImpl<uint64_t> &Record) {
                       48: branch 1 taken
                        0: branch 2 not taken
    1720               48:   if (Listener) {
    1721               48:     LangOptions LangOpts;
    1722                 : 
    1723                 :   #define PARSE_LANGOPT(Option)                  \
    1724                 :       LangOpts.Option = Record[Idx];             \
    1725                 :       ++Idx
    1726                 : 
    1727               48:     unsigned Idx = 0;
    1728               48:     PARSE_LANGOPT(Trigraphs);
    1729               48:     PARSE_LANGOPT(BCPLComment);
    1730               48:     PARSE_LANGOPT(DollarIdents);
    1731               48:     PARSE_LANGOPT(AsmPreprocessor);
    1732               48:     PARSE_LANGOPT(GNUMode);
    1733               48:     PARSE_LANGOPT(ImplicitInt);
    1734               48:     PARSE_LANGOPT(Digraphs);
    1735               48:     PARSE_LANGOPT(HexFloats);
    1736               48:     PARSE_LANGOPT(C99);
    1737               48:     PARSE_LANGOPT(Microsoft);
    1738               48:     PARSE_LANGOPT(CPlusPlus);
    1739               48:     PARSE_LANGOPT(CPlusPlus0x);
    1740               48:     PARSE_LANGOPT(CXXOperatorNames);
    1741               48:     PARSE_LANGOPT(ObjC1);
    1742               48:     PARSE_LANGOPT(ObjC2);
    1743               48:     PARSE_LANGOPT(ObjCNonFragileABI);
    1744               48:     PARSE_LANGOPT(ObjCNonFragileABI2);
    1745               48:     PARSE_LANGOPT(PascalStrings);
    1746               48:     PARSE_LANGOPT(WritableStrings);
    1747               48:     PARSE_LANGOPT(LaxVectorConversions);
    1748               48:     PARSE_LANGOPT(AltiVec);
    1749               48:     PARSE_LANGOPT(Exceptions);
    1750               48:     PARSE_LANGOPT(NeXTRuntime);
    1751               48:     PARSE_LANGOPT(Freestanding);
    1752               48:     PARSE_LANGOPT(NoBuiltin);
    1753               48:     PARSE_LANGOPT(ThreadsafeStatics);
    1754               48:     PARSE_LANGOPT(POSIXThreads);
    1755               48:     PARSE_LANGOPT(Blocks);
    1756               48:     PARSE_LANGOPT(EmitAllDecls);
    1757               48:     PARSE_LANGOPT(MathErrno);
    1758               48:     PARSE_LANGOPT(OverflowChecking);
    1759               48:     PARSE_LANGOPT(HeinousExtensions);
    1760               48:     PARSE_LANGOPT(Optimize);
    1761               48:     PARSE_LANGOPT(OptimizeSize);
    1762               48:     PARSE_LANGOPT(Static);
    1763               48:     PARSE_LANGOPT(PICLevel);
    1764               48:     PARSE_LANGOPT(GNUInline);
    1765               48:     PARSE_LANGOPT(NoInline);
    1766               48:     PARSE_LANGOPT(AccessControl);
    1767               48:     PARSE_LANGOPT(CharIsSigned);
    1768               48:     PARSE_LANGOPT(ShortWChar);
    1769               48:     LangOpts.setGCMode((LangOptions::GCMode)Record[Idx]);
    1770               48:     ++Idx;
    1771               48:     LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]);
    1772               48:     ++Idx;
    1773                 :     LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
    1774               48:                                    Record[Idx]);
    1775               48:     ++Idx;
    1776               48:     PARSE_LANGOPT(InstantiationDepth);
    1777               48:     PARSE_LANGOPT(OpenCL);
    1778               48:     PARSE_LANGOPT(CatchUndefined);
    1779                 :     // FIXME: Missing ElideConstructors?!
    1780                 :   #undef PARSE_LANGOPT
    1781                 : 
    1782               48:     return Listener->ReadLanguageOptions(LangOpts);
    1783                 :   }
    1784                 : 
    1785                0:   return false;
    1786                 : }
    1787                 : 
    1788                0: void PCHReader::ReadComments(std::vector<SourceRange> &Comments) {
    1789                0:   Comments.resize(NumComments);
    1790                 :   std::copy(this->Comments, this->Comments + NumComments,
    1791                0:             Comments.begin());
    1792                0: }
    1793                 : 
    1794                 : /// \brief Read and return the type at the given offset.
    1795                 : ///
    1796                 : /// This routine actually reads the record corresponding to the type
    1797                 : /// at the given offset in the bitstream. It is a helper routine for
    1798                 : /// GetType, which deals with reading type IDs.
    1799              379: QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
    1800                 :   // Keep track of where we are in the stream, then jump back there
    1801                 :   // after reading this type.
    1802              379:   SavedStreamPosition SavedPosition(DeclsCursor);
    1803                 : 
    1804                 :   // Note that we are loading a type record.
    1805              379:   LoadingTypeOrDecl Loading(*this);
    1806                 : 
    1807              379:   DeclsCursor.JumpToBit(Offset);
    1808              379:   RecordData Record;
    1809              379:   unsigned Code = DeclsCursor.ReadCode();
                        1: branch 1 taken
                        2: branch 2 taken
                       68: branch 3 taken
                        2: branch 4 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                       23: branch 8 taken
                        6: branch 9 taken
                        1: branch 10 taken
                        1: branch 11 taken
                        4: branch 12 taken
                        5: branch 13 taken
                       39: branch 14 taken
                        0: branch 15 not taken
                       88: branch 16 taken
                       36: branch 17 taken
                        4: branch 18 taken
                        0: branch 19 not taken
                       31: branch 20 taken
                        6: branch 21 taken
                        0: branch 22 not taken
                       22: branch 23 taken
                       40: branch 24 taken
                        0: branch 25 not taken
                        0: branch 26 not taken
    1810              379:   switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
    1811                 :   case pch::TYPE_EXT_QUAL: {
    1812                 :     assert(Record.size() == 2 &&
                        1: branch 1 taken
                        0: branch 2 not taken
    1813                1:            "Incorrect encoding of extended qualifier type");
    1814                1:     QualType Base = GetType(Record[0]);
    1815                1:     Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
    1816                1:     return Context->getQualifiedType(Base, Quals);
    1817                 :   }
    1818                 : 
    1819                 :   case pch::TYPE_COMPLEX: {
                        2: branch 1 taken
                        0: branch 2 not taken
    1820                2:     assert(Record.size() == 1 && "Incorrect encoding of complex type");
    1821                2:     QualType ElemType = GetType(Record[0]);
    1822                2:     return Context->getComplexType(ElemType);
    1823                 :   }
    1824                 : 
    1825                 :   case pch::TYPE_POINTER: {
                       68: branch 1 taken
                        0: branch 2 not taken
    1826               68:     assert(Record.size() == 1 && "Incorrect encoding of pointer type");
    1827               68:     QualType PointeeType = GetType(Record[0]);
    1828               68:     return Context->getPointerType(PointeeType);
    1829                 :   }
    1830                 : 
    1831                 :   case pch::TYPE_BLOCK_POINTER: {
                        2: branch 1 taken
                        0: branch 2 not taken
    1832                2:     assert(Record.size() == 1 && "Incorrect encoding of block pointer type");
    1833                2:     QualType PointeeType = GetType(Record[0]);
    1834                2:     return Context->getBlockPointerType(PointeeType);
    1835                 :   }
    1836                 : 
    1837                 :   case pch::TYPE_LVALUE_REFERENCE: {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1838                0:     assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type");
    1839                0:     QualType PointeeType = GetType(Record[0]);
    1840                0:     return Context->getLValueReferenceType(PointeeType);
    1841                 :   }
    1842                 : 
    1843                 :   case pch::TYPE_RVALUE_REFERENCE: {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1844                0:     assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type");
    1845                0:     QualType PointeeType = GetType(Record[0]);
    1846                0:     return Context->getRValueReferenceType(PointeeType);
    1847                 :   }
    1848                 : 
    1849                 :   case pch::TYPE_MEMBER_POINTER: {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1850                0:     assert(Record.size() == 1 && "Incorrect encoding of member pointer type");
    1851                0:     QualType PointeeType = GetType(Record[0]);
    1852                0:     QualType ClassType = GetType(Record[1]);
    1853                0:     return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
    1854                 :   }
    1855                 : 
    1856                 :   case pch::TYPE_CONSTANT_ARRAY: {
    1857               23:     QualType ElementType = GetType(Record[0]);
    1858               23:     ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
    1859               23:     unsigned IndexTypeQuals = Record[2];
    1860               23:     unsigned Idx = 3;
    1861               23:     llvm::APInt Size = ReadAPInt(Record, Idx);
    1862                 :     return Context->getConstantArrayType(ElementType, Size,
    1863               23:                                          ASM, IndexTypeQuals);
    1864                 :   }
    1865                 : 
    1866                 :   case pch::TYPE_INCOMPLETE_ARRAY: {
    1867                6:     QualType ElementType = GetType(Record[0]);
    1868                6:     ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
    1869                6:     unsigned IndexTypeQuals = Record[2];
    1870                6:     return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
    1871                 :   }
    1872                 : 
    1873                 :   case pch::TYPE_VARIABLE_ARRAY: {
    1874                1:     QualType ElementType = GetType(Record[0]);
    1875                1:     ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
    1876                1:     unsigned IndexTypeQuals = Record[2];
    1877                1:     SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
    1878                1:     SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
    1879                 :     return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
    1880                 :                                          ASM, IndexTypeQuals,
    1881                1:                                          SourceRange(LBLoc, RBLoc));
    1882                 :   }
    1883                 : 
    1884                 :   case pch::TYPE_VECTOR: {
                        0: branch 1 not taken
                        1: branch 2 taken
    1885                1:     if (Record.size() != 4) {
    1886                0:       Error("incorrect encoding of vector type in PCH file");
    1887                0:       return QualType();
    1888                 :     }
    1889                 : 
    1890                1:     QualType ElementType = GetType(Record[0]);
    1891                1:     unsigned NumElements = Record[1];
    1892                1:     bool AltiVec = Record[2];
    1893                1:     bool Pixel = Record[3];
    1894                1:     return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel);
    1895                 :   }
    1896                 : 
    1897                 :   case pch::TYPE_EXT_VECTOR: {
                        0: branch 1 not taken
                        4: branch 2 taken
    1898                4:     if (Record.size() != 4) {
    1899                0:       Error("incorrect encoding of extended vector type in PCH file");
    1900                0:       return QualType();
    1901                 :     }
    1902                 : 
    1903                4:     QualType ElementType = GetType(Record[0]);
    1904                4:     unsigned NumElements = Record[1];
    1905                4:     return Context->getExtVectorType(ElementType, NumElements);
    1906                 :   }
    1907                 : 
    1908                 :   case pch::TYPE_FUNCTION_NO_PROTO: {
                        0: branch 1 not taken
                        5: branch 2 taken
    1909                5:     if (Record.size() != 3) {
    1910                0:       Error("incorrect encoding of no-proto function type");
    1911                0:       return QualType();
    1912                 :     }
    1913                5:     QualType ResultType = GetType(Record[0]);
    1914                 :     return Context->getFunctionNoProtoType(ResultType, Record[1],
    1915                5:                                            (CallingConv)Record[2]);
    1916                 :   }
    1917                 : 
    1918                 :   case pch::TYPE_FUNCTION_PROTO: {
    1919               39:     QualType ResultType = GetType(Record[0]);
    1920               39:     bool NoReturn = Record[1];
    1921               39:     CallingConv CallConv = (CallingConv)Record[2];
    1922               39:     unsigned Idx = 3;
    1923               39:     unsigned NumParams = Record[Idx++];
    1924               39:     llvm::SmallVector<QualType, 16> ParamTypes;
                       58: branch 0 taken
                       39: branch 1 taken
    1925               97:     for (unsigned I = 0; I != NumParams; ++I)
    1926               58:       ParamTypes.push_back(GetType(Record[Idx++]));
    1927               39:     bool isVariadic = Record[Idx++];
    1928               39:     unsigned Quals = Record[Idx++];
    1929               39:     bool hasExceptionSpec = Record[Idx++];
    1930               39:     bool hasAnyExceptionSpec = Record[Idx++];
    1931               39:     unsigned NumExceptions = Record[Idx++];
    1932               39:     llvm::SmallVector<QualType, 2> Exceptions;
                        0: branch 0 not taken
                       39: branch 1 taken
    1933               39:     for (unsigned I = 0; I != NumExceptions; ++I)
    1934                0:       Exceptions.push_back(GetType(Record[Idx++]));
    1935                 :     return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
    1936                 :                                     isVariadic, Quals, hasExceptionSpec,
    1937                 :                                     hasAnyExceptionSpec, NumExceptions,
    1938               39:                                     Exceptions.data(), NoReturn, CallConv);
    1939                 :   }
    1940                 : 
    1941                 :   case pch::TYPE_UNRESOLVED_USING:
    1942                 :     return Context->getTypeDeclType(
    1943                0:              cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
    1944                 : 
    1945                 :   case pch::TYPE_TYPEDEF:
                       88: branch 1 taken
                        0: branch 2 not taken
    1946               88:     assert(Record.size() == 1 && "incorrect encoding of typedef type");
    1947               88:     return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
    1948                 : 
    1949                 :   case pch::TYPE_TYPEOF_EXPR:
    1950               36:     return Context->getTypeOfExprType(ReadTypeExpr());
    1951                 : 
    1952                 :   case pch::TYPE_TYPEOF: {
                        0: branch 1 not taken
                        4: branch 2 taken
    1953                4:     if (Record.size() != 1) {
    1954                0:       Error("incorrect encoding of typeof(type) in PCH file");
    1955                0:       return QualType();
    1956                 :     }
    1957                4:     QualType UnderlyingType = GetType(Record[0]);
    1958                4:     return Context->getTypeOfType(UnderlyingType);
    1959                 :   }
    1960                 : 
    1961                 :   case pch::TYPE_DECLTYPE:
    1962                0:     return Context->getDecltypeType(ReadTypeExpr());
    1963                 : 
    1964                 :   case pch::TYPE_RECORD:
                       31: branch 1 taken
                        0: branch 2 not taken
    1965               31:     assert(Record.size() == 1 && "incorrect encoding of record type");
    1966               31:     return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
    1967                 : 
    1968                 :   case pch::TYPE_ENUM:
                        6: branch 1 taken
                        0: branch 2 not taken
    1969                6:     assert(Record.size() == 1 && "incorrect encoding of enum type");
    1970                6:     return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
    1971                 : 
    1972                 :   case pch::TYPE_ELABORATED: {
                        0: branch 1 not taken
                        0: branch 2 not taken
    1973                0:     assert(Record.size() == 2 && "incorrect encoding of elaborated type");
    1974                0:     unsigned Tag = Record[1];
    1975                 :     return Context->getElaboratedType(GetType(Record[0]),
    1976                0:                                       (ElaboratedType::TagKind) Tag);
    1977                 :   }
    1978                 : 
    1979                 :   case pch::TYPE_OBJC_INTERFACE: {
    1980               22:     unsigned Idx = 0;
    1981               22:     ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
    1982               22:     unsigned NumProtos = Record[Idx++];
    1983               22:     llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
                        1: branch 0 taken
                       22: branch 1 taken
    1984               23:     for (unsigned I = 0; I != NumProtos; ++I)
    1985                1:       Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
    1986               22:     return Context->getObjCInterfaceType(ItfD, Protos.data(), NumProtos);
    1987                 :   }
    1988                 : 
    1989                 :   case pch::TYPE_OBJC_OBJECT_POINTER: {
    1990               40:     unsigned Idx = 0;
    1991               40:     QualType OIT = GetType(Record[Idx++]);
    1992               40:     unsigned NumProtos = Record[Idx++];
    1993               40:     llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
                        6: branch 0 taken
                       40: branch 1 taken
    1994               46:     for (unsigned I = 0; I != NumProtos; ++I)
    1995                6:       Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
    1996               40:     return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos);
    1997                 :   }
    1998                 : 
    1999                 :   case pch::TYPE_SUBST_TEMPLATE_TYPE_PARM: {
    2000                0:     unsigned Idx = 0;
    2001                0:     QualType Parm = GetType(Record[Idx++]);
    2002                0:     QualType Replacement = GetType(Record[Idx++]);
    2003                 :     return
    2004                 :       Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
    2005                0:                                             Replacement);
    2006                 :   }
    2007                 :   }
    2008                 :   // Suppress a GCC warning
    2009                0:   return QualType();
    2010                 : }
    2011                 : 
    2012                 : namespace {
    2013                 : 
    2014                 : class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
    2015                 :   PCHReader &Reader;
    2016                 :   const PCHReader::RecordData &Record;
    2017                 :   unsigned &Idx;
    2018                 : 
    2019                 : public:
    2020                 :   TypeLocReader(PCHReader &Reader, const PCHReader::RecordData &Record,
    2021              373:                 unsigned &Idx)
    2022              373:     : Reader(Reader), Record(Record), Idx(Idx) { }
    2023                 : 
    2024                 :   // We want compile-time assurance that we've enumerated all of
    2025                 :   // these, so unfortunately we have to declare them first, then
    2026                 :   // define them out-of-line.
    2027                 : #define ABSTRACT_TYPELOC(CLASS, PARENT)
    2028                 : #define TYPELOC(CLASS, PARENT) \
    2029                 :   void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
    2030                 : #include "clang/AST/TypeLocNodes.def"
    2031                 : 
    2032                 :   void VisitFunctionTypeLoc(FunctionTypeLoc);
    2033                 :   void VisitArrayTypeLoc(ArrayTypeLoc);
    2034                 : };
    2035                 : 
    2036                 : }
    2037                 : 
    2038               14: void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
    2039                 :   // nothing to do
    2040               14: }
    2041              284: void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
    2042              284:   TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
                      178: branch 1 taken
                      106: branch 2 taken
    2043              284:   if (TL.needsExtraLocalData()) {
    2044              178:     TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
    2045              178:     TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
    2046              178:     TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
    2047              178:     TL.setModeAttr(Record[Idx++]);
    2048                 :   }
    2049              284: }
    2050                1: void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
    2051                1:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2052                1: }
    2053               71: void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
    2054               71:   TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2055               71: }
    2056                2: void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
    2057                2:   TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2058                2: }
    2059                0: void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
    2060                0:   TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2061                0: }
    2062                0: void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
    2063                0:   TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2064                0: }
    2065                0: void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
    2066                0:   TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2067                0: }
    2068               19: void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
    2069               19:   TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2070               19:   TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
                       12: branch 1 taken
                        7: branch 2 taken
    2071               19:   if (Record[Idx++])
    2072               12:     TL.setSizeExpr(Reader.ReadDeclExpr());
    2073                 :   else
    2074                7:     TL.setSizeExpr(0);
    2075               19: }
    2076               11: void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
    2077               11:   VisitArrayTypeLoc(TL);
    2078               11: }
    2079                7: void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
    2080                7:   VisitArrayTypeLoc(TL);
    2081                7: }
    2082                1: void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
    2083                1:   VisitArrayTypeLoc(TL);
    2084                1: }
    2085                 : void TypeLocReader::VisitDependentSizedArrayTypeLoc(
    2086                0:                                             DependentSizedArrayTypeLoc TL) {
    2087                0:   VisitArrayTypeLoc(TL);
    2088                0: }
    2089                 : void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
    2090                0:                                         DependentSizedExtVectorTypeLoc TL) {
    2091                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2092                0: }
    2093                1: void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
    2094                1:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2095                1: }
    2096                4: void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
    2097                4:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2098                4: }
    2099               49: void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
    2100               49:   TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2101               49:   TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
                       59: branch 1 taken
                       49: branch 2 taken
    2102              108:   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
    2103               59:     TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
    2104                 :   }
    2105               49: }
    2106               43: void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
    2107               43:   VisitFunctionTypeLoc(TL);
    2108               43: }
    2109                6: void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
    2110                6:   VisitFunctionTypeLoc(TL);
    2111                6: }
    2112                0: void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
    2113                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2114                0: }
    2115               15: void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
    2116               15:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2117               15: }
    2118               36: void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
    2119               36:   TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2120               36:   TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2121               36:   TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2122               36: }
    2123                4: void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
    2124                4:   TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2125                4:   TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2126                4:   TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2127                4:   TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(Record, Idx));
    2128                4: }
    2129                0: void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
    2130                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2131                0: }
    2132               19: void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
    2133               19:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2134               19: }
    2135                1: void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
    2136                1:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2137                1: }
    2138                0: void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
    2139                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2140                0: }
    2141                0: void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
    2142                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2143                0: }
    2144                 : void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
    2145                0:                                             SubstTemplateTypeParmTypeLoc TL) {
    2146                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2147                0: }
    2148                 : void TypeLocReader::VisitTemplateSpecializationTypeLoc(
    2149                0:                                            TemplateSpecializationTypeLoc TL) {
    2150                0:   TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2151                0:   TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2152                0:   TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
                        0: branch 1 not taken
                        0: branch 2 not taken
    2153                0:   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
    2154                 :     TL.setArgLocInfo(i,
    2155                 :         Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
    2156                0:                                           Record, Idx));
    2157                0: }
    2158                0: void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
    2159                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2160                0: }
    2161                0: void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
    2162                0:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2163                0: }
    2164                8: void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
    2165                8:   TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2166                8:   TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2167                8:   TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
                        1: branch 1 taken
                        8: branch 2 taken
    2168                9:   for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
    2169                1:     TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
    2170                8: }
    2171               37: void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
    2172               37:   TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2173               37:   TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2174               37:   TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
    2175               37:   TL.setHasBaseTypeAsWritten(Record[Idx++]);
    2176               37:   TL.setHasProtocolsAsWritten(Record[Idx++]);
                        5: branch 1 taken
                       32: branch 2 taken
    2177               37:   if (TL.hasProtocolsAsWritten())
                        5: branch 1 taken
                        5: branch 2 taken
    2178               10:     for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
    2179                5:       TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
    2180               37: }
    2181                 : 
    2182                 : TypeSourceInfo *PCHReader::GetTypeSourceInfo(const RecordData &Record,
    2183              380:                                              unsigned &Idx) {
    2184              380:   QualType InfoTy = GetType(Record[Idx++]);
                        7: branch 1 taken
                      373: branch 2 taken
    2185              380:   if (InfoTy.isNull())
    2186                7:     return 0;
    2187                 : 
    2188              373:   TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
    2189              373:   TypeLocReader TLR(*this, Record, Idx);
                      565: branch 3 taken
                      373: branch 4 taken
    2190              938:   for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
    2191              565:     TLR.Visit(TL);
    2192              373:   return TInfo;
    2193                 : }
    2194                 : 
    2195             1651: QualType PCHReader::GetType(pch::TypeID ID) {
    2196             1651:   unsigned FastQuals = ID & Qualifiers::FastMask;
    2197             1651:   unsigned Index = ID >> Qualifiers::FastWidth;
    2198                 : 
                      931: branch 0 taken
                      720: branch 1 taken
    2199             1651:   if (Index < pch::NUM_PREDEF_TYPE_IDS) {
    2200              931:     QualType T;
                      166: branch 0 taken
                       33: branch 1 taken
                        8: branch 2 taken
                       43: branch 3 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                       30: branch 6 taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        9: branch 9 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                      458: branch 13 taken
                        2: branch 14 taken
                        0: branch 15 not taken
                        9: branch 16 taken
                       75: branch 17 taken
                       55: branch 18 taken
                        0: branch 19 not taken
                        0: branch 20 not taken
                        0: branch 21 not taken
                        2: branch 22 taken
                        0: branch 23 not taken
                        0: branch 24 not taken
                       17: branch 25 taken
                       12: branch 26 taken
                       12: branch 27 taken
                        0: branch 28 not taken
    2201              931:     switch ((pch::PredefinedTypeIDs)Index) {
    2202              166:     case pch::PREDEF_TYPE_NULL_ID: return QualType();
    2203               33:     case pch::PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
    2204                8:     case pch::PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
    2205                 : 
    2206                 :     case pch::PREDEF_TYPE_CHAR_U_ID:
    2207                 :     case pch::PREDEF_TYPE_CHAR_S_ID:
    2208                 :       // FIXME: Check that the signedness of CharTy is correct!
    2209               43:       T = Context->CharTy;
    2210               43:       break;
    2211                 : 
    2212                0:     case pch::PREDEF_TYPE_UCHAR_ID:      T = Context->UnsignedCharTy;     break;
    2213                0:     case pch::PREDEF_TYPE_USHORT_ID:     T = Context->UnsignedShortTy;    break;
    2214               30:     case pch::PREDEF_TYPE_UINT_ID:       T = Context->UnsignedIntTy;      break;
    2215                0:     case pch::PREDEF_TYPE_ULONG_ID:      T = Context->UnsignedLongTy;     break;
    2216                0:     case pch::PREDEF_TYPE_ULONGLONG_ID:  T = Context->UnsignedLongLongTy; break;
    2217                9:     case pch::PREDEF_TYPE_UINT128_ID:    T = Context->UnsignedInt128Ty;   break;
    2218                0:     case pch::PREDEF_TYPE_SCHAR_ID:      T = Context->SignedCharTy;       break;
    2219                0:     case pch::PREDEF_TYPE_WCHAR_ID:      T = Context->WCharTy;            break;
    2220                0:     case pch::PREDEF_TYPE_SHORT_ID:      T = Context->ShortTy;            break;
    2221              458:     case pch::PREDEF_TYPE_INT_ID:        T = Context->IntTy;              break;
    2222                2:     case pch::PREDEF_TYPE_LONG_ID:       T = Context->LongTy;             break;
    2223                0:     case pch::PREDEF_TYPE_LONGLONG_ID:   T = Context->LongLongTy;         break;
    2224                9:     case pch::PREDEF_TYPE_INT128_ID:     T = Context->Int128Ty;           break;
    2225               75:     case pch::PREDEF_TYPE_FLOAT_ID:      T = Context->FloatTy;            break;
    2226               55:     case pch::PREDEF_TYPE_DOUBLE_ID:     T = Context->DoubleTy;           break;
    2227                0:     case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy;       break;
    2228                0:     case pch::PREDEF_TYPE_OVERLOAD_ID:   T = Context->OverloadTy;         break;
    2229                0:     case pch::PREDEF_TYPE_DEPENDENT_ID:  T = Context->DependentTy;        break;
    2230                2:     case pch::PREDEF_TYPE_NULLPTR_ID:    T = Context->NullPtrTy;          break;
    2231                0:     case pch::PREDEF_TYPE_CHAR16_ID:     T = Context->Char16Ty;           break;
    2232                0:     case pch::PREDEF_TYPE_CHAR32_ID:     T = Context->Char32Ty;           break;
    2233               17:     case pch::PREDEF_TYPE_OBJC_ID:       T = Context->ObjCBuiltinIdTy;    break;
    2234               12:     case pch::PREDEF_TYPE_OBJC_CLASS:    T = Context->ObjCBuiltinClassTy; break;
    2235               12:     case pch::PREDEF_TYPE_OBJC_SEL:      T = Context->ObjCBuiltinSelTy;   break;
    2236                 :     }
    2237                 : 
                      765: branch 1 taken
                        0: branch 2 not taken
    2238              765:     assert(!T.isNull() && "Unknown predefined type");
    2239              765:     return T.withFastQualifiers(FastQuals);
    2240                 :   }
    2241                 : 
    2242              720:   Index -= pch::NUM_PREDEF_TYPE_IDS;
    2243                 :   //assert(Index < TypesLoaded.size() && "Type index out-of-range");
                      379: branch 2 taken
                      341: branch 3 taken
    2244              720:   if (TypesLoaded[Index].isNull())
    2245              379:     TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]);
    2246                 : 
    2247              720:   return TypesLoaded[Index].withFastQualifiers(FastQuals);
    2248                 : }
    2249                 : 
    2250                 : TemplateArgumentLocInfo
    2251                 : PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
    2252                 :                                       const RecordData &Record,
    2253                0:                                       unsigned &Index) {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
    2254                0:   switch (Kind) {
    2255                 :   case TemplateArgument::Expression:
    2256                0:     return ReadDeclExpr();
    2257                 :   case TemplateArgument::Type:
    2258                0:     return GetTypeSourceInfo(Record, Index);
    2259                 :   case TemplateArgument::Template: {
    2260                 :     SourceLocation 
    2261                0:       QualStart = SourceLocation::getFromRawEncoding(Record[Index++]),
    2262                0:       QualEnd = SourceLocation::getFromRawEncoding(Record[Index++]),
    2263                0:       TemplateNameLoc = SourceLocation::getFromRawEncoding(Record[Index++]);
    2264                 :     return TemplateArgumentLocInfo(SourceRange(QualStart, QualEnd),
    2265                0:                                    TemplateNameLoc);
    2266                 :   }
    2267                 :   case TemplateArgument::Null:
    2268                 :   case TemplateArgument::Integral:
    2269                 :   case TemplateArgument::Declaration:
    2270                 :   case TemplateArgument::Pack:
    2271                0:     return TemplateArgumentLocInfo();
    2272                 :   }
    2273                0:   llvm_unreachable("unexpected template argument loc");
    2274                 :   return TemplateArgumentLocInfo();
    2275                 : }
    2276                 : 
    2277             2377: Decl *PCHReader::GetDecl(pch::DeclID ID) {
                      428: branch 0 taken
                     1949: branch 1 taken
    2278             2377:   if (ID == 0)
    2279              428:     return 0;
    2280                 : 
                        0: branch 1 not taken
                     1949: branch 2 taken
    2281             1949:   if (ID > DeclsLoaded.size()) {
    2282                0:     Error("declaration ID out-of-range for PCH file");
    2283                0:     return 0;
    2284                 :   }
    2285                 : 
    2286             1949:   unsigned Index = ID - 1;
                      471: branch 1 taken
                     1478: branch 2 taken
    2287             1949:   if (!DeclsLoaded[Index])
    2288              471:     ReadDeclRecord(DeclOffsets[Index], Index);
    2289                 : 
    2290             1949:   return DeclsLoaded[Index];
    2291                 : }
    2292                 : 
    2293                 : /// \brief Resolve the offset of a statement into a statement.
    2294                 : ///
    2295                 : /// This operation will read a new statement from the external
    2296                 : /// source each time it is called, and is meant to be used via a
    2297                 : /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
    2298               25: Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
    2299                 :   // Since we know tha this statement is part of a decl, make sure to use the
    2300                 :   // decl cursor to read it.
    2301               25:   DeclsCursor.JumpToBit(Offset);
    2302               25:   return ReadStmt(DeclsCursor);
    2303                 : }
    2304                 : 
    2305                 : bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
    2306               36:                                   llvm::SmallVectorImpl<pch::DeclID> &Decls) {
    2307                 :   assert(DC->hasExternalLexicalStorage() &&
                       36: branch 1 taken
                        0: branch 2 not taken
    2308               36:          "DeclContext has no lexical decls in storage");
    2309               36:   uint64_t Offset = DeclContextOffsets[DC].first;
                        0: branch 0 not taken
                       36: branch 1 taken
    2310               36:   assert(Offset && "DeclContext has no lexical decls in storage");
    2311                 : 
    2312                 :   // Keep track of where we are in the stream, then jump back there
    2313                 :   // after reading this context.
    2314               36:   SavedStreamPosition SavedPosition(DeclsCursor);
    2315                 : 
    2316                 :   // Load the record containing all of the declarations lexically in
    2317                 :   // this context.
    2318               36:   DeclsCursor.JumpToBit(Offset);
    2319               36:   RecordData Record;
    2320               36:   unsigned Code = DeclsCursor.ReadCode();
    2321               36:   unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
    2322                 :   (void)RecCode;
                        0: branch 0 not taken
                       36: branch 1 taken
    2323               36:   assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block");
    2324                 : 
    2325                 :   // Load all of the declaration IDs
    2326               36:   Decls.clear();
    2327               36:   Decls.insert(Decls.end(), Record.begin(), Record.end());
    2328               36:   ++NumLexicalDeclContextsRead;
    2329               36:   return false;
    2330                 : }
    2331                 : 
    2332                 : bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
    2333                6:                            llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
    2334                 :   assert(DC->hasExternalVisibleStorage() &&
                        6: branch 1 taken
                        0: branch 2 not taken
    2335                6:          "DeclContext has no visible decls in storage");
    2336                6:   uint64_t Offset = DeclContextOffsets[DC].second;
                        0: branch 0 not taken
                        6: branch 1 taken
    2337                6:   assert(Offset && "DeclContext has no visible decls in storage");
    2338                 : 
    2339                 :   // Keep track of where we are in the stream, then jump back there
    2340                 :   // after reading this context.
    2341                6:   SavedStreamPosition SavedPosition(DeclsCursor);
    2342                 : 
    2343                 :   // Load the record containing all of the declarations visible in
    2344                 :   // this context.
    2345                6:   DeclsCursor.JumpToBit(Offset);
    2346                6:   RecordData Record;
    2347                6:   unsigned Code = DeclsCursor.ReadCode();
    2348                6:   unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
    2349                 :   (void)RecCode;
                        0: branch 0 not taken
                        6: branch 1 taken
    2350                6:   assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block");
                        0: branch 1 not taken
                        6: branch 2 taken
    2351                6:   if (Record.size() == 0)
    2352                0:     return false;
    2353                 : 
    2354                6:   Decls.clear();
    2355                 : 
    2356                6:   unsigned Idx = 0;
                       19: branch 1 taken
                        6: branch 2 taken
    2357               31:   while (Idx < Record.size()) {
    2358               19:     Decls.push_back(VisibleDeclaration());
    2359               19:     Decls.back().Name = ReadDeclarationName(Record, Idx);
    2360                 : 
    2361               19:     unsigned Size = Record[Idx++];
    2362               19:     llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
    2363               19:     LoadedDecls.reserve(Size);
                       21: branch 0 taken
                       19: branch 1 taken
    2364               40:     for (unsigned I = 0; I < Size; ++I)
    2365               21:       LoadedDecls.push_back(Record[Idx++]);
    2366                 :   }
    2367                 : 
    2368                6:   ++NumVisibleDeclContextsRead;
    2369                6:   return false;
    2370                 : }
    2371                 : 
    2372               35: void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
    2373               35:   this->Consumer = Consumer;
    2374                 : 
                        0: branch 0 not taken
                       35: branch 1 taken
    2375               35:   if (!Consumer)
    2376                0:     return;
    2377                 : 
                       36: branch 1 taken
                       35: branch 2 taken
    2378               71:   for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
    2379                 :     // Force deserialization of this decl, which will cause it to be passed to
    2380                 :     // the consumer (or queued).
    2381               36:     GetDecl(ExternalDefinitions[I]);
    2382                 :   }
    2383                 : 
                        4: branch 1 taken
                       35: branch 2 taken
    2384               39:   for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
    2385                4:     DeclGroupRef DG(InterestingDecls[I]);
    2386                4:     Consumer->HandleTopLevelDecl(DG);
    2387                 :   }
    2388                 : }
    2389                 : 
    2390                0: void PCHReader::PrintStats() {
    2391                0:   std::fprintf(stderr, "*** PCH Statistics:\n");
    2392                 : 
    2393                 :   unsigned NumTypesLoaded
    2394                 :     = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
    2395                0:                                       QualType());
    2396                 :   unsigned NumDeclsLoaded
    2397                 :     = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
    2398                0:                                       (Decl *)0);
    2399                 :   unsigned NumIdentifiersLoaded
    2400                 :     = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
    2401                 :                                             IdentifiersLoaded.end(),
    2402                0:                                             (IdentifierInfo *)0);
    2403                 :   unsigned NumSelectorsLoaded
    2404                 :     = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
    2405                 :                                           SelectorsLoaded.end(),
    2406                0:                                           Selector());
    2407                 : 
    2408                0:   std::fprintf(stderr, "  %u stat cache hits\n", NumStatHits);
    2409                0:   std::fprintf(stderr, "  %u stat cache misses\n", NumStatMisses);
                        0: branch 0 not taken
                        0: branch 1 not taken
    2410                0:   if (TotalNumSLocEntries)
    2411                 :     std::fprintf(stderr, "  %u/%u source location entries read (%f%%)\n",
    2412                 :                  NumSLocEntriesRead, TotalNumSLocEntries,
    2413                0:                  ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
                        0: branch 1 not taken
                        0: branch 2 not taken
    2414                0:   if (!TypesLoaded.empty())
    2415                 :     std::fprintf(stderr, "  %u/%u types read (%f%%)\n",
    2416                 :                  NumTypesLoaded, (unsigned)TypesLoaded.size(),
    2417                0:                  ((float)NumTypesLoaded/TypesLoaded.size() * 100));
                        0: branch 1 not taken
                        0: branch 2 not taken
    2418                0:   if (!DeclsLoaded.empty())
    2419                 :     std::fprintf(stderr, "  %u/%u declarations read (%f%%)\n",
    2420                 :                  NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
    2421                0:                  ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
                        0: branch 1 not taken
                        0: branch 2 not taken
    2422                0:   if (!IdentifiersLoaded.empty())
    2423                 :     std::fprintf(stderr, "  %u/%u identifiers read (%f%%)\n",
    2424                 :                  NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
    2425                0:                  ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
                        0: branch 0 not taken
                        0: branch 1 not taken
    2426                0:   if (TotalNumSelectors)
    2427                 :     std::fprintf(stderr, "  %u/%u selectors read (%f%%)\n",
    2428                 :                  NumSelectorsLoaded, TotalNumSelectors,
    2429                0:                  ((float)NumSelectorsLoaded/TotalNumSelectors * 100));
                        0: branch 0 not taken
                        0: branch 1 not taken
    2430                0:   if (TotalNumStatements)
    2431                 :     std::fprintf(stderr, "  %u/%u statements read (%f%%)\n",
    2432                 :                  NumStatementsRead, TotalNumStatements,
    2433                0:                  ((float)NumStatementsRead/TotalNumStatements * 100));
                        0: branch 0 not taken
                        0: branch 1 not taken
    2434                0:   if (TotalNumMacros)
    2435                 :     std::fprintf(stderr, "  %u/%u macros read (%f%%)\n",
    2436                 :                  NumMacrosRead, TotalNumMacros,
    2437                0:                  ((float)NumMacrosRead/TotalNumMacros * 100));
                        0: branch 0 not taken
                        0: branch 1 not taken
    2438                0:   if (TotalLexicalDeclContexts)
    2439                 :     std::fprintf(stderr, "  %u/%u lexical declcontexts read (%f%%)\n",
    2440                 :                  NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
    2441                 :                  ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
    2442                0:                   * 100));
                        0: branch 0 not taken
                        0: branch 1 not taken
    2443                0:   if (TotalVisibleDeclContexts)
    2444                 :     std::fprintf(stderr, "  %u/%u visible declcontexts read (%f%%)\n",
    2445                 :                  NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
    2446                 :                  ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
    2447                0:                   * 100));
                        0: branch 0 not taken
                        0: branch 1 not taken
    2448                0:   if (TotalSelectorsInMethodPool) {
    2449                 :     std::fprintf(stderr, "  %u/%u method pool entries read (%f%%)\n",
    2450                 :                  NumMethodPoolSelectorsRead, TotalSelectorsInMethodPool,
    2451                 :                  ((float)NumMethodPoolSelectorsRead/TotalSelectorsInMethodPool
    2452                0:                   * 100));
    2453                0:     std::fprintf(stderr, "  %u method pool misses\n", NumMethodPoolMisses);
    2454                 :   }
    2455                0:   std::fprintf(stderr, "\n");
    2456                0: }
    2457                 : 
    2458               35: void PCHReader::InitializeSema(Sema &S) {
    2459               35:   SemaObj = &S;
    2460               35:   S.ExternalSource = this;
    2461                 : 
    2462                 :   // Makes sure any declarations that were deserialized "too early"
    2463                 :   // still get added to the identifier's declaration chains.
                       35: branch 1 taken
                       35: branch 2 taken
    2464               70:   for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
    2465               35:     SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I]));
    2466               35:     SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
    2467                 :   }
    2468               35:   PreloadedDecls.clear();
    2469                 : 
    2470                 :   // If there were any tentative definitions, deserialize them and add
    2471                 :   // them to Sema's list of tentative definitions.
                       27: branch 1 taken
                       35: branch 2 taken
    2472               62:   for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
    2473               27:     VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
    2474               27:     SemaObj->TentativeDefinitions.push_back(Var);
    2475                 :   }
    2476                 : 
    2477                 :   // If there were any locally-scoped external declarations,
    2478                 :   // deserialize them and add them to Sema's table of locally-scoped
    2479                 :   // external declarations.
                        4: branch 1 taken
                       35: branch 2 taken
    2480               39:   for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
    2481                4:     NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
    2482                4:     SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
    2483                 :   }
    2484                 : 
    2485                 :   // If there were any ext_vector type declarations, deserialize them
    2486                 :   // and add them to Sema's vector of such declarations.
                        4: branch 1 taken
                       35: branch 2 taken
    2487               39:   for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
    2488                 :     SemaObj->ExtVectorDecls.push_back(
    2489                4:                                cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
    2490               35: }
    2491                 : 
    2492             1770: IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
    2493                 :   // Try to find this name within our on-disk hash table
    2494                 :   PCHIdentifierLookupTable *IdTable
    2495             1770:     = (PCHIdentifierLookupTable *)IdentifierLookupTable;
    2496             1770:   std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
    2497             1770:   PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
                      197: branch 2 taken
                     1573: branch 3 taken
    2498             1770:   if (Pos == IdTable->end())
    2499              197:     return 0;
    2500                 : 
    2501                 :   // Dereferencing the iterator has the effect of building the
    2502                 :   // IdentifierInfo node and populating it with the various
    2503                 :   // declarations it needs.
    2504             1573:   return *Pos;
    2505                 : }
    2506                 : 
    2507                 : std::pair<ObjCMethodList, ObjCMethodList>
    2508                1: PCHReader::ReadMethodPool(Selector Sel) {
                        0: branch 0 not taken
                        1: branch 1 taken
    2509                1:   if (!MethodPoolLookupTable)
    2510                0:     return std::pair<ObjCMethodList, ObjCMethodList>();
    2511                 : 
    2512                 :   // Try to find this selector within our on-disk hash table.
    2513                 :   PCHMethodPoolLookupTable *PoolTable
    2514                1:     = (PCHMethodPoolLookupTable*)MethodPoolLookupTable;
    2515                1:   PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel);
                        0: branch 2 not taken
                        1: branch 3 taken
    2516                1:   if (Pos == PoolTable->end()) {
    2517                0:     ++NumMethodPoolMisses;
    2518                0:     return std::pair<ObjCMethodList, ObjCMethodList>();;
    2519                 :   }
    2520                 : 
    2521                1:   ++NumMethodPoolSelectorsRead;
    2522                1:   return *Pos;
    2523                 : }
    2524                 : 
    2525             5416: void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
                        0: branch 0 not taken
                     5416: branch 1 taken
    2526             5416:   assert(ID && "Non-zero identifier ID required");
                     5416: branch 1 taken
                        0: branch 2 not taken
    2527             5416:   assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
    2528             5416:   IdentifiersLoaded[ID - 1] = II;
    2529             5416: }
    2530                 : 
    2531                 : /// \brief Set the globally-visible declarations associated with the given
    2532                 : /// identifier.
    2533                 : ///
    2534                 : /// If the PCH reader is currently in a state where the given declaration IDs
    2535                 : /// cannot safely be resolved, they are queued until it is safe to resolve
    2536                 : /// them.
    2537                 : ///
    2538                 : /// \param II an IdentifierInfo that refers to one or more globally-visible
    2539                 : /// declarations.
    2540                 : ///
    2541                 : /// \param DeclIDs the set of declaration IDs with the name @p II that are
    2542                 : /// visible at global scope.
    2543                 : ///
    2544                 : /// \param Nonrecursive should be true to indicate that the caller knows that
    2545                 : /// this call is non-recursive, and therefore the globally-visible declarations
    2546                 : /// will not be placed onto the pending queue.
    2547                 : void
    2548                 : PCHReader::SetGloballyVisibleDecls(IdentifierInfo *II,
    2549                 :                               const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
    2550              505:                                    bool Nonrecursive) {
                      436: branch 0 taken
                       69: branch 1 taken
                      218: branch 2 taken
                      218: branch 3 taken
    2551              505:   if (CurrentlyLoadingTypeOrDecl && !Nonrecursive) {
    2552              218:     PendingIdentifierInfos.push_back(PendingIdentifierInfo());
    2553              218:     PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
    2554              218:     PII.II = II;
                      228: branch 1 taken
                      218: branch 2 taken
    2555              446:     for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
    2556              228:       PII.DeclIDs.push_back(DeclIDs[I]);
    2557              218:     return;
    2558                 :   }
    2559                 : 
                      299: branch 1 taken
                      287: branch 2 taken
    2560              586:   for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
    2561              299:     NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
                      168: branch 0 taken
                      131: branch 1 taken
    2562              299:     if (SemaObj) {
    2563                 :       // Introduce this declaration into the translation-unit scope
    2564                 :       // and add it to the declaration chain for this identifier, so
    2565                 :       // that (unqualified) name lookup will find it.
    2566              168:       SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D));
    2567              168:       SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
    2568                 :     } else {
    2569                 :       // Queue this declaration so that it will be added to the
    2570                 :       // translation unit scope and identifier's declaration chain
    2571                 :       // once a Sema object is known.
    2572              131:       PreloadedDecls.push_back(D);
    2573                 :     }
    2574                 :   }
    2575                 : }
    2576                 : 
    2577             1547: IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
                      357: branch 0 taken
                     1190: branch 1 taken
    2578             1547:   if (ID == 0)
    2579              357:     return 0;
    2580                 : 
                     1190: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                     1190: branch 4 taken
                        0: branch 5 not taken
                     1190: branch 6 taken
    2581             1190:   if (!IdentifierTableData || IdentifiersLoaded.empty()) {
    2582                0:     Error("no identifier table in PCH file");
    2583                0:     return 0;
    2584                 :   }
    2585                 : 
                        0: branch 0 not taken
                     1190: branch 1 taken
    2586             1190:   assert(PP && "Forgot to set Preprocessor ?");
                      652: branch 1 taken
                      538: branch 2 taken
    2587             1190:   if (!IdentifiersLoaded[ID - 1]) {
    2588              652:     uint32_t Offset = IdentifierOffsets[ID - 1];
    2589              652:     const char *Str = IdentifierTableData + Offset;
    2590                 : 
    2591                 :     // All of the strings in the PCH file are preceded by a 16-bit
    2592                 :     // length. Extract that 16-bit length to avoid having to execute
    2593                 :     // strlen().
    2594                 :     // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
    2595                 :     //  unsigned integers.  This is important to avoid integer overflow when
    2596                 :     //  we cast them to 'unsigned'.
    2597              652:     const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
    2598                 :     unsigned StrLen = (((unsigned) StrLenPtr[0])
    2599              652:                        | (((unsigned) StrLenPtr[1]) << 8)) - 1;
    2600                 :     IdentifiersLoaded[ID - 1]
    2601              652:       = &PP->getIdentifierTable().get(Str, Str + StrLen);
    2602                 :   }
    2603                 : 
    2604             1190:   return IdentifiersLoaded[ID - 1];
    2605                 : }
    2606                 : 
    2607               39: void PCHReader::ReadSLocEntry(unsigned ID) {
    2608               39:   ReadSLocEntryRecord(ID);
    2609               39: }
    2610                 : 
    2611               51: Selector PCHReader::DecodeSelector(unsigned ID) {
                        0: branch 0 not taken
                       51: branch 1 taken
    2612               51:   if (ID == 0)
    2613                0:     return Selector();
    2614                 : 
                        3: branch 0 taken
                       48: branch 1 taken
    2615               51:   if (!MethodPoolLookupTableData)
    2616                3:     return Selector();
    2617                 : 
                        0: branch 0 not taken
                       48: branch 1 taken
    2618               48:   if (ID > TotalNumSelectors) {
    2619                0:     Error("selector ID out of range in PCH file");
    2620                0:     return Selector();
    2621                 :   }
    2622                 : 
    2623               48:   unsigned Index = ID - 1;
                       24: branch 2 taken
                       24: branch 3 taken
    2624               48:   if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) {
    2625                 :     // Load this selector from the selector table.
    2626                 :     // FIXME: endianness portability issues with SelectorOffsets table
    2627               24:     PCHMethodPoolLookupTrait Trait(*this);
    2628                 :     SelectorsLoaded[Index]
    2629               24:       = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0);
    2630                 :   }
    2631                 : 
    2632               48:   return SelectorsLoaded[Index];
    2633                 : }
    2634                 : 
    2635                 : DeclarationName
    2636              487: PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
    2637              487:   DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
                      449: branch 0 taken
                       38: branch 1 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
    2638              487:   switch (Kind) {
    2639                 :   case DeclarationName::Identifier:
    2640              449:     return DeclarationName(GetIdentifierInfo(Record, Idx));
    2641                 : 
    2642                 :   case DeclarationName::ObjCZeroArgSelector:
    2643                 :   case DeclarationName::ObjCOneArgSelector:
    2644                 :   case DeclarationName::ObjCMultiArgSelector:
    2645               38:     return DeclarationName(GetSelector(Record, Idx));
    2646                 : 
    2647                 :   case DeclarationName::CXXConstructorName:
    2648                 :     return Context->DeclarationNames.getCXXConstructorName(
    2649                0:                           Context->getCanonicalType(GetType(Record[Idx++])));
    2650                 : 
    2651                 :   case DeclarationName::CXXDestructorName:
    2652                 :     return Context->DeclarationNames.getCXXDestructorName(
    2653                0:                           Context->getCanonicalType(GetType(Record[Idx++])));
    2654                 : 
    2655                 :   case DeclarationName::CXXConversionFunctionName:
    2656                 :     return Context->DeclarationNames.getCXXConversionFunctionName(
    2657                0:                           Context->getCanonicalType(GetType(Record[Idx++])));
    2658                 : 
    2659                 :   case DeclarationName::CXXOperatorName:
    2660                 :     return Context->DeclarationNames.getCXXOperatorName(
    2661                0:                                        (OverloadedOperatorKind)Record[Idx++]);
    2662                 : 
    2663                 :   case DeclarationName::CXXLiteralOperatorName:
    2664                 :     return Context->DeclarationNames.getCXXLiteralOperatorName(
    2665                0:                                        GetIdentifierInfo(Record, Idx));
    2666                 : 
    2667                 :   case DeclarationName::CXXUsingDirective:
    2668                0:     return DeclarationName::getUsingDirectiveName();
    2669                 :   }
    2670                 : 
    2671                 :   // Required to silence GCC warning
    2672                0:   return DeclarationName();
    2673                 : }
    2674                 : 
    2675                 : /// \brief Read an integral value
    2676              116: llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
    2677              116:   unsigned BitWidth = Record[Idx++];
    2678              116:   unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
    2679              116:   llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
    2680              116:   Idx += NumWords;
    2681                 :   return Result;
    2682                 : }
    2683                 : 
    2684                 : /// \brief Read a signed integral value
    2685                6: llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
    2686                6:   bool isUnsigned = Record[Idx++];
    2687                6:   return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
    2688                 : }
    2689                 : 
    2690                 : /// \brief Read a floating-point value
    2691               12: llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
    2692               12:   return llvm::APFloat(ReadAPInt(Record, Idx));
    2693                 : }
    2694                 : 
    2695                 : // \brief Read a string
    2696                4: std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
    2697                4:   unsigned Len = Record[Idx++];
    2698                4:   std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
    2699                4:   Idx += Len;
    2700                 :   return Result;
    2701                 : }
    2702                 : 
    2703                3: DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
    2704                3:   return Diag(SourceLocation(), DiagID);
    2705                 : }
    2706                 : 
    2707                4: DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
    2708                4:   return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
    2709                 : }
    2710                 : 
    2711                 : /// \brief Retrieve the identifier table associated with the
    2712                 : /// preprocessor.
    2713             1573: IdentifierTable &PCHReader::getIdentifierTable() {
                        0: branch 0 not taken
                     1573: branch 1 taken
    2714             1573:   assert(PP && "Forgot to set Preprocessor ?");
    2715             1573:   return PP->getIdentifierTable();
    2716                 : }
    2717                 : 
    2718                 : /// \brief Record that the given ID maps to the given switch-case
    2719                 : /// statement.
    2720                8: void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
                        8: branch 1 taken
                        0: branch 2 not taken
    2721                8:   assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
    2722                8:   SwitchCaseStmts[ID] = SC;
    2723                8: }
    2724                 : 
    2725                 : /// \brief Retrieve the switch-case statement with the given ID.
    2726                8: SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
                        8: branch 1 taken
                        0: branch 2 not taken
    2727                8:   assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
    2728                8:   return SwitchCaseStmts[ID];
    2729                 : }
    2730                 : 
    2731                 : /// \brief Record that the given label statement has been
    2732                 : /// deserialized and has the given ID.
    2733                4: void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
    2734                 :   assert(LabelStmts.find(ID) == LabelStmts.end() &&
                        4: branch 3 taken
                        0: branch 4 not taken
    2735                4:          "Deserialized label twice");
    2736                4:   LabelStmts[ID] = S;
    2737                 : 
    2738                 :   // If we've already seen any goto statements that point to this
    2739                 :   // label, resolve them now.
    2740                 :   typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
    2741                4:   std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
                        2: branch 2 taken
                        4: branch 3 taken
    2742                6:   for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
    2743                2:     Goto->second->setLabel(S);
    2744                4:   UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
    2745                 : 
    2746                 :   // If we've already seen any address-label statements that point to
    2747                 :   // this label, resolve them now.
    2748                 :   typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
    2749                 :   std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
    2750                4:     = UnresolvedAddrLabelExprs.equal_range(ID);
                        1: branch 2 taken
                        4: branch 3 taken
    2751                5:   for (AddrLabelIter AddrLabel = AddrLabels.first;
    2752                 :        AddrLabel != AddrLabels.second; ++AddrLabel)
    2753                1:     AddrLabel->second->setLabel(S);
    2754                4:   UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
    2755                4: }
    2756                 : 
    2757                 : /// \brief Set the label of the given statement to the label
    2758                 : /// identified by ID.
    2759                 : ///
    2760                 : /// Depending on the order in which the label and other statements
    2761                 : /// referencing that label occur, this operation may complete
    2762                 : /// immediately (updating the statement) or it may queue the
    2763                 : /// statement to be back-patched later.
    2764                2: void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) {
    2765                2:   std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
                        0: branch 2 not taken
                        2: branch 3 taken
    2766                2:   if (Label != LabelStmts.end()) {
    2767                 :     // We've already seen this label, so set the label of the goto and
    2768                 :     // we're done.
    2769                0:     S->setLabel(Label->second);
    2770                 :   } else {
    2771                 :     // We haven't seen this label yet, so add this goto to the set of
    2772                 :     // unresolved goto statements.
    2773                2:     UnresolvedGotoStmts.insert(std::make_pair(ID, S));
    2774                 :   }
    2775                2: }
    2776                 : 
    2777                 : /// \brief Set the label of the given expression to the label
    2778                 : /// identified by ID.
    2779                 : ///
    2780                 : /// Depending on the order in which the label and other statements
    2781                 : /// referencing that label occur, this operation may complete
    2782                 : /// immediately (updating the statement) or it may queue the
    2783                 : /// statement to be back-patched later.
    2784                2: void PCHReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
    2785                2:   std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
                        1: branch 2 taken
                        1: branch 3 taken
    2786                2:   if (Label != LabelStmts.end()) {
    2787                 :     // We've already seen this label, so set the label of the
    2788                 :     // label-address expression and we're done.
    2789                1:     S->setLabel(Label->second);
    2790                 :   } else {
    2791                 :     // We haven't seen this label yet, so add this label-address
    2792                 :     // expression to the set of unresolved label-address expressions.
    2793                1:     UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
    2794                 :   }
    2795                2: }
    2796                 : 
    2797                 : 
    2798              896: PCHReader::LoadingTypeOrDecl::LoadingTypeOrDecl(PCHReader &Reader)
    2799              896:   : Reader(Reader), Parent(Reader.CurrentlyLoadingTypeOrDecl) {
    2800              896:   Reader.CurrentlyLoadingTypeOrDecl = this;
    2801              896: }
    2802                 : 
    2803              896: PCHReader::LoadingTypeOrDecl::~LoadingTypeOrDecl() {
                      375: branch 0 taken
                      521: branch 1 taken
                      521: branch 2 taken
                      521: branch 3 taken
    2804              896:   if (!Parent) {
    2805                 :     // If any identifiers with corresponding top-level declarations have
    2806                 :     // been loaded, load those declarations now.
                      218: branch 1 taken
                      375: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
    2807              968:     while (!Reader.PendingIdentifierInfos.empty()) {
    2808                 :       Reader.SetGloballyVisibleDecls(Reader.PendingIdentifierInfos.front().II,
    2809                 :                                  Reader.PendingIdentifierInfos.front().DeclIDs,
    2810              218:                                      true);
    2811              218:       Reader.PendingIdentifierInfos.pop_front();
    2812                 :     }
    2813                 :   }
    2814                 : 
    2815              896:   Reader.CurrentlyLoadingTypeOrDecl = Parent;
    2816              896: }

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