14e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
24e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
34e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
44e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
54e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
64e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
74e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
84e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
94e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "IndexingContext.h"
11f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CIndexDiagnostic.h"
12f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CIndexer.h"
13b1ba0efc3d1dc1daa5d82c40bc504e1f368c4fa0Chandler Carruth#include "CLog.h"
144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "CXCursor.h"
154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "CXSourceLocation.h"
164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "CXString.h"
17f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CXTranslationUnit.h"
18f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/AST/ASTConsumer.h"
19f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/AST/DeclVisitor.h"
204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "clang/Frontend/ASTUnit.h"
214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "clang/Frontend/CompilerInstance.h"
22f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/Frontend/CompilerInvocation.h"
231f6b2b5c82b2d2d3935b0db76352a04e9877b73fDouglas Gregor#include "clang/Frontend/FrontendAction.h"
244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "clang/Frontend/Utils.h"
25b99083e60325a28063fb588f458a871151971fdcChandler Carruth#include "clang/Lex/HeaderSearch.h"
264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "clang/Lex/PPCallbacks.h"
27838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis#include "clang/Lex/PPConditionalDirectiveRecord.h"
28b99083e60325a28063fb588f458a871151971fdcChandler Carruth#include "clang/Lex/Preprocessor.h"
29f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/Sema/SemaConsumer.h"
304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "llvm/Support/CrashRecoveryContext.h"
31f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "llvm/Support/MemoryBuffer.h"
32838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis#include "llvm/Support/Mutex.h"
33838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis#include "llvm/Support/MutexGuard.h"
349af20d8187384b841a6244ab81c8a57b010d72d0Dmitri Gribenko#include <cstdio>
354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace clang;
374e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxtu;
384e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxindex;
394e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
40996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidisstatic void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx);
41996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis
424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisnamespace {
434e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
444e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
45838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis// Skip Parsed Bodies
46838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
47838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
48838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis#ifdef LLVM_ON_WIN32
49838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
50838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis// FIXME: On windows it is disabled since current implementation depends on
51838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis// file inodes.
52838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
53838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisclass SessionSkipBodyData { };
54838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
55838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisclass TUSkipBodyControl {
56838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidispublic:
57838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  TUSkipBodyControl(SessionSkipBodyData &sessionData,
58335078b0ffa844a963fdebab58b80f645ba32088Evgeniy Stepanov                    PPConditionalDirectiveRecord &ppRec,
59335078b0ffa844a963fdebab58b80f645ba32088Evgeniy Stepanov                    Preprocessor &pp) { }
60838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
61838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return false;
62838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
63838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  void finished() { }
64838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis};
65838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
66838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis#else
67838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
68838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// \brief A "region" in source code identified by the file/offset of the
69838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// preprocessor conditional directive that it belongs to.
70838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// Multiple, non-consecutive ranges can be parts of the same region.
71838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///
72838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// As an example of different regions separated by preprocessor directives:
73838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///
74838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// \code
75838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #1
76838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// #ifdef BLAH
77838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #2
78838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// #ifdef CAKE
79838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #3
80838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// #endif
81838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #2
82838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// #endif
83838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #1
84838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// \endcode
85838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///
86838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis/// There are 3 regions, with non-consecutive parts:
87838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #1 is identified as the beginning of the file
88838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #2 is identified as the location of "#ifdef BLAH"
89838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///   #3 is identified as the location of "#ifdef CAKE"
90838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis///
91838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisclass PPRegion {
920fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola  llvm::sys::fs::UniqueID UniqueID;
93838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  time_t ModTime;
94838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  unsigned Offset;
95838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidispublic:
9613a165e3a1499a942fc4435b5e574d17ea0f54f1Alexey Samsonov  PPRegion() : UniqueID(0, 0), ModTime(), Offset() {}
970fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola  PPRegion(llvm::sys::fs::UniqueID UniqueID, unsigned offset, time_t modTime)
980fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      : UniqueID(UniqueID), ModTime(modTime), Offset(offset) {}
99838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
1000fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola  const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
101838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  unsigned getOffset() const { return Offset; }
102838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  time_t getModTime() const { return ModTime; }
103838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
104838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool isInvalid() const { return *this == PPRegion(); }
105838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
106838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  friend bool operator==(const PPRegion &lhs, const PPRegion &rhs) {
1070fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola    return lhs.UniqueID == rhs.UniqueID && lhs.Offset == rhs.Offset &&
1080fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola           lhs.ModTime == rhs.ModTime;
109838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
110838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis};
111838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
112838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidistypedef llvm::DenseSet<PPRegion> PPRegionSetTy;
113838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
114838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis} // end anonymous namespace
115838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
116838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisnamespace llvm {
117838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  template <> struct isPodLike<PPRegion> {
118838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    static const bool value = true;
119838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  };
120838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
121838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  template <>
122838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  struct DenseMapInfo<PPRegion> {
123838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    static inline PPRegion getEmptyKey() {
1240fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-1), 0);
125838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
126838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    static inline PPRegion getTombstoneKey() {
1270fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-2), 0);
128838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
129838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
130838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    static unsigned getHashValue(const PPRegion &S) {
131838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      llvm::FoldingSetNodeID ID;
1320fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      const llvm::sys::fs::UniqueID &UniqueID = S.getUniqueID();
1330fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      ID.AddInteger(UniqueID.getFile());
1340fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      ID.AddInteger(UniqueID.getDevice());
135838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      ID.AddInteger(S.getOffset());
136838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      ID.AddInteger(S.getModTime());
137838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return ID.ComputeHash();
138838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
139838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
140838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    static bool isEqual(const PPRegion &LHS, const PPRegion &RHS) {
141838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return LHS == RHS;
142838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
143838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  };
144838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis}
145838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
146838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisnamespace {
147838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
148838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisclass SessionSkipBodyData {
149838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  llvm::sys::Mutex Mux;
150838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  PPRegionSetTy ParsedRegions;
151838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
152838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidispublic:
153838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  SessionSkipBodyData() : Mux(/*recursive=*/false) {}
154838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  ~SessionSkipBodyData() {
155838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    //llvm::errs() << "RegionData: " << Skipped.size() << " - " << Skipped.getMemorySize() << "\n";
156838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
157838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
158838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  void copyTo(PPRegionSetTy &Set) {
159838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    llvm::MutexGuard MG(Mux);
160838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    Set = ParsedRegions;
161838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
162838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
163838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  void update(ArrayRef<PPRegion> Regions) {
164838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    llvm::MutexGuard MG(Mux);
165838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    ParsedRegions.insert(Regions.begin(), Regions.end());
166838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
167838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis};
168838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
169838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisclass TUSkipBodyControl {
170838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  SessionSkipBodyData &SessionData;
171838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  PPConditionalDirectiveRecord &PPRec;
172838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  Preprocessor &PP;
173838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
174838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  PPRegionSetTy ParsedRegions;
175838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  SmallVector<PPRegion, 32> NewParsedRegions;
176838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  PPRegion LastRegion;
177838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool LastIsParsed;
178838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
179838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidispublic:
180838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  TUSkipBodyControl(SessionSkipBodyData &sessionData,
181838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                    PPConditionalDirectiveRecord &ppRec,
182838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                    Preprocessor &pp)
183838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    : SessionData(sessionData), PPRec(ppRec), PP(pp) {
184838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    SessionData.copyTo(ParsedRegions);
185838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
186838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
187838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
188838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    PPRegion region = getRegion(Loc, FID, FE);
189838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (region.isInvalid())
190838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
191838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
192838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    // Check common case, consecutive functions in the same region.
193838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (LastRegion == region)
194838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return LastIsParsed;
195838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
196838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    LastRegion = region;
197838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    LastIsParsed = ParsedRegions.count(region);
198838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (!LastIsParsed)
199838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      NewParsedRegions.push_back(region);
200838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return LastIsParsed;
201838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
202838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
203838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  void finished() {
204838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    SessionData.update(NewParsedRegions);
205838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
206838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
207838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisprivate:
208838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  PPRegion getRegion(SourceLocation Loc, FileID FID, const FileEntry *FE) {
209838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    SourceLocation RegionLoc = PPRec.findConditionalDirectiveRegionLoc(Loc);
210838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (RegionLoc.isInvalid()) {
2110fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      if (isParsedOnceInclude(FE)) {
2120fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola        const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
2130fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola        return PPRegion(ID, 0, FE->getModificationTime());
2140fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      }
215838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return PPRegion();
216838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
217838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
218838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    const SourceManager &SM = PPRec.getSourceManager();
219838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    assert(RegionLoc.isFileID());
220838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    FileID RegionFID;
221838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    unsigned RegionOffset;
222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    std::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
223838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
224838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (RegionFID != FID) {
2250fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      if (isParsedOnceInclude(FE)) {
2260fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola        const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
2270fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola        return PPRegion(ID, 0, FE->getModificationTime());
2280fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola      }
229838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return PPRegion();
230838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
231838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
2320fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola    const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
2330fda0f75f053ad9afdb2bb8d4ea72c5e6a49d657Rafael Espindola    return PPRegion(ID, RegionOffset, FE->getModificationTime());
234838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
235838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
236838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool isParsedOnceInclude(const FileEntry *FE) {
237838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE);
238838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
239838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis};
240838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
241838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis#endif
242838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
243838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
2444e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// IndexPPCallbacks
2454e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
2464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass IndexPPCallbacks : public PPCallbacks {
2484e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  Preprocessor &PP;
2494e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx;
250dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis  bool IsMainFileEntered;
2514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
2534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexPPCallbacks(Preprocessor &PP, IndexingContext &indexCtx)
254dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    : PP(PP), IndexCtx(indexCtx), IsMainFileEntered(false) { }
255dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 SrcMgr::CharacteristicKind FileType, FileID PrevFID) override {
258dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    if (IsMainFileEntered)
259dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis      return;
260dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
261dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    SourceManager &SM = PP.getSourceManager();
262dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    SourceLocation MainFileLoc = SM.getLocForStartOfFile(SM.getMainFileID());
263dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
264dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    if (Loc == MainFileLoc && Reason == PPCallbacks::EnterFile) {
265dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis      IsMainFileEntered = true;
266dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis      IndexCtx.enteredMainFile(SM.getFileEntryForID(SM.getMainFileID()));
267dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis    }
268dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis  }
2694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          StringRef FileName, bool IsAngled,
272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          CharSourceRange FilenameRange, const FileEntry *File,
273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          StringRef SearchPath, StringRef RelativePath,
274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          const Module *Imported) override {
2754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    bool isImport = (IncludeTok.is(tok::identifier) &&
2764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis            IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
2778d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis    IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
2788d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            Imported);
2794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
2804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MacroDefined - This hook is called whenever a macro definition is seen.
282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void MacroDefined(const Token &Id, const MacroDirective *MD) override {}
2834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
2854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MI is released immediately following this callback.
286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void MacroUndefined(const Token &MacroNameTok,
287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                      const MacroDirective *MD) override {}
2884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MacroExpands - This is called by when a macro invocation is found.
290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    SourceRange Range, const MacroArgs *Args) override {}
292838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
2934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// SourceRangeSkipped - This hook is called when a source range is skipped.
2944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// \param Range The SourceRange that was skipped. The range begins at the
2954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// #if/#else directive and ends after the #endif/#else directive.
296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void SourceRangeSkipped(SourceRange Range) override {}
2974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
2984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// IndexingConsumer
3014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass IndexingConsumer : public ASTConsumer {
3044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx;
305838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  TUSkipBodyControl *SKCtrl;
3064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
308838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  IndexingConsumer(IndexingContext &indexCtx, TUSkipBodyControl *skCtrl)
309838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    : IndexCtx(indexCtx), SKCtrl(skCtrl) { }
3104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // ASTConsumer Implementation
3124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void Initialize(ASTContext &Context) override {
3144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.setASTContext(Context);
3156ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis    IndexCtx.startedTranslationUnit();
3164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleTranslationUnit(ASTContext &Ctx) override {
319838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SKCtrl)
320838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      SKCtrl->finished();
3214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool HandleTopLevelDecl(DeclGroupRef DG) override {
3244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.indexDeclGroupRef(DG);
32588c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis    return !IndexCtx.shouldAbort();
3264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// \brief Handle the specified top-level declaration that occurred inside
3294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// and ObjC container.
330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
3314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    // They will be handled after the interface is seen first.
3324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.addTUDeclInObjCContainer(D);
3334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// \brief This is called by the AST reader when deserializing things.
3364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// The default implementation forwards to HandleTopLevelDecl but we don't
3374e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// care about them when indexing, so have an empty definition.
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleInterestingDecl(DeclGroupRef D) override {}
3396d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis
340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleTagDeclDefinition(TagDecl *D) override {
34158d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    if (!IndexCtx.shouldIndexImplicitTemplateInsts())
34258d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return;
34358d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis
3446d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis    if (IndexCtx.isTemplateImplicitInstantiation(D))
3456d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis      IndexCtx.indexDecl(D);
3466d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis  }
3476d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis
348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override {
34958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    if (!IndexCtx.shouldIndexImplicitTemplateInsts())
35058d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return;
35158d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis
3526d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis    IndexCtx.indexDecl(D);
3536d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis  }
354838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool shouldSkipFunctionBody(Decl *D) override {
356838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (!SKCtrl) {
357838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      // Always skip bodies.
358838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return true;
359838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
360838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
361838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    const SourceManager &SM = IndexCtx.getASTContext().getSourceManager();
362838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    SourceLocation Loc = D->getLocation();
363838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (Loc.isMacroID())
364838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
365838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SM.isInSystemHeader(Loc))
366838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return true; // always skip bodies from system headers.
367838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
368838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    FileID FID;
369838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    unsigned Offset;
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
371838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    // Don't skip bodies from main files; this may be revisited.
372838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SM.getMainFileID() == FID)
373838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
374838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    const FileEntry *FE = SM.getFileEntryForID(FID);
375838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (!FE)
376838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
377838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
378838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return SKCtrl->isParsed(Loc, FID, FE);
379838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
3804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
3814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
383b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis// CaptureDiagnosticConsumer
3844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass CaptureDiagnosticConsumer : public DiagnosticConsumer {
3874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SmallVector<StoredDiagnostic, 4> Errors;
3884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
3894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleDiagnostic(DiagnosticsEngine::Level level,
391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        const Diagnostic &Info) override {
3924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (level >= DiagnosticsEngine::Error)
3934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      Errors.push_back(StoredDiagnostic(level, Info));
3944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
3964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// IndexingFrontendAction
3994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
4004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass IndexingFrontendAction : public ASTFrontendAction {
4024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext IndexCtx;
403996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  CXTranslationUnit CXTU;
4044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
405838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  SessionSkipBodyData *SKData;
406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<TUSkipBodyControl> SKCtrl;
407838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
4084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
4094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingFrontendAction(CXClientData clientData,
4104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                         IndexerCallbacks &indexCallbacks,
4114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                         unsigned indexOptions,
412838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                         CXTranslationUnit cxTU,
413838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                         SessionSkipBodyData *skData)
414996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis    : IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
415838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      CXTU(cxTU), SKData(skData) { }
4164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 StringRef InFile) override {
4193da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
4203da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
4213da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    if (!PPOpts.ImplicitPCHInclude.empty()) {
4223da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis      IndexCtx.importedPCH(
4233da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis                        CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude));
4243da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    }
4253fe97781ad5f31dbfd9348c9488b93a7c01d7818Argyrios Kyrtzidis
4264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.setASTContext(CI.getASTContext());
4274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    Preprocessor &PP = CI.getPreprocessor();
4284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx));
4297fe90f3bfa6bd7f779ecfd4ba201a296a3a1c8cbArgyrios Kyrtzidis    IndexCtx.setPreprocessor(PP);
430838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
431838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SKData) {
432838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      PPConditionalDirectiveRecord *
433838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis        PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
434838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      PP.addPPCallbacks(PPRec);
435838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      SKCtrl.reset(new TUSkipBodyControl(*SKData, *PPRec, PP));
436838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
437838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
438838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return new IndexingConsumer(IndexCtx, SKCtrl.get());
4394e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
4404e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void EndSourceFileAction() override {
442996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis    indexDiagnostics(CXTU, IndexCtx);
443996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  }
444996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  TranslationUnitKind getTranslationUnitKind() override {
44658d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    if (IndexCtx.shouldIndexImplicitTemplateInsts())
44758d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return TU_Complete;
44858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    else
44958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return TU_Prefix;
45058d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis  }
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool hasCodeCompletionSupport() const override { return false; }
4524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
4534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
45521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis// clang_indexSourceFileUnit Implementation
4564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
4574e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
458838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisstruct IndexSessionData {
459838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  CXIndex CIdx;
460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<SessionSkipBodyData> SkipBodyData;
461838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
462838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  explicit IndexSessionData(CXIndex cIdx)
463838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
464838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis};
465838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
46621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstruct IndexSourceFileInfo {
4672957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  CXIndexAction idxAction;
4684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXClientData client_data;
4694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexerCallbacks *index_callbacks;
4704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_callbacks_size;
4714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_options;
4724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char *source_filename;
4734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char *const *command_line_args;
4744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  int num_command_line_args;
475ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<CXUnsavedFile> unsaved_files;
4764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXTranslationUnit *out_TU;
4774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned TU_options;
478ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  CXErrorCode &result;
4794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
4804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // anonymous namespace
4824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
48321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void clang_indexSourceFile_Impl(void *UserData) {
484ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  const IndexSourceFileInfo *ITUI =
485ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      static_cast<IndexSourceFileInfo *>(UserData);
486838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  CXIndexAction cxIdxAction = ITUI->idxAction;
4874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXClientData client_data = ITUI->client_data;
4884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
4894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_callbacks_size = ITUI->index_callbacks_size;
4904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_options = ITUI->index_options;
4914e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char *source_filename = ITUI->source_filename;
4924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char * const *command_line_args = ITUI->command_line_args;
4934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  int num_command_line_args = ITUI->num_command_line_args;
4944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXTranslationUnit *out_TU  = ITUI->out_TU;
4954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned TU_options = ITUI->TU_options;
496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (out_TU)
498ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    *out_TU = nullptr;
499ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool requestedToGetTU = (out_TU != nullptr);
5004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!cxIdxAction) {
502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ITUI->result = CXError_InvalidArguments;
5034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!client_index_callbacks || index_callbacks_size == 0) {
506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ITUI->result = CXError_InvalidArguments;
5074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
5094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexerCallbacks CB;
5114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  memset(&CB, 0, sizeof(CB));
5124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
5134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  ? index_callbacks_size : sizeof(CB);
5144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  memcpy(&CB, client_index_callbacks, ClientCBSize);
5154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
516838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  IndexSessionData *IdxSession = static_cast<IndexSessionData *>(cxIdxAction);
517838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  CIndexer *CXXIdx = static_cast<CIndexer *>(IdxSession->CIdx);
5184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
519fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
52081b5ac39a97cde1a54b8d0eb7105290c40eb84d7Argyrios Kyrtzidis    setThreadBackgroundPriority();
521fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis
522c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis  bool CaptureDiagnostics = !Logger::isLoggingEnabled();
523c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis
524ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  CaptureDiagnosticConsumer *CaptureDiag = nullptr;
525c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis  if (CaptureDiagnostics)
526c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis    CaptureDiag = new CaptureDiagnosticConsumer();
5274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Configure the diagnostics.
529c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<DiagnosticsEngine>
53002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor    Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
53102c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor                                              CaptureDiag,
532cc2b653c319599f502425d2c3de29865d47bb9e4Douglas Gregor                                              /*ShouldOwnClient=*/true));
5334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this function.
5354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
5364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
537ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    DiagCleanup(Diags.get());
538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<std::vector<const char *>> Args(
540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      new std::vector<const char *>());
5414e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
5434e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
5444e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    ArgsCleanup(Args.get());
5454e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  Args->insert(Args->end(), command_line_args,
5474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis               command_line_args + num_command_line_args);
5484e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5494e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // The 'source_filename' argument is optional.  If the caller does not
5504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // specify it then it is assumed that the source file is specified
5514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // in the actual argument list.
5524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Put the source file after command_line_args otherwise if '-x' flag is
5534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // present it will be unused.
5544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (source_filename)
5554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    Args->push_back(source_filename);
5564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
557c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<CompilerInvocation>
5584e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    CInvok(createInvocationFromCommandLine(*Args, Diags));
5594e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5604e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!CInvok)
5614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
5624e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5634e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this function.
5644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
5654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
566ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    CInvokCleanup(CInvok.get());
5674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (CInvok->getFrontendOpts().Inputs.empty())
5694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
5704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
571ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  typedef SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 8> MemBufferOwner;
572ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner);
5734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
575ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup(
576ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      BufOwner.get());
577ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
578ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  for (auto &UF : ITUI->unsaved_files) {
579ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    llvm::MemoryBuffer *MB =
580ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
581ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    BufOwner->push_back(std::unique_ptr<llvm::MemoryBuffer>(MB));
582ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB);
5834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
5844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Since libclang is primarily used by batch tools dealing with
5864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // (often very broken) source code, where spell-checking can have a
5874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // significant negative impact on performance (particularly when
5884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // precompiled headers are involved), we disable it.
589d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek  CInvok->getLangOpts()->SpellChecking = false;
5904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
591b49a29f7e4413a7a014a2b28c5c25fe54e005cf3Argyrios Kyrtzidis  if (index_options & CXIndexOpt_SuppressWarnings)
592b49a29f7e4413a7a014a2b28c5c25fe54e005cf3Argyrios Kyrtzidis    CInvok->getDiagnosticOpts().IgnoreWarnings = true;
593b49a29f7e4413a7a014a2b28c5c25fe54e005cf3Argyrios Kyrtzidis
594ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags,
595c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis                                  CaptureDiagnostics,
596ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                  /*UserFilesAreVolatile=*/true);
5976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Unit) {
5986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ITUI->result = CXError_InvalidArguments;
5996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return;
6006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
6016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<CXTUOwner> CXTU(
603651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
6044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
6064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
6074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    CXTUCleanup(CXTU.get());
6084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
609838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  // Enable the skip-parsed-bodies optimization only for C++; this may be
610838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  // revisited.
611838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
612838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      CInvok->getLangOpts()->CPlusPlus;
613838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  if (SkipBodies)
614838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    CInvok->getFrontendOpts().SkipFunctionBodies = true;
615838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
616651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<IndexingFrontendAction> IndexAction;
6174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexAction.reset(new IndexingFrontendAction(client_data, CB,
618838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                                               index_options, CXTU->getTU(),
619ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                        SkipBodies ? IdxSession->SkipBodyData.get() : nullptr));
6204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
6224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
6234e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexActionCleanup(IndexAction.get());
6244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6256f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool Persistent = requestedToGetTU;
6266f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool OnlyLocalDecls = false;
6276f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool PrecompilePreamble = false;
6286f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool CacheCodeCompletionResults = false;
6296f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
630bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  PPOpts.AllowPCHWithCompilerErrors = true;
6316f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis
6326f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  if (requestedToGetTU) {
6336f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
6346f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
6356f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    // FIXME: Add a flag for modules.
6366f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    CacheCodeCompletionResults
6376f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis      = TU_options & CXTranslationUnit_CacheCompletionResults;
6386f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  }
6396f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis
64053d6ded0edb70b04430cdaf7d02602799b4d4b07Argyrios Kyrtzidis  if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) {
64153d6ded0edb70b04430cdaf7d02602799b4d4b07Argyrios Kyrtzidis    PPOpts.DetailedRecord = true;
64253d6ded0edb70b04430cdaf7d02602799b4d4b07Argyrios Kyrtzidis  }
6433fe97781ad5f31dbfd9348c9488b93a7c01d7818Argyrios Kyrtzidis
64493cd6e8e17a40ee6fe1f17ab74d841e1f4fe9351Argyrios Kyrtzidis  if (!requestedToGetTU && !CInvok->getLangOpts()->Modules)
64593cd6e8e17a40ee6fe1f17ab74d841e1f4fe9351Argyrios Kyrtzidis    PPOpts.DetailedRecord = false;
64693cd6e8e17a40ee6fe1f17ab74d841e1f4fe9351Argyrios Kyrtzidis
647e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  DiagnosticErrorTrap DiagTrap(*Diags);
648ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), Diags,
6494e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                                       IndexAction.get(),
6506f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       Unit,
6516f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       Persistent,
6523791814b2c5efb3986ec4dd40c75c9d28f325222Argyrios Kyrtzidis                                                CXXIdx->getClangResourcesPath(),
6536f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       OnlyLocalDecls,
654c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis                                                       CaptureDiagnostics,
6556f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       PrecompilePreamble,
656ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                                    CacheCodeCompletionResults,
657ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                 /*IncludeBriefCommentsInCodeCompletion=*/false,
658ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                                 /*UserFilesAreVolatile=*/true);
659e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
660e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    printDiagsToStderr(Unit);
661e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (isASTReadError(Unit)) {
663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ITUI->result = CXError_ASTReadError;
664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return;
665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
667e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  if (!Success)
6684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
6694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (out_TU)
6714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    *out_TU = CXTU->takeTU();
6724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ITUI->result = CXError_Success;
6744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
6754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
67721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis// clang_indexTranslationUnit Implementation
67821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
67921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
68021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisnamespace {
68121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
68221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstruct IndexTranslationUnitInfo {
6832957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  CXIndexAction idxAction;
68421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  CXClientData client_data;
68521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexerCallbacks *index_callbacks;
68621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_callbacks_size;
68721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_options;
6882957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  CXTranslationUnit TU;
68921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  int result;
69021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis};
69121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
69221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis} // anonymous namespace
69321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
69421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
69521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  Preprocessor &PP = Unit.getPreprocessor();
69621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!PP.getPreprocessingRecord())
69721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
69821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
69921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  // FIXME: Only deserialize inclusion directives.
70021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
70121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  PreprocessingRecord::iterator I, E;
702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::tie(I, E) = Unit.getLocalPreprocessingEntities();
70321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
70462288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis  bool isModuleFile = Unit.isModuleFile();
70521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  for (; I != E; ++I) {
70621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    PreprocessedEntity *PPE = *I;
70721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
70821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
7098d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      SourceLocation Loc = ID->getSourceRange().getBegin();
7108d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      // Modules have synthetic main files as input, give an invalid location
7118d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      // if the location points to such a file.
7128d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      if (isModuleFile && Unit.isInMainFileID(Loc))
7138d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis        Loc = SourceLocation();
7148d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      IdxCtx.ppIncludedFile(Loc, ID->getFileName(),
7158d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            ID->getFile(),
7168d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            ID->getKind() == InclusionDirective::Import,
7178d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            !ID->wasInQuotes(), ID->importedModule());
71821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    }
71921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  }
72021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
72121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
72295c579cae01118eadd311d445ff7f491d0011fb0Argyrios Kyrtzidisstatic bool topLevelDeclVisitor(void *context, const Decl *D) {
7232093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  IndexingContext &IdxCtx = *static_cast<IndexingContext*>(context);
7242093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  IdxCtx.indexTopLevelDecl(D);
7252093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  if (IdxCtx.shouldAbort())
7262093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    return false;
7272093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  return true;
7282093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis}
72921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7302093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidisstatic void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) {
73195c579cae01118eadd311d445ff7f491d0011fb0Argyrios Kyrtzidis  Unit.visitLocalTopLevelDecls(&IdxCtx, topLevelDeclVisitor);
73221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
73321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
73421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx) {
735996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  if (!IdxCtx.hasDiagnosticCallback())
736996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis    return;
737996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis
738996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  CXDiagnosticSetImpl *DiagSet = cxdiag::lazyCreateDiags(TU);
739996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  IdxCtx.handleDiagnosticSet(DiagSet);
74021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
74121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
74221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void clang_indexTranslationUnit_Impl(void *UserData) {
74321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexTranslationUnitInfo *ITUI =
74421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    static_cast<IndexTranslationUnitInfo*>(UserData);
74521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  CXTranslationUnit TU = ITUI->TU;
74621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  CXClientData client_data = ITUI->client_data;
74721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
74821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_callbacks_size = ITUI->index_callbacks_size;
74921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_options = ITUI->index_options;
75021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Set up the initial return value.
752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ITUI->result = CXError_Failure;
753651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Check arguments.
755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (isNotUsableTU(TU)) {
756651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LOG_BAD_TU(TU);
757651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ITUI->result = CXError_InvalidArguments;
75821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
759651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!client_index_callbacks || index_callbacks_size == 0) {
761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ITUI->result = CXError_InvalidArguments;
76221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
76421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7658c718e7d87018919b5b84b0d545fe477b2d532d1Dmitri Gribenko  CIndexer *CXXIdx = TU->CIdx;
766fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
76781b5ac39a97cde1a54b8d0eb7105290c40eb84d7Argyrios Kyrtzidis    setThreadBackgroundPriority();
768fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis
76921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexerCallbacks CB;
77021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  memset(&CB, 0, sizeof(CB));
77121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
77221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                                  ? index_callbacks_size : sizeof(CB);
77321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  memcpy(&CB, client_index_callbacks, ClientCBSize);
77421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<IndexingContext> IndexCtx;
77621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU));
77721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
77821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
77921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext>
78021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexCtxCleanup(IndexCtx.get());
78121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<IndexingConsumer> IndexConsumer;
783ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, nullptr));
78421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
78521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
78621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
78721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexConsumerCleanup(IndexConsumer.get());
78821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7895694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *Unit = cxtu::getASTUnit(TU);
79021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!Unit)
79121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
79221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
793162884d7063646224d1b0759b6568aaf1d8935b6Argyrios Kyrtzidis  ASTUnit::ConcurrencyCheck Check(*Unit);
794162884d7063646224d1b0759b6568aaf1d8935b6Argyrios Kyrtzidis
7953da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  if (const FileEntry *PCHFile = Unit->getPCHFile())
7963da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    IndexCtx->importedPCH(PCHFile);
7973da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
79821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  FileManager &FileMgr = Unit->getFileManager();
79921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
80021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (Unit->getOriginalSourceFileName().empty())
801ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    IndexCtx->enteredMainFile(nullptr);
80221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  else
80321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
80421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
80521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexConsumer->Initialize(Unit->getASTContext());
80621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
80721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  indexPreprocessingRecord(*Unit, *IndexCtx);
80821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  indexTranslationUnit(*Unit, *IndexCtx);
80921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  indexDiagnostics(TU, *IndexCtx);
81021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ITUI->result = CXError_Success;
81221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
81321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
81421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
8154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// libclang public APIs.
8164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
8174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
8184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisextern "C" {
8194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
8206ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisint clang_index_isEntityObjCContainerKind(CXIdxEntityKind K) {
8216ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis  return CXIdxEntity_ObjCClass <= K && K <= CXIdxEntity_ObjCCategory;
822dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
823dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
8246ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisconst CXIdxObjCContainerDeclInfo *
8256ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisclang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) {
8266ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis  if (!DInfo)
827ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
8286ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis
829c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
830c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCContainerDeclInfo *
831c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI))
832c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &ContInfo->ObjCContDeclInfo;
833dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
834ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
835dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
836dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
8376ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisconst CXIdxObjCInterfaceDeclInfo *
8386ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisclang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) {
839c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (!DInfo)
840ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
841dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
842c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
843c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCInterfaceDeclInfo *
844c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
845c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &InterInfo->ObjCInterDeclInfo;
846dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
847ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
848dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
849dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
850c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisconst CXIdxObjCCategoryDeclInfo *
851c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisclang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){
852c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (!DInfo)
853ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
854dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
855c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
856c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCCategoryDeclInfo *
857c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
858c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &CatInfo->ObjCCatDeclInfo;
859dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
860ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
861dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
862dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
863c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisconst CXIdxObjCProtocolRefListInfo *
864c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisclang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) {
865c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (!DInfo)
866ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
8676ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis
868c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
869c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis
870c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCInterfaceDeclInfo *
871c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
872c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return InterInfo->ObjCInterDeclInfo.protocols;
873c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis
874c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCProtocolDeclInfo *
875c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        ProtInfo = dyn_cast<ObjCProtocolDeclInfo>(DI))
876c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &ProtInfo->ObjCProtoRefListInfo;
877c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis
878c10a4c8baff3164bee9b7fc293679a5a5a90eb74Argyrios Kyrtzidis  if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
879c10a4c8baff3164bee9b7fc293679a5a5a90eb74Argyrios Kyrtzidis    return CatInfo->ObjCCatDeclInfo.protocols;
880c10a4c8baff3164bee9b7fc293679a5a5a90eb74Argyrios Kyrtzidis
881ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
8826ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis}
8836ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis
884792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidisconst CXIdxObjCPropertyDeclInfo *
885792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidisclang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) {
886792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  if (!DInfo)
887ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
888792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis
889792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
890792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI))
891792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis    return &PropInfo->ObjCPropDeclInfo;
892792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis
893ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
894792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis}
895792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis
896b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidisconst CXIdxIBOutletCollectionAttrInfo *
897b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidisclang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) {
898b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  if (!AInfo)
899ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
900b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
901b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo);
902b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  if (const IBOutletCollectionInfo *
903b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis        IBInfo = dyn_cast<IBOutletCollectionInfo>(DI))
904b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    return &IBInfo->IBCollInfo;
905b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
906ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
907b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis}
908b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
9092957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisconst CXIdxCXXClassDeclInfo *
9102957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisclang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) {
9112957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!DInfo)
912ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
9132957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9142957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
9152957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI))
9162957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return &ClassInfo->CXXClassInfo;
9172957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
918ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return nullptr;
9192957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9202957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9212957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios KyrtzidisCXIdxClientContainer
9222957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisclang_index_getClientContainer(const CXIdxContainerInfo *info) {
9232957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
924ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
9253267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
9262957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  return Container->IndexCtx->getClientContainerForDC(Container->DC);
9272957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9282957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9292957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisvoid clang_index_setClientContainer(const CXIdxContainerInfo *info,
9302957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                    CXIdxClientContainer client) {
9312957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
9322957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return;
9333267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
9342957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  Container->IndexCtx->addContainerInMap(Container->DC, client);
9352957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9362957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9372957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios KyrtzidisCXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) {
9382957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
939ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return nullptr;
9403267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
9412957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  return Entity->IndexCtx->getClientEntity(Entity->Dcl);
9422957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9432957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9442957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisvoid clang_index_setClientEntity(const CXIdxEntityInfo *info,
9452957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                 CXIdxClientEntity client) {
9462957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
9472957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return;
9483267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
9492957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  Entity->IndexCtx->setClientEntity(Entity->Dcl, client);
9502957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9512957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9522957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios KyrtzidisCXIndexAction clang_IndexAction_create(CXIndex CIdx) {
953838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  return new IndexSessionData(CIdx);
9542957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9552957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9562957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisvoid clang_IndexAction_dispose(CXIndexAction idxAction) {
957838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  if (idxAction)
958838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    delete static_cast<IndexSessionData *>(idxAction);
9592957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9602957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9612957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisint clang_indexSourceFile(CXIndexAction idxAction,
9622957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          CXClientData client_data,
9632957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          IndexerCallbacks *index_callbacks,
9642957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned index_callbacks_size,
9652957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned index_options,
9662957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          const char *source_filename,
9672957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          const char * const *command_line_args,
9682957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          int num_command_line_args,
9692957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          struct CXUnsavedFile *unsaved_files,
9702957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned num_unsaved_files,
9712957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          CXTranslationUnit *out_TU,
9722957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned TU_options) {
973c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  LOG_FUNC_SECTION {
974c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    *Log << source_filename << ": ";
975c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    for (int i = 0; i != num_command_line_args; ++i)
976c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis      *Log << command_line_args[i] << " ";
977c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  }
9782957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
979ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (num_unsaved_files && !unsaved_files)
980ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return CXError_InvalidArguments;
981ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
982ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  CXErrorCode result = CXError_Failure;
983ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  IndexSourceFileInfo ITUI = {
984ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      idxAction,
985ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      client_data,
986ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      index_callbacks,
987ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      index_callbacks_size,
988ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      index_options,
989ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      source_filename,
990ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      command_line_args,
991ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      num_command_line_args,
992ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      llvm::makeArrayRef(unsaved_files, num_unsaved_files),
993ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      out_TU,
994ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      TU_options,
995ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      result};
9964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
997e7de9b4a1f4a15620ab15bc8159018df7d54080aArgyrios Kyrtzidis  if (getenv("LIBCLANG_NOTHREADS")) {
99821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    clang_indexSourceFile_Impl(&ITUI);
999ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return result;
10004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
10014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContext CRC;
10034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
100421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!RunSafely(CRC, clang_indexSourceFile_Impl, &ITUI)) {
100521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    fprintf(stderr, "libclang: crash detected during indexing source file: {\n");
10064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
10074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'command_line_args' : [");
10084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (int i = 0; i != num_command_line_args; ++i) {
10094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      if (i)
10104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        fprintf(stderr, ", ");
10114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      fprintf(stderr, "'%s'", command_line_args[i]);
10124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
10134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "],\n");
10144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'unsaved_files' : [");
10154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (unsigned i = 0; i != num_unsaved_files; ++i) {
10164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      if (i)
10174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        fprintf(stderr, ", ");
10184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
10194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis              unsaved_files[i].Length);
10204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
10214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "],\n");
10224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'options' : %d,\n", TU_options);
10234e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "}\n");
10244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return 1;
10264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
10274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (out_TU)
10284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      PrintLibclangResourceUsage(*out_TU);
10294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
1030ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
1031ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return result;
10324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
10334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10342957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisint clang_indexTranslationUnit(CXIndexAction idxAction,
103521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                               CXClientData client_data,
103621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                               IndexerCallbacks *index_callbacks,
103721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                               unsigned index_callbacks_size,
10382957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               unsigned index_options,
10392957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               CXTranslationUnit TU) {
1040c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  LOG_FUNC_SECTION {
1041c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    *Log << TU;
1042c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  }
104321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
10442957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  IndexTranslationUnitInfo ITUI = { idxAction, client_data, index_callbacks,
10452957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                    index_callbacks_size, index_options, TU,
10462957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                    0 };
104721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
104821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (getenv("LIBCLANG_NOTHREADS")) {
104921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    clang_indexTranslationUnit_Impl(&ITUI);
105021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return ITUI.result;
105121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  }
105221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
105321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  llvm::CrashRecoveryContext CRC;
105421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
105521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!RunSafely(CRC, clang_indexTranslationUnit_Impl, &ITUI)) {
105621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    fprintf(stderr, "libclang: crash detected during indexing TU\n");
105721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
105821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return 1;
105921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  }
106021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
106121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  return ITUI.result;
106221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
106321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
10644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid clang_indexLoc_getFileLocation(CXIdxLoc location,
1065dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis                                    CXIdxClientFile *indexFile,
10664e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    CXFile *file,
10674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    unsigned *line,
10684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    unsigned *column,
10694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    unsigned *offset) {
1070ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (indexFile) *indexFile = nullptr;
1071ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (file)   *file = nullptr;
10724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (line)   *line = 0;
10734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (column) *column = 0;
10744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (offset) *offset = 0;
10754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
10774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
10784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
10794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx =
10814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      *static_cast<IndexingContext*>(location.ptr_data[0]);
10824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexCtx.translateLoc(Loc, indexFile, file, line, column, offset);
10834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
10844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios KyrtzidisCXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
10864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
10874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
10884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return clang_getNullLocation();
10894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx =
10914e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      *static_cast<IndexingContext*>(location.ptr_data[0]);
10924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  return cxloc::translateSourceLocation(IndexCtx.getASTContext(), Loc);
10934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
10944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // end: extern "C"
10964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1097