Home | History | Annotate | Download | only in libclang
      1 //===- CIndexHigh.cpp - Higher level API functions ------------------------===//
      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 #include "CIndexDiagnostic.h"
     11 #include "CIndexer.h"
     12 #include "CLog.h"
     13 #include "CXCursor.h"
     14 #include "CXIndexDataConsumer.h"
     15 #include "CXSourceLocation.h"
     16 #include "CXString.h"
     17 #include "CXTranslationUnit.h"
     18 #include "clang/AST/ASTConsumer.h"
     19 #include "clang/Frontend/ASTUnit.h"
     20 #include "clang/Frontend/CompilerInstance.h"
     21 #include "clang/Frontend/CompilerInvocation.h"
     22 #include "clang/Frontend/FrontendAction.h"
     23 #include "clang/Frontend/Utils.h"
     24 #include "clang/Index/IndexingAction.h"
     25 #include "clang/Lex/HeaderSearch.h"
     26 #include "clang/Lex/PPCallbacks.h"
     27 #include "clang/Lex/PPConditionalDirectiveRecord.h"
     28 #include "clang/Lex/Preprocessor.h"
     29 #include "clang/Sema/SemaConsumer.h"
     30 #include "llvm/Support/CrashRecoveryContext.h"
     31 #include "llvm/Support/MemoryBuffer.h"
     32 #include "llvm/Support/Mutex.h"
     33 #include "llvm/Support/MutexGuard.h"
     34 #include <cstdio>
     35 #include <utility>
     36 
     37 using namespace clang;
     38 using namespace clang::index;
     39 using namespace cxtu;
     40 using namespace cxindex;
     41 
     42 namespace {
     43 
     44 //===----------------------------------------------------------------------===//
     45 // Skip Parsed Bodies
     46 //===----------------------------------------------------------------------===//
     47 
     48 /// \brief A "region" in source code identified by the file/offset of the
     49 /// preprocessor conditional directive that it belongs to.
     50 /// Multiple, non-consecutive ranges can be parts of the same region.
     51 ///
     52 /// As an example of different regions separated by preprocessor directives:
     53 ///
     54 /// \code
     55 ///   #1
     56 /// #ifdef BLAH
     57 ///   #2
     58 /// #ifdef CAKE
     59 ///   #3
     60 /// #endif
     61 ///   #2
     62 /// #endif
     63 ///   #1
     64 /// \endcode
     65 ///
     66 /// There are 3 regions, with non-consecutive parts:
     67 ///   #1 is identified as the beginning of the file
     68 ///   #2 is identified as the location of "#ifdef BLAH"
     69 ///   #3 is identified as the location of "#ifdef CAKE"
     70 ///
     71 class PPRegion {
     72   llvm::sys::fs::UniqueID UniqueID;
     73   time_t ModTime;
     74   unsigned Offset;
     75 public:
     76   PPRegion() : UniqueID(0, 0), ModTime(), Offset() {}
     77   PPRegion(llvm::sys::fs::UniqueID UniqueID, unsigned offset, time_t modTime)
     78       : UniqueID(UniqueID), ModTime(modTime), Offset(offset) {}
     79 
     80   const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
     81   unsigned getOffset() const { return Offset; }
     82   time_t getModTime() const { return ModTime; }
     83 
     84   bool isInvalid() const { return *this == PPRegion(); }
     85 
     86   friend bool operator==(const PPRegion &lhs, const PPRegion &rhs) {
     87     return lhs.UniqueID == rhs.UniqueID && lhs.Offset == rhs.Offset &&
     88            lhs.ModTime == rhs.ModTime;
     89   }
     90 };
     91 
     92 typedef llvm::DenseSet<PPRegion> PPRegionSetTy;
     93 
     94 } // end anonymous namespace
     95 
     96 namespace llvm {
     97   template <> struct isPodLike<PPRegion> {
     98     static const bool value = true;
     99   };
    100 
    101   template <>
    102   struct DenseMapInfo<PPRegion> {
    103     static inline PPRegion getEmptyKey() {
    104       return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-1), 0);
    105     }
    106     static inline PPRegion getTombstoneKey() {
    107       return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-2), 0);
    108     }
    109 
    110     static unsigned getHashValue(const PPRegion &S) {
    111       llvm::FoldingSetNodeID ID;
    112       const llvm::sys::fs::UniqueID &UniqueID = S.getUniqueID();
    113       ID.AddInteger(UniqueID.getFile());
    114       ID.AddInteger(UniqueID.getDevice());
    115       ID.AddInteger(S.getOffset());
    116       ID.AddInteger(S.getModTime());
    117       return ID.ComputeHash();
    118     }
    119 
    120     static bool isEqual(const PPRegion &LHS, const PPRegion &RHS) {
    121       return LHS == RHS;
    122     }
    123   };
    124 }
    125 
    126 namespace {
    127 
    128 class SessionSkipBodyData {
    129   llvm::sys::Mutex Mux;
    130   PPRegionSetTy ParsedRegions;
    131 
    132 public:
    133   SessionSkipBodyData() : Mux(/*recursive=*/false) {}
    134   ~SessionSkipBodyData() {
    135     //llvm::errs() << "RegionData: " << Skipped.size() << " - " << Skipped.getMemorySize() << "\n";
    136   }
    137 
    138   void copyTo(PPRegionSetTy &Set) {
    139     llvm::MutexGuard MG(Mux);
    140     Set = ParsedRegions;
    141   }
    142 
    143   void update(ArrayRef<PPRegion> Regions) {
    144     llvm::MutexGuard MG(Mux);
    145     ParsedRegions.insert(Regions.begin(), Regions.end());
    146   }
    147 };
    148 
    149 class TUSkipBodyControl {
    150   SessionSkipBodyData &SessionData;
    151   PPConditionalDirectiveRecord &PPRec;
    152   Preprocessor &PP;
    153 
    154   PPRegionSetTy ParsedRegions;
    155   SmallVector<PPRegion, 32> NewParsedRegions;
    156   PPRegion LastRegion;
    157   bool LastIsParsed;
    158 
    159 public:
    160   TUSkipBodyControl(SessionSkipBodyData &sessionData,
    161                     PPConditionalDirectiveRecord &ppRec,
    162                     Preprocessor &pp)
    163     : SessionData(sessionData), PPRec(ppRec), PP(pp) {
    164     SessionData.copyTo(ParsedRegions);
    165   }
    166 
    167   bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
    168     PPRegion region = getRegion(Loc, FID, FE);
    169     if (region.isInvalid())
    170       return false;
    171 
    172     // Check common case, consecutive functions in the same region.
    173     if (LastRegion == region)
    174       return LastIsParsed;
    175 
    176     LastRegion = region;
    177     LastIsParsed = ParsedRegions.count(region);
    178     if (!LastIsParsed)
    179       NewParsedRegions.push_back(region);
    180     return LastIsParsed;
    181   }
    182 
    183   void finished() {
    184     SessionData.update(NewParsedRegions);
    185   }
    186 
    187 private:
    188   PPRegion getRegion(SourceLocation Loc, FileID FID, const FileEntry *FE) {
    189     SourceLocation RegionLoc = PPRec.findConditionalDirectiveRegionLoc(Loc);
    190     if (RegionLoc.isInvalid()) {
    191       if (isParsedOnceInclude(FE)) {
    192         const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
    193         return PPRegion(ID, 0, FE->getModificationTime());
    194       }
    195       return PPRegion();
    196     }
    197 
    198     const SourceManager &SM = PPRec.getSourceManager();
    199     assert(RegionLoc.isFileID());
    200     FileID RegionFID;
    201     unsigned RegionOffset;
    202     std::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
    203 
    204     if (RegionFID != FID) {
    205       if (isParsedOnceInclude(FE)) {
    206         const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
    207         return PPRegion(ID, 0, FE->getModificationTime());
    208       }
    209       return PPRegion();
    210     }
    211 
    212     const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
    213     return PPRegion(ID, RegionOffset, FE->getModificationTime());
    214   }
    215 
    216   bool isParsedOnceInclude(const FileEntry *FE) {
    217     return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE);
    218   }
    219 };
    220 
    221 //===----------------------------------------------------------------------===//
    222 // IndexPPCallbacks
    223 //===----------------------------------------------------------------------===//
    224 
    225 class IndexPPCallbacks : public PPCallbacks {
    226   Preprocessor &PP;
    227   CXIndexDataConsumer &DataConsumer;
    228   bool IsMainFileEntered;
    229 
    230 public:
    231   IndexPPCallbacks(Preprocessor &PP, CXIndexDataConsumer &dataConsumer)
    232     : PP(PP), DataConsumer(dataConsumer), IsMainFileEntered(false) { }
    233 
    234   void FileChanged(SourceLocation Loc, FileChangeReason Reason,
    235                  SrcMgr::CharacteristicKind FileType, FileID PrevFID) override {
    236     if (IsMainFileEntered)
    237       return;
    238 
    239     SourceManager &SM = PP.getSourceManager();
    240     SourceLocation MainFileLoc = SM.getLocForStartOfFile(SM.getMainFileID());
    241 
    242     if (Loc == MainFileLoc && Reason == PPCallbacks::EnterFile) {
    243       IsMainFileEntered = true;
    244       DataConsumer.enteredMainFile(SM.getFileEntryForID(SM.getMainFileID()));
    245     }
    246   }
    247 
    248   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
    249                           StringRef FileName, bool IsAngled,
    250                           CharSourceRange FilenameRange, const FileEntry *File,
    251                           StringRef SearchPath, StringRef RelativePath,
    252                           const Module *Imported) override {
    253     bool isImport = (IncludeTok.is(tok::identifier) &&
    254             IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
    255     DataConsumer.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
    256                             Imported);
    257   }
    258 
    259   /// MacroDefined - This hook is called whenever a macro definition is seen.
    260   void MacroDefined(const Token &Id, const MacroDirective *MD) override {}
    261 
    262   /// MacroUndefined - This hook is called whenever a macro #undef is seen.
    263   /// MI is released immediately following this callback.
    264   void MacroUndefined(const Token &MacroNameTok,
    265                       const MacroDefinition &MD) override {}
    266 
    267   /// MacroExpands - This is called by when a macro invocation is found.
    268   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
    269                     SourceRange Range, const MacroArgs *Args) override {}
    270 
    271   /// SourceRangeSkipped - This hook is called when a source range is skipped.
    272   /// \param Range The SourceRange that was skipped. The range begins at the
    273   /// #if/#else directive and ends after the #endif/#else directive.
    274   void SourceRangeSkipped(SourceRange Range) override {}
    275 };
    276 
    277 //===----------------------------------------------------------------------===//
    278 // IndexingConsumer
    279 //===----------------------------------------------------------------------===//
    280 
    281 class IndexingConsumer : public ASTConsumer {
    282   CXIndexDataConsumer &DataConsumer;
    283   TUSkipBodyControl *SKCtrl;
    284 
    285 public:
    286   IndexingConsumer(CXIndexDataConsumer &dataConsumer, TUSkipBodyControl *skCtrl)
    287     : DataConsumer(dataConsumer), SKCtrl(skCtrl) { }
    288 
    289   // ASTConsumer Implementation
    290 
    291   void Initialize(ASTContext &Context) override {
    292     DataConsumer.setASTContext(Context);
    293     DataConsumer.startedTranslationUnit();
    294   }
    295 
    296   void HandleTranslationUnit(ASTContext &Ctx) override {
    297     if (SKCtrl)
    298       SKCtrl->finished();
    299   }
    300 
    301   bool HandleTopLevelDecl(DeclGroupRef DG) override {
    302     return !DataConsumer.shouldAbort();
    303   }
    304 
    305   bool shouldSkipFunctionBody(Decl *D) override {
    306     if (!SKCtrl) {
    307       // Always skip bodies.
    308       return true;
    309     }
    310 
    311     const SourceManager &SM = DataConsumer.getASTContext().getSourceManager();
    312     SourceLocation Loc = D->getLocation();
    313     if (Loc.isMacroID())
    314       return false;
    315     if (SM.isInSystemHeader(Loc))
    316       return true; // always skip bodies from system headers.
    317 
    318     FileID FID;
    319     unsigned Offset;
    320     std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
    321     // Don't skip bodies from main files; this may be revisited.
    322     if (SM.getMainFileID() == FID)
    323       return false;
    324     const FileEntry *FE = SM.getFileEntryForID(FID);
    325     if (!FE)
    326       return false;
    327 
    328     return SKCtrl->isParsed(Loc, FID, FE);
    329   }
    330 };
    331 
    332 //===----------------------------------------------------------------------===//
    333 // CaptureDiagnosticConsumer
    334 //===----------------------------------------------------------------------===//
    335 
    336 class CaptureDiagnosticConsumer : public DiagnosticConsumer {
    337   SmallVector<StoredDiagnostic, 4> Errors;
    338 public:
    339 
    340   void HandleDiagnostic(DiagnosticsEngine::Level level,
    341                         const Diagnostic &Info) override {
    342     if (level >= DiagnosticsEngine::Error)
    343       Errors.push_back(StoredDiagnostic(level, Info));
    344   }
    345 };
    346 
    347 //===----------------------------------------------------------------------===//
    348 // IndexingFrontendAction
    349 //===----------------------------------------------------------------------===//
    350 
    351 class IndexingFrontendAction : public ASTFrontendAction {
    352   std::shared_ptr<CXIndexDataConsumer> DataConsumer;
    353 
    354   SessionSkipBodyData *SKData;
    355   std::unique_ptr<TUSkipBodyControl> SKCtrl;
    356 
    357 public:
    358   IndexingFrontendAction(std::shared_ptr<CXIndexDataConsumer> dataConsumer,
    359                          SessionSkipBodyData *skData)
    360       : DataConsumer(std::move(dataConsumer)), SKData(skData) {}
    361 
    362   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
    363                                                  StringRef InFile) override {
    364     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
    365 
    366     if (!PPOpts.ImplicitPCHInclude.empty()) {
    367       DataConsumer->importedPCH(
    368                         CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude));
    369     }
    370 
    371     DataConsumer->setASTContext(CI.getASTContext());
    372     Preprocessor &PP = CI.getPreprocessor();
    373     PP.addPPCallbacks(llvm::make_unique<IndexPPCallbacks>(PP, *DataConsumer));
    374     DataConsumer->setPreprocessor(PP);
    375 
    376     if (SKData) {
    377       auto *PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
    378       PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(PPRec));
    379       SKCtrl = llvm::make_unique<TUSkipBodyControl>(*SKData, *PPRec, PP);
    380     }
    381 
    382     return llvm::make_unique<IndexingConsumer>(*DataConsumer, SKCtrl.get());
    383   }
    384 
    385   TranslationUnitKind getTranslationUnitKind() override {
    386     if (DataConsumer->shouldIndexImplicitTemplateInsts())
    387       return TU_Complete;
    388     else
    389       return TU_Prefix;
    390   }
    391   bool hasCodeCompletionSupport() const override { return false; }
    392 };
    393 
    394 //===----------------------------------------------------------------------===//
    395 // clang_indexSourceFileUnit Implementation
    396 //===----------------------------------------------------------------------===//
    397 
    398 static IndexingOptions getIndexingOptionsFromCXOptions(unsigned index_options) {
    399   IndexingOptions IdxOpts;
    400   if (index_options & CXIndexOpt_IndexFunctionLocalSymbols)
    401     IdxOpts.IndexFunctionLocals = true;
    402   return IdxOpts;
    403 }
    404 
    405 struct IndexSessionData {
    406   CXIndex CIdx;
    407   std::unique_ptr<SessionSkipBodyData> SkipBodyData;
    408 
    409   explicit IndexSessionData(CXIndex cIdx)
    410     : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
    411 };
    412 
    413 } // anonymous namespace
    414 
    415 static CXErrorCode clang_indexSourceFile_Impl(
    416     CXIndexAction cxIdxAction, CXClientData client_data,
    417     IndexerCallbacks *client_index_callbacks, unsigned index_callbacks_size,
    418     unsigned index_options, const char *source_filename,
    419     const char *const *command_line_args, int num_command_line_args,
    420     ArrayRef<CXUnsavedFile> unsaved_files, CXTranslationUnit *out_TU,
    421     unsigned TU_options) {
    422   if (out_TU)
    423     *out_TU = nullptr;
    424   bool requestedToGetTU = (out_TU != nullptr);
    425 
    426   if (!cxIdxAction) {
    427     return CXError_InvalidArguments;
    428   }
    429   if (!client_index_callbacks || index_callbacks_size == 0) {
    430     return CXError_InvalidArguments;
    431   }
    432 
    433   IndexerCallbacks CB;
    434   memset(&CB, 0, sizeof(CB));
    435   unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
    436                                   ? index_callbacks_size : sizeof(CB);
    437   memcpy(&CB, client_index_callbacks, ClientCBSize);
    438 
    439   IndexSessionData *IdxSession = static_cast<IndexSessionData *>(cxIdxAction);
    440   CIndexer *CXXIdx = static_cast<CIndexer *>(IdxSession->CIdx);
    441 
    442   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
    443     setThreadBackgroundPriority();
    444 
    445   bool CaptureDiagnostics = !Logger::isLoggingEnabled();
    446 
    447   CaptureDiagnosticConsumer *CaptureDiag = nullptr;
    448   if (CaptureDiagnostics)
    449     CaptureDiag = new CaptureDiagnosticConsumer();
    450 
    451   // Configure the diagnostics.
    452   IntrusiveRefCntPtr<DiagnosticsEngine>
    453     Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
    454                                               CaptureDiag,
    455                                               /*ShouldOwnClient=*/true));
    456 
    457   // Recover resources if we crash before exiting this function.
    458   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
    459     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
    460     DiagCleanup(Diags.get());
    461 
    462   std::unique_ptr<std::vector<const char *>> Args(
    463       new std::vector<const char *>());
    464 
    465   // Recover resources if we crash before exiting this method.
    466   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
    467     ArgsCleanup(Args.get());
    468 
    469   Args->insert(Args->end(), command_line_args,
    470                command_line_args + num_command_line_args);
    471 
    472   // The 'source_filename' argument is optional.  If the caller does not
    473   // specify it then it is assumed that the source file is specified
    474   // in the actual argument list.
    475   // Put the source file after command_line_args otherwise if '-x' flag is
    476   // present it will be unused.
    477   if (source_filename)
    478     Args->push_back(source_filename);
    479 
    480   IntrusiveRefCntPtr<CompilerInvocation>
    481     CInvok(createInvocationFromCommandLine(*Args, Diags));
    482 
    483   if (!CInvok)
    484     return CXError_Failure;
    485 
    486   // Recover resources if we crash before exiting this function.
    487   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
    488     llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
    489     CInvokCleanup(CInvok.get());
    490 
    491   if (CInvok->getFrontendOpts().Inputs.empty())
    492     return CXError_Failure;
    493 
    494   typedef SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 8> MemBufferOwner;
    495   std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner);
    496 
    497   // Recover resources if we crash before exiting this method.
    498   llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup(
    499       BufOwner.get());
    500 
    501   for (auto &UF : unsaved_files) {
    502     std::unique_ptr<llvm::MemoryBuffer> MB =
    503         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
    504     CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB.get());
    505     BufOwner->push_back(std::move(MB));
    506   }
    507 
    508   // Since libclang is primarily used by batch tools dealing with
    509   // (often very broken) source code, where spell-checking can have a
    510   // significant negative impact on performance (particularly when
    511   // precompiled headers are involved), we disable it.
    512   CInvok->getLangOpts()->SpellChecking = false;
    513 
    514   if (index_options & CXIndexOpt_SuppressWarnings)
    515     CInvok->getDiagnosticOpts().IgnoreWarnings = true;
    516 
    517   // Make sure to use the raw module format.
    518   CInvok->getHeaderSearchOpts().ModuleFormat =
    519     CXXIdx->getPCHContainerOperations()->getRawReader().getFormat();
    520 
    521   ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags, CaptureDiagnostics,
    522                                   /*UserFilesAreVolatile=*/true);
    523   if (!Unit)
    524     return CXError_InvalidArguments;
    525 
    526   std::unique_ptr<CXTUOwner> CXTU(
    527       new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
    528 
    529   // Recover resources if we crash before exiting this method.
    530   llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
    531     CXTUCleanup(CXTU.get());
    532 
    533   // Enable the skip-parsed-bodies optimization only for C++; this may be
    534   // revisited.
    535   bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
    536       CInvok->getLangOpts()->CPlusPlus;
    537   if (SkipBodies)
    538     CInvok->getFrontendOpts().SkipFunctionBodies = true;
    539 
    540   auto DataConsumer =
    541     std::make_shared<CXIndexDataConsumer>(client_data, CB, index_options,
    542                                           CXTU->getTU());
    543   auto InterAction = llvm::make_unique<IndexingFrontendAction>(DataConsumer,
    544                          SkipBodies ? IdxSession->SkipBodyData.get() : nullptr);
    545   std::unique_ptr<FrontendAction> IndexAction;
    546   IndexAction = createIndexingAction(DataConsumer,
    547                                 getIndexingOptionsFromCXOptions(index_options),
    548                                      std::move(InterAction));
    549 
    550   // Recover resources if we crash before exiting this method.
    551   llvm::CrashRecoveryContextCleanupRegistrar<FrontendAction>
    552     IndexActionCleanup(IndexAction.get());
    553 
    554   bool Persistent = requestedToGetTU;
    555   bool OnlyLocalDecls = false;
    556   bool PrecompilePreamble = false;
    557   bool CreatePreambleOnFirstParse = false;
    558   bool CacheCodeCompletionResults = false;
    559   PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
    560   PPOpts.AllowPCHWithCompilerErrors = true;
    561 
    562   if (requestedToGetTU) {
    563     OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
    564     PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
    565     CreatePreambleOnFirstParse =
    566         TU_options & CXTranslationUnit_CreatePreambleOnFirstParse;
    567     // FIXME: Add a flag for modules.
    568     CacheCodeCompletionResults
    569       = TU_options & CXTranslationUnit_CacheCompletionResults;
    570   }
    571 
    572   if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) {
    573     PPOpts.DetailedRecord = true;
    574   }
    575 
    576   if (!requestedToGetTU && !CInvok->getLangOpts()->Modules)
    577     PPOpts.DetailedRecord = false;
    578 
    579   // Unless the user specified that they want the preamble on the first parse
    580   // set it up to be created on the first reparse. This makes the first parse
    581   // faster, trading for a slower (first) reparse.
    582   unsigned PrecompilePreambleAfterNParses =
    583       !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
    584   DiagnosticErrorTrap DiagTrap(*Diags);
    585   bool Success = ASTUnit::LoadFromCompilerInvocationAction(
    586       CInvok.get(), CXXIdx->getPCHContainerOperations(), Diags,
    587       IndexAction.get(), Unit, Persistent, CXXIdx->getClangResourcesPath(),
    588       OnlyLocalDecls, CaptureDiagnostics, PrecompilePreambleAfterNParses,
    589       CacheCodeCompletionResults,
    590       /*IncludeBriefCommentsInCodeCompletion=*/false,
    591       /*UserFilesAreVolatile=*/true);
    592   if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
    593     printDiagsToStderr(Unit);
    594 
    595   if (isASTReadError(Unit))
    596     return CXError_ASTReadError;
    597 
    598   if (!Success)
    599     return CXError_Failure;
    600 
    601   if (out_TU)
    602     *out_TU = CXTU->takeTU();
    603 
    604   return CXError_Success;
    605 }
    606 
    607 //===----------------------------------------------------------------------===//
    608 // clang_indexTranslationUnit Implementation
    609 //===----------------------------------------------------------------------===//
    610 
    611 static void indexPreprocessingRecord(ASTUnit &Unit, CXIndexDataConsumer &IdxCtx) {
    612   Preprocessor &PP = Unit.getPreprocessor();
    613   if (!PP.getPreprocessingRecord())
    614     return;
    615 
    616   // FIXME: Only deserialize inclusion directives.
    617 
    618   bool isModuleFile = Unit.isModuleFile();
    619   for (PreprocessedEntity *PPE : Unit.getLocalPreprocessingEntities()) {
    620     if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
    621       SourceLocation Loc = ID->getSourceRange().getBegin();
    622       // Modules have synthetic main files as input, give an invalid location
    623       // if the location points to such a file.
    624       if (isModuleFile && Unit.isInMainFileID(Loc))
    625         Loc = SourceLocation();
    626       IdxCtx.ppIncludedFile(Loc, ID->getFileName(),
    627                             ID->getFile(),
    628                             ID->getKind() == InclusionDirective::Import,
    629                             !ID->wasInQuotes(), ID->importedModule());
    630     }
    631   }
    632 }
    633 
    634 static CXErrorCode clang_indexTranslationUnit_Impl(
    635     CXIndexAction idxAction, CXClientData client_data,
    636     IndexerCallbacks *client_index_callbacks, unsigned index_callbacks_size,
    637     unsigned index_options, CXTranslationUnit TU) {
    638   // Check arguments.
    639   if (isNotUsableTU(TU)) {
    640     LOG_BAD_TU(TU);
    641     return CXError_InvalidArguments;
    642   }
    643   if (!client_index_callbacks || index_callbacks_size == 0) {
    644     return CXError_InvalidArguments;
    645   }
    646 
    647   CIndexer *CXXIdx = TU->CIdx;
    648   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
    649     setThreadBackgroundPriority();
    650 
    651   IndexerCallbacks CB;
    652   memset(&CB, 0, sizeof(CB));
    653   unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
    654                                   ? index_callbacks_size : sizeof(CB);
    655   memcpy(&CB, client_index_callbacks, ClientCBSize);
    656 
    657   auto DataConsumer = std::make_shared<CXIndexDataConsumer>(client_data, CB,
    658                                                             index_options, TU);
    659 
    660   ASTUnit *Unit = cxtu::getASTUnit(TU);
    661   if (!Unit)
    662     return CXError_Failure;
    663 
    664   ASTUnit::ConcurrencyCheck Check(*Unit);
    665 
    666   if (const FileEntry *PCHFile = Unit->getPCHFile())
    667     DataConsumer->importedPCH(PCHFile);
    668 
    669   FileManager &FileMgr = Unit->getFileManager();
    670 
    671   if (Unit->getOriginalSourceFileName().empty())
    672     DataConsumer->enteredMainFile(nullptr);
    673   else
    674     DataConsumer->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
    675 
    676   DataConsumer->setASTContext(Unit->getASTContext());
    677   DataConsumer->startedTranslationUnit();
    678 
    679   indexPreprocessingRecord(*Unit, *DataConsumer);
    680   indexASTUnit(*Unit, DataConsumer, getIndexingOptionsFromCXOptions(index_options));
    681   DataConsumer->indexDiagnostics();
    682 
    683   return CXError_Success;
    684 }
    685 
    686 //===----------------------------------------------------------------------===//
    687 // libclang public APIs.
    688 //===----------------------------------------------------------------------===//
    689 
    690 extern "C" {
    691 
    692 int clang_index_isEntityObjCContainerKind(CXIdxEntityKind K) {
    693   return CXIdxEntity_ObjCClass <= K && K <= CXIdxEntity_ObjCCategory;
    694 }
    695 
    696 const CXIdxObjCContainerDeclInfo *
    697 clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) {
    698   if (!DInfo)
    699     return nullptr;
    700 
    701   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
    702   if (const ObjCContainerDeclInfo *
    703         ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI))
    704     return &ContInfo->ObjCContDeclInfo;
    705 
    706   return nullptr;
    707 }
    708 
    709 const CXIdxObjCInterfaceDeclInfo *
    710 clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) {
    711   if (!DInfo)
    712     return nullptr;
    713 
    714   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
    715   if (const ObjCInterfaceDeclInfo *
    716         InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
    717     return &InterInfo->ObjCInterDeclInfo;
    718 
    719   return nullptr;
    720 }
    721 
    722 const CXIdxObjCCategoryDeclInfo *
    723 clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){
    724   if (!DInfo)
    725     return nullptr;
    726 
    727   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
    728   if (const ObjCCategoryDeclInfo *
    729         CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
    730     return &CatInfo->ObjCCatDeclInfo;
    731 
    732   return nullptr;
    733 }
    734 
    735 const CXIdxObjCProtocolRefListInfo *
    736 clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) {
    737   if (!DInfo)
    738     return nullptr;
    739 
    740   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
    741 
    742   if (const ObjCInterfaceDeclInfo *
    743         InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
    744     return InterInfo->ObjCInterDeclInfo.protocols;
    745 
    746   if (const ObjCProtocolDeclInfo *
    747         ProtInfo = dyn_cast<ObjCProtocolDeclInfo>(DI))
    748     return &ProtInfo->ObjCProtoRefListInfo;
    749 
    750   if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
    751     return CatInfo->ObjCCatDeclInfo.protocols;
    752 
    753   return nullptr;
    754 }
    755 
    756 const CXIdxObjCPropertyDeclInfo *
    757 clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) {
    758   if (!DInfo)
    759     return nullptr;
    760 
    761   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
    762   if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI))
    763     return &PropInfo->ObjCPropDeclInfo;
    764 
    765   return nullptr;
    766 }
    767 
    768 const CXIdxIBOutletCollectionAttrInfo *
    769 clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) {
    770   if (!AInfo)
    771     return nullptr;
    772 
    773   const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo);
    774   if (const IBOutletCollectionInfo *
    775         IBInfo = dyn_cast<IBOutletCollectionInfo>(DI))
    776     return &IBInfo->IBCollInfo;
    777 
    778   return nullptr;
    779 }
    780 
    781 const CXIdxCXXClassDeclInfo *
    782 clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) {
    783   if (!DInfo)
    784     return nullptr;
    785 
    786   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
    787   if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI))
    788     return &ClassInfo->CXXClassInfo;
    789 
    790   return nullptr;
    791 }
    792 
    793 CXIdxClientContainer
    794 clang_index_getClientContainer(const CXIdxContainerInfo *info) {
    795   if (!info)
    796     return nullptr;
    797   const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
    798   return Container->IndexCtx->getClientContainerForDC(Container->DC);
    799 }
    800 
    801 void clang_index_setClientContainer(const CXIdxContainerInfo *info,
    802                                     CXIdxClientContainer client) {
    803   if (!info)
    804     return;
    805   const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
    806   Container->IndexCtx->addContainerInMap(Container->DC, client);
    807 }
    808 
    809 CXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) {
    810   if (!info)
    811     return nullptr;
    812   const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
    813   return Entity->IndexCtx->getClientEntity(Entity->Dcl);
    814 }
    815 
    816 void clang_index_setClientEntity(const CXIdxEntityInfo *info,
    817                                  CXIdxClientEntity client) {
    818   if (!info)
    819     return;
    820   const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
    821   Entity->IndexCtx->setClientEntity(Entity->Dcl, client);
    822 }
    823 
    824 CXIndexAction clang_IndexAction_create(CXIndex CIdx) {
    825   return new IndexSessionData(CIdx);
    826 }
    827 
    828 void clang_IndexAction_dispose(CXIndexAction idxAction) {
    829   if (idxAction)
    830     delete static_cast<IndexSessionData *>(idxAction);
    831 }
    832 
    833 int clang_indexSourceFile(CXIndexAction idxAction,
    834                           CXClientData client_data,
    835                           IndexerCallbacks *index_callbacks,
    836                           unsigned index_callbacks_size,
    837                           unsigned index_options,
    838                           const char *source_filename,
    839                           const char * const *command_line_args,
    840                           int num_command_line_args,
    841                           struct CXUnsavedFile *unsaved_files,
    842                           unsigned num_unsaved_files,
    843                           CXTranslationUnit *out_TU,
    844                           unsigned TU_options) {
    845   SmallVector<const char *, 4> Args;
    846   Args.push_back("clang");
    847   Args.append(command_line_args, command_line_args + num_command_line_args);
    848   return clang_indexSourceFileFullArgv(
    849       idxAction, client_data, index_callbacks, index_callbacks_size,
    850       index_options, source_filename, Args.data(), Args.size(), unsaved_files,
    851       num_unsaved_files, out_TU, TU_options);
    852 }
    853 
    854 int clang_indexSourceFileFullArgv(
    855     CXIndexAction idxAction, CXClientData client_data,
    856     IndexerCallbacks *index_callbacks, unsigned index_callbacks_size,
    857     unsigned index_options, const char *source_filename,
    858     const char *const *command_line_args, int num_command_line_args,
    859     struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
    860     CXTranslationUnit *out_TU, unsigned TU_options) {
    861   LOG_FUNC_SECTION {
    862     *Log << source_filename << ": ";
    863     for (int i = 0; i != num_command_line_args; ++i)
    864       *Log << command_line_args[i] << " ";
    865   }
    866 
    867   if (num_unsaved_files && !unsaved_files)
    868     return CXError_InvalidArguments;
    869 
    870   CXErrorCode result = CXError_Failure;
    871   auto IndexSourceFileImpl = [=, &result]() {
    872     result = clang_indexSourceFile_Impl(
    873         idxAction, client_data, index_callbacks, index_callbacks_size,
    874         index_options, source_filename, command_line_args,
    875         num_command_line_args,
    876         llvm::makeArrayRef(unsaved_files, num_unsaved_files), out_TU,
    877         TU_options);
    878   };
    879 
    880   if (getenv("LIBCLANG_NOTHREADS")) {
    881     IndexSourceFileImpl();
    882     return result;
    883   }
    884 
    885   llvm::CrashRecoveryContext CRC;
    886 
    887   if (!RunSafely(CRC, IndexSourceFileImpl)) {
    888     fprintf(stderr, "libclang: crash detected during indexing source file: {\n");
    889     fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
    890     fprintf(stderr, "  'command_line_args' : [");
    891     for (int i = 0; i != num_command_line_args; ++i) {
    892       if (i)
    893         fprintf(stderr, ", ");
    894       fprintf(stderr, "'%s'", command_line_args[i]);
    895     }
    896     fprintf(stderr, "],\n");
    897     fprintf(stderr, "  'unsaved_files' : [");
    898     for (unsigned i = 0; i != num_unsaved_files; ++i) {
    899       if (i)
    900         fprintf(stderr, ", ");
    901       fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
    902               unsaved_files[i].Length);
    903     }
    904     fprintf(stderr, "],\n");
    905     fprintf(stderr, "  'options' : %d,\n", TU_options);
    906     fprintf(stderr, "}\n");
    907 
    908     return 1;
    909   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
    910     if (out_TU)
    911       PrintLibclangResourceUsage(*out_TU);
    912   }
    913 
    914   return result;
    915 }
    916 
    917 int clang_indexTranslationUnit(CXIndexAction idxAction,
    918                                CXClientData client_data,
    919                                IndexerCallbacks *index_callbacks,
    920                                unsigned index_callbacks_size,
    921                                unsigned index_options,
    922                                CXTranslationUnit TU) {
    923   LOG_FUNC_SECTION {
    924     *Log << TU;
    925   }
    926 
    927   CXErrorCode result;
    928   auto IndexTranslationUnitImpl = [=, &result]() {
    929     result = clang_indexTranslationUnit_Impl(
    930         idxAction, client_data, index_callbacks, index_callbacks_size,
    931         index_options, TU);
    932   };
    933 
    934   if (getenv("LIBCLANG_NOTHREADS")) {
    935     IndexTranslationUnitImpl();
    936     return result;
    937   }
    938 
    939   llvm::CrashRecoveryContext CRC;
    940 
    941   if (!RunSafely(CRC, IndexTranslationUnitImpl)) {
    942     fprintf(stderr, "libclang: crash detected during indexing TU\n");
    943 
    944     return 1;
    945   }
    946 
    947   return result;
    948 }
    949 
    950 void clang_indexLoc_getFileLocation(CXIdxLoc location,
    951                                     CXIdxClientFile *indexFile,
    952                                     CXFile *file,
    953                                     unsigned *line,
    954                                     unsigned *column,
    955                                     unsigned *offset) {
    956   if (indexFile) *indexFile = nullptr;
    957   if (file)   *file = nullptr;
    958   if (line)   *line = 0;
    959   if (column) *column = 0;
    960   if (offset) *offset = 0;
    961 
    962   SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
    963   if (!location.ptr_data[0] || Loc.isInvalid())
    964     return;
    965 
    966   CXIndexDataConsumer &DataConsumer =
    967       *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
    968   DataConsumer.translateLoc(Loc, indexFile, file, line, column, offset);
    969 }
    970 
    971 CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
    972   SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
    973   if (!location.ptr_data[0] || Loc.isInvalid())
    974     return clang_getNullLocation();
    975 
    976   CXIndexDataConsumer &DataConsumer =
    977       *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
    978   return cxloc::translateSourceLocation(DataConsumer.getASTContext(), Loc);
    979 }
    980 
    981 } // end: extern "C"
    982 
    983